Chapter 15 · Security: Authentication, RBAC, Privileges, TLS, Secrets, and Least Privilege
Users, Roles, Authentication Providers, Password Policy, and Administrative Separation
Separate AtlasMart identities and administrative power, prove native authentication behavior, and understand exactly where Community stops and Enterprise/Aura authorization begins.
Learning outcomes
AtlasMart has one production-shaped mistake before it has a
production outage: the order API connects with the same
neo4j administrator credential used by engineers.
An injection bug, leaked environment file, compromised CI runner
or vulnerable procedure would therefore inherit administrative
power. Security begins by separating who are you? from
what are you allowed to do? and by recognizing that
Community and Enterprise expose different authorization
mechanisms.
Distinguish authentication, authorization, native users, roles, auth providers and administrative identities.
Explain current Community-vs-Enterprise behavior instead of assuming every Neo4j deployment has RBAC.
Configure and test native users, password-change state, minimum password length and failed-login lockout behavior safely.
Design administrative separation and break-glass access without putting admin credentials in application code.
Explain when OIDC/LDAP/external providers are appropriate and why their availability changes by edition/tier.
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.
Reproducible AtlasMart setup
$env:NEO4J_URI='bolt://127.0.0.1:7687'$env:NEO4J_USER='neo4j'$env:NEO4J_PASSWORD='atlasmart-course-2026'$env:NEO4J_DATABASE='neo4j'py -3 -m venv .venv.\.venv\Scripts\Activate.ps1python -m pip install --upgrade pippython -m pip install neo4j==6.3.0
CYPHER 25CREATE CONSTRAINT customer_id IF NOT EXISTSFOR (c:Customer) REQUIRE c.customerId IS UNIQUE;CREATE CONSTRAINT product_id IF NOT EXISTSFOR (p:Product) REQUIRE p.productId IS UNIQUE;CREATE CONSTRAINT order_id IF NOT EXISTSFOR (o:Order) REQUIRE o.orderId IS UNIQUE;MERGE (c:Customer {customerId:'C-1001'})SET c.name='Mina Rahimi', c.tier='GOLD', c.tenantId='TENANT-A'MERGE (p:Product {productId:'P-1001'})SET p.name='Trail Camera', p.category='Cameras', p.price=129.90MERGE (o:Order {orderId:'O-5001'})SET o.status='PAID', o.tenantId='TENANT-A', o.orderedAt=datetime('2026-09-08T16:30:00Z')MERGE (c)-[:PLACED]->(o)MERGE (o)-[r:CONTAINS]->(p)SET r.quantity=1, r.unitPrice=129.90;
These are course-only credentials and synthetic records. The
fixture deliberately includes tenantId because
authorization mistakes often appear when a graph traversal
crosses a tenant boundary even though authentication succeeded.
1. Authentication is not authorization
| Mechanism | Question answered | Current Neo4j boundary |
|---|---|---|
| Authentication | Who is the principal? | native auth in Community/Enterprise; external providers such as OIDC/LDAP are Enterprise capabilities |
| Authorization | What may that principal do? | Community users are implied admins; fine-grained roles/privileges are Enterprise/Aura-tier |
| Role | Reusable privilege set | Enterprise/Aura relevant; Community has no roles |
| Auth provider | Where identity/claims are verified | native everywhere; per-user OIDC/LDAP provider integration is Enterprise |
| Administrative separation | Should an app be able to administer users/schema/server? | yes as a design question; DB enforcement requires RBAC-capable tier |
Do not call a Community username “least privilege” merely because it has a different password. It is a separate credential, but the DBMS still grants implied administrator capability.
2. Native user and password controls
CREATE USER atlasmart_app IF NOT EXISTSSET PASSWORD 'atlasmart-app-lab-2026'CHANGE NOT REQUIRED;SHOW USERSYIELD user, passwordChangeRequiredRETURN user, passwordChangeRequiredORDER BY user;
SHOW SETTINGSYIELD name, valueWHERE name IN [ 'dbms.security.auth_enabled', 'dbms.security.auth_minimum_password_length', 'dbms.security.auth_max_failed_attempts', 'dbms.security.auth_lock_time']RETURN name, valueORDER BY name;
Current defaults document authentication enabled, minimum password length 8, three failed attempts before lockout and a 5-second lock interval. Defaults are evidence to inspect, not a universal policy recommendation: your organization may need stronger credential controls upstream or stricter values after testing operational effects.
3. Prove authentication failure without damaging the lab
docker exec atlasmart-neo4j cypher-shell ` -a neo4j://localhost:7687 -u atlasmart_app -p atlasmart-app-lab-2026 ` "SHOW CURRENT USER;"docker exec atlasmart-neo4j cypher-shell ` -a neo4j://localhost:7687 -u atlasmart_app -p definitely-wrong ` "RETURN 1;"
The second command should fail authentication. That proves a
credential boundary, not least privilege. In Community,
SHOW USERS or another administrative operation
remains available to the authenticated user because the edition
has no role model.
4. Enterprise administrative separation (licensed path)
CREATE ROLE atlasmart_app_role IF NOT EXISTS;CREATE USER atlasmart_service IF NOT EXISTSSET PASSWORD $password CHANGE NOT REQUIRED;GRANT ROLE atlasmart_app_role TO atlasmart_service;GRANT ACCESS ON DATABASE neo4j TO atlasmart_app_role;GRANT MATCH {*} ON GRAPH neo4j NODES Customer, Product, Order TO atlasmart_app_role;GRANT MATCH {*} ON GRAPH neo4j RELATIONSHIPS PLACED, CONTAINS TO atlasmart_app_role;SHOW ROLE atlasmart_app_role PRIVILEGES AS COMMANDS;
The purpose is to show the mechanism the licensed tier supplies. If Enterprise/Aura Business Critical/VDC is unavailable, validate the intended grant/deny matrix as a test specification and keep database-level least privilege on the deployment decision register.
5. External providers and administrative identity
| Choice | Use when | Security consequence |
|---|---|---|
| Native password | small local/self-managed deployments, break-glass account | Neo4j stores hashed password; rotate and protect secret delivery |
| OIDC/SSO | central IdP, user lifecycle, enterprise browser/tool access | Enterprise; token/claims/redirect/certificate configuration becomes part of security boundary |
| LDAP | enterprise directory is authority | Enterprise; secure LDAP/StartTLS and group/role mapping must be governed |
| Separate admin identity | routine app/service work must not administer DBMS | reduces credential-compromise blast radius when tier can enforce it |
| Break-glass admin | identity provider outage or emergency recovery | offline-protected, monitored, tested, rarely used; never application credential |
6. Deliberately wrong: admin credentials in application source
# WRONG — synthetic example onlyfrom neo4j import GraphDatabasedriver = GraphDatabase.driver( "neo4j://db.example.internal:7687", auth=("neo4j", "SuperSecretPasswordInGit"))
import osfrom neo4j import GraphDatabaseuri = os.environ["NEO4J_URI"]user = os.environ["NEO4J_USER"]password = os.environ["NEO4J_PASSWORD"]driver = GraphDatabase.driver(uri, auth=(user, password))driver.verify_connectivity()
Environment variables are only a delivery mechanism, not a complete secrets manager. In production, define who can read the process environment, CI variables, container secrets, crash dumps and diagnostics; prefer your platform secret store and rotation workflow.
7. Verification checklist and cleanup
| Check | Evidence |
|---|---|
| native user exists |
SHOW USERS includes
atlasmart_app
|
| correct secret works |
SHOW CURRENT USER identifies app user
|
| wrong secret fails | client receives authentication error |
| Community gap visible | role commands unavailable / users have implied admin behavior |
| app has no hard-coded real secret | repository and logs contain only placeholders/synthetic lab values |
| break-glass documented | owner, storage, rotation and emergency procedure are explicit |
DROP USER atlasmart_app IF EXISTS;
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 a second Community user create least privilege?
- What is the default minimum password length currently documented?
- Why separate an app identity from an admin identity?
- Are OIDC and LDAP Community features?
- What is the best evidence that authentication works?
Review the answers
1. No. It creates a separate authentication credential, but Community users have implied administrator privileges.
2. Eight characters, controlled by dbms.security.auth_minimum_password_length; production policy may need to be stronger.
3. A compromised app should not automatically gain user/schema/server administration capabilities.
4. No. Current external auth-provider integration is an Enterprise capability.
5. Positive and negative login tests plus SHOW CURRENT USER; authentication success alone says nothing about authorization scope.
Summary and next step
Identity is the first layer, not the whole security model. Lesson 2 turns the intended AtlasMart behavior into explicit database, graph, label/type and procedure privileges where the tier supports them, while keeping the Community gap visible.
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.
- Configuration settings — Authentication enabled, minimum password length and lockout settings.
- User auth providers — Enterprise per-user native/OIDC/LDAP provider model.
- Single sign-on integration — Enterprise OIDC/SSO architecture and configuration.