> ## Documentation Index
> Fetch the complete documentation index at: https://warden.buildlab.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Neo4j

> The third engine: a governed subset of Cypher, refused by default.

Neo4j is Warden's third engine, and its first statement-shaped one since PostgreSQL. Agents write Cypher strings, so the connector parses what they wrote with a small refuse-by-default grammar rather than with regular expressions — a regex guard is defeated by a comment, a stacked statement, or a write nested in a read-shaped clause.

| | |
| - | - |
| Versions | Neo4j 5+ (Community or Enterprise; single instance or cluster) |
| Certification | Strict in CI against a live server — `wardencert -engine neo4j -strict` — plus live integration tests |
| Driver | `neo4j-go-driver v5` |

## What it provides, and who provides it

| Guarantee | Level | How |
| - | - | - |
| Record scoping | `enforced` | Lease bindings are conjoined into the statement's `WHERE` clause on every bound variable, before it reaches the server |
| Field masking | `enforced` | Result-path masking before rows leave the gateway; rows are keyed by field name so an alias cannot smuggle a value past the mask |
| Statement timeout | `native` | Transaction timeout, set on every transaction and enforced by the server |
| Attribution | `native` | Sanitised comment on every statement, visible in `SHOW TRANSACTIONS` |
| Row limits | `enforced` | `LIMIT` injected into reads, re-capped in the gateway with honest truncation |
| Dry run | `enforced` | Count from the server plus sampled before/after images, at `estimated` fidelity |
| Cost estimate | `advisory` | Counts only |
| Fence | `native` | Content hash over the targeted records, re-checked inside the commit transaction |
| Per-agent identity | `enforced` | Gateway-side identity; the connector mints no database users on any edition |
| Lease revocation | `enforced` | Sessions under a revoked lease are refused on next use |
| Transactional DDL | `unavailable` | No DDL in the governed subset |

Identity stays gateway-enforced even on Enterprise: Community has no per-user roles, and per-lease database users are a follow-up, not something this connector mints quietly. A policy requiring more than `enforced` identity refuses to start on a Neo4j connection.

## The governed subset

One leading `MATCH` with an optional `WHERE`, followed by exactly one of `RETURN`, `CREATE`, `SET`, or `DELETE`/`DETACH DELETE` — or a standalone `CREATE`. Parameters are positional (`$0`, `$1, ...`) and stay bound all the way to the driver. A parameter in a label or relationship-type position is refused: it would let the agent choose the label at execution time.

Everything else is refused outright: `WITH`, `UNION`, `MERGE`, `CALL` (and so every `apoc.*` procedure), `LOAD CSV`, `FOREACH`, `UNWIND`, `OPTIONAL MATCH`, `REMOVE`, whole-node assignment, function calls in `RETURN`, variable-length relationships, and stacked statements. A filter the subset accepts but cannot normalize — a regex, a function call, a nested expression — fails the statement instead of executing with a filter Warden did not understand.

Comments are inert by construction: what the lexer strips cannot execute, so `MATCH (o:Order) // DETACH DELETE o` is a read and nothing else.

## Writes carry the scope too

Reads and deletes are restricted by conjoining the lease's bindings into the filter, on every variable bound to a scoped label — a label matched under two variables with the condition on only one would still read the other's records. Writes are restricted by what they write: a `CREATE` must state the lease's value inline for every scoped label it creates, and a `SET` may not move a node out of scope. Anything else is refused rather than corrected, so the operation that executes is the one a reviewer approved.

## Setting it up

```yaml theme={null}
connections:
  - name: shop
    engine: neo4j
    dsn: bolt://warden_gateway:secret@graph.internal:7687
    policy: ./policies/shop.yaml
    options:
      database: neo4j
      labels: Order,Customer
      statement_timeout_ms: "5000"
      max_conns: "10"
      application_name: warden
```

`database` defaults to `neo4j`, which is the only database Community serves — refusing an empty value would make every Community deployment fail to start over a setting it cannot use. Set `labels` on any non-trivial graph; without it the catalog includes every label. Use a least-privilege role: the connector needs to read and write data, never to manage users or databases.

## Known gaps

* **Native per-lease principals.** Not minted on any edition yet; Enterprise RBAC could back them in a follow-up.
* **Relationship scoping** is not supported.
* **The subset is narrow on purpose.** `MERGE`, aggregations, and path queries are refused today; broadening it means proving each addition against the adversarial corpus first.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.