Chapter 15 · Security: Authentication, RBAC, Privileges, TLS, Secrets, and Least Privilege
TLS for Bolt/HTTPS, Certificate Trust, Encryption in Transit, and Client Verification
Protect AtlasMart Bolt and HTTPS traffic with explicit TLS policies and verified certificate identity, reproducing self-signed behavior only in an isolated local lab.
Learning outcomes
A password can authenticate AtlasMart correctly while an attacker on the network still observes or tampers with traffic if transport is not protected. TLS adds confidentiality and peer authentication only when certificate trust and hostname verification are meaningful. “Encrypted” is therefore not the same as “verified.”
Configure separate Neo4j SSL policies for Bolt and HTTPS and understand connector TLS levels.
Distinguish neo4j+s/bolt+s from
self-signed +ssc schemes and plain schemes.
Validate certificate subject/SAN, trust chain and hostname rather than disabling verification.
Reproduce a safe self-signed local TLS lab without modifying the continuity container.
Design certificate/key permissions, rotation and remote-access policy for production deployments.
The continuity lab remains Neo4j Community
2026.07.1, database neo4j, explicit
CYPHER 25 where language behavior matters,
container atlasmart-neo4j, loopback Bolt
bolt://127.0.0.1:7687, synthetic credential
neo4j/atlasmart-course-2026,
official Python driver neo4j 6.3.0, and no
mandatory plugin. Neo4j 5.26.30 is the LTS
comparison line. For TLS changes, this chapter deliberately
uses a second disposable container
atlasmart-neo4j-secure so earlier labs are not
disrupted.
Current Community Edition supports native users but has no roles; every Community user has implied administrator privileges. Fine-grained RBAC, built-in/custom roles, graph/database/procedure privileges, external auth-provider integration, security/query logs and related enterprise authorization controls are Enterprise/Aura-tier features. Mandatory Community exercises therefore prove authentication, parameterization, TLS, credential rotation and application-layer authorization, while RBAC denial examples are explicitly marked licensed/deterministic rather than presented as Community output.
All credentials, certificates and attacks in this chapter are synthetic and disposable. Never paste production passwords/private keys into source control, do not disable certificate verification to make a production connection work, and do not broaden procedure/plugin privileges merely to get a demo running.
1. TLS protects channels, not authorization
| Channel | Typical port | TLS policy scope | Security purpose |
|---|---|---|---|
| Bolt client | 7687 | bolt |
driver/cypher-shell confidentiality and server identity |
| HTTPS | 7473 | https |
Browser/HTTP API transport |
| cluster | 6000/7000/7688 current topology-specific ports | cluster |
Enterprise intra-cluster traffic |
| backup | 6362 | backup |
Enterprise backup traffic |
Remote Bolt/HTTPS should use trusted TLS. A certificate does not grant graph privileges, and RBAC does not encrypt bytes on the wire; layers complement each other.
2. URI schemes encode routing and trust intent
| URI | Routing | Encryption/trust |
|---|---|---|
neo4j:// |
yes | unencrypted |
neo4j+s:// |
yes | encrypted, full certificate verification |
neo4j+ssc:// |
yes | encrypted, self-signed/no CA certificate check; testing only |
bolt:// |
no | unencrypted |
bolt+s:// |
no | encrypted, full certificate verification |
bolt+ssc:// |
no | encrypted, self-signed/no CA certificate check; testing only |
Do not “fix” a certificate error by switching a production
connection from +s to +ssc or by
disabling verification. Fix the CA chain, SAN/hostname,
certificate dates or endpoint configuration.
3. Generate disposable self-signed PEM material
$Root = Join-Path $PWD 'atlasmart-security-lab'$Bolt = Join-Path $Root 'certificates\bolt'$Https = Join-Path $Root 'certificates\https'New-Item -ItemType Directory -Force $Bolt,$Https | Out-Null# Requires Docker, not host OpenSSL.docker run --rm -v "${Bolt}:/work" alpine/openssl req ` -x509 -nodes -newkey rsa:2048 -days 2 ` -keyout /work/private.key -out /work/public.crt ` -subj '/CN=localhost' ` -addext 'subjectAltName=DNS:localhost,IP:127.0.0.1'Copy-Item "$Bolt\private.key" "$Https\private.key"Copy-Item "$Bolt\public.crt" "$Https\public.crt"
The two-day certificate is intentionally disposable and includes SANs for the lab hostnames. Production certificates should be CA-issued, tracked, rotated before expiry and protected by filesystem/secret-store controls.
4. Start an isolated TLS-required Community container
docker rm -f atlasmart-neo4j-secure 2>$null$Root = (Resolve-Path .\atlasmart-security-lab).Pathdocker run -d --name atlasmart-neo4j-secure ` -p 127.0.0.1:17473:7473 ` -p 127.0.0.1:17687:7687 ` -e NEO4J_AUTH=neo4j/atlasmart-secure-lab-2026 ` -e NEO4J_server_http_enabled=false ` -e NEO4J_server_https_enabled=true ` -e NEO4J_server_bolt_tls__level=REQUIRED ` -e NEO4J_dbms_ssl_policy_bolt_enabled=true ` -e NEO4J_dbms_ssl_policy_bolt_base__directory=/ssl/bolt ` -e NEO4J_dbms_ssl_policy_https_enabled=true ` -e NEO4J_dbms_ssl_policy_https_base__directory=/ssl/https ` -v "${Root}\certificates:/ssl:ro" ` neo4j:2026.07.1docker logs --tail 120 atlasmart-neo4j-secure
If your host/container path handling differs, use the same Neo4j
settings in neo4j.conf. The important mechanism is
separate enabled SSL policies plus
server.bolt.tls_level=REQUIRED, not this exact
Docker invocation.
5. Prove encrypted success and plain failure
# Inspect certificate presented by Bolt.docker run --rm --network host alpine/openssl s_client ` -connect 127.0.0.1:17687 -servername localhost# Self-signed lab scheme: encrypted but CA verification relaxed.cypher-shell -a bolt+ssc://localhost:17687 ` -u neo4j -p atlasmart-secure-lab-2026 "RETURN 1 AS tls_ok;"# Expected to fail because server requires TLS.cypher-shell -a bolt://localhost:17687 ` -u neo4j -p atlasmart-secure-lab-2026 "RETURN 1;"
For production, replace the self-signed certificate with a
CA-issued certificate and use bolt+s or
neo4j+s. Also test that connecting with the wrong
hostname fails verification.
6. HTTPS and certificate verification
# -k is deliberately allowed ONLY for this isolated self-signed test.curl.exe -k https://localhost:17473/# Production check: omit -k and provide a trust chain trusted by the client.# curl.exe https://db.example.com:7473/
Neo4j documentation recommends disabling unencrypted HTTP when HTTPS is enabled. Test redirect/connector expectations explicitly; enabling HTTPS does not automatically make every client use it.
7. Private-key and certificate lifecycle
| Control | Failure if ignored | Evidence |
|---|---|---|
| private-key read permission | key theft impersonates server | only Neo4j service identity/secret mount can read key |
| SAN/hostname | client connects to wrong endpoint or fails verification | certificate SAN covers advertised hostname |
| expiry/rotation | outage or emergency verification bypass | expiry alert + rehearsed rotation |
| TLS versions/ciphers | legacy cryptography remains accepted | configured allowed versions/ciphers match policy |
| client trust store | unknown CA causes bypass pressure |
documented CA deployment; +s succeeds
without ignore flags
|
| connector exposure | plain listener remains reachable | network scan/config confirms intended ports only |
8. Cleanup
docker rm -f atlasmart-neo4j-secureRemove-Item -Recurse -Force .\atlasmart-security-lab
Production judgment
| Review area | Decision evidence |
|---|---|
| Identity/authentication | native or external identity source, MFA/SSO upstream where available, password/token lifecycle, lockout and break-glass process |
| Authorization | least-privilege database/graph/procedure grants; explicit DENY review; Community control gap documented |
| Transport | encrypted remote Bolt/HTTPS, trusted CA and hostname validation; self-signed only for isolated testing |
| Secrets | out of source/logs/images; rotated without code changes; incident revocation path tested |
| Application layer | parameterized Cypher, tenant/subject authorization before graph expansion, bounded result/data-export paths |
| Extensions/admin | procedure allowlist/unrestricted/boosted review, plugin provenance, backup/admin filesystem and host access |
| Evidence | auth/TLS denial tests, security/query logs where licensed, driver/server correlation and configuration review |
| Recovery | credential compromise playbook, backup encryption/access, break-glass scope, rollback/reconciliation and post-incident validation |
Check your understanding
- Does TLS prove a user may read Customer nodes?
- What is the difference between +s and +ssc?
- Why include SAN in the certificate?
- Why use a second security container?
- What is the correct production response to a certificate error?
Review the answers
1. No. TLS protects transport/server identity; authorization is a separate layer.
2. Both encrypt, but +s performs full certificate verification while +ssc is for self-signed/test situations without normal CA verification.
3. Clients verify the endpoint hostname/IP against certificate identity; CN-only assumptions are not sufficient modern practice.
4. TLS/auth changes and destructive cleanup stay isolated from the earlier continuity lab.
5. Fix trust/hostname/certificate configuration, not disable verification.
Summary and next step
Transport security is a verified identity channel, not an “encryption checkbox.” Lesson 4 moves the same lifecycle discipline to credentials themselves: creation, delivery, rotation, evidence, revocation and incident response.
Authoritative references
- Current Neo4j versions — Current server and 5.26 LTS release snapshot.
- Security checklist — Official baseline for deployment, transport, extensions, backup and filesystem security.
- Manage users — Native users, password handling, Community/Enterprise user-model distinctions.
- Role-based access control — Enterprise RBAC model and GRANT/DENY/REVOKE semantics.
- Read privileges — TRAVERSE, READ and MATCH graph privilege semantics.
- Write privileges — CREATE, DELETE, SET, MERGE and WRITE privilege semantics.
- SSL framework — Bolt/HTTPS TLS policies, certificate files, TLS levels and URI schemes.
- Procedure/function privileges — Execute and boosted-execution privilege boundaries.
- Python driver advanced connections — TLS/trust and rotating authentication token support in the maintained Python driver.
- Configure network connectors — Connector exposure and TLS-related network configuration.
- Neo4j Python driver connectivity — Driver URI/auth basics and secure Aura scheme guidance.