Neo4j database plugin HTTP API
The Neo4j database plugin is one of the supported plugins for the database secrets engine. This plugin generates database credentials dynamically based on configured roles against a Neo4j 4+ cluster over the Bolt protocol.
Configure connection
In addition to the parameters defined by the Database Secrets Engine, this plugin has a number of parameters to further configure a connection.
| Method | Path |
|---|---|
POST | /database/config/:name |
Parameters
-
uri(string: <required>)– Specifies the Bolt connection URI for the Neo4j cluster, e.g.bolt://neo4j.example.com:7687. Accepts any scheme supported by the Neo4j Go driver, includingbolt://,neo4j://,bolt+s://,neo4j+s://, and their+ssc(self-signed cert) variants. -
username(string: <required>)– Specifies the root credential username OpenBao uses to log into the cluster and issue/revoke dynamic users. -
password(string: <required>)– Specifies the root credential password corresponding tousername. -
database(string: "system")– Specifies the database thatCREATE USER/ALTER USER/DROP USER/GRANT ROLEstatements are run against. Defaults tosystem, the Neo4j 4+ convention for user administration. This is unrelated to any application database queries. -
username_template(string)- Template describing how dynamic usernames are generated.
Default Username Template
{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 10) (.RoleName | truncate 10) (random 15) (unix_time) | replace "." "-" | truncate 60 }}
Example Usernames:
| Example | |
|---|---|
DisplayName | token |
RoleName | myrolename |
| Username | v-token-myrolena-uszt1n4cyhal4-1614294836 |
Sample payload
{
"plugin_name": "neo4j-database-plugin",
"allowed_roles": "reader",
"uri": "bolt://neo4j.example.com:7687",
"username": "neo4j",
"password": "password"
}
Sample request
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data @payload.json \
http://127.0.0.1:8200/v1/database/config/neo4j
Statements
Unlike SQL-style database plugins, this plugin does not use
semicolon-separated statement lists. creation_statements is a single JSON
document listing pre-existing Neo4j role names to grant the new user. For
more information on configuring roles see the Role
API in the database secrets engine docs.
The following are the statements used by this plugin. If not mentioned in this list the plugin does not support that statement type.
-
creation_statements(string: <required>)– Specifies a single JSON document listing the Neo4j roles to grant the new user:{ "roles": ["reader", "editor"] }roles(required) is an array of bare role name strings — Neo4j's role model is global, so roles are not scoped to a database. Every listed role must already exist on the cluster; this plugin does not create roles. On the wire the plugin runsCREATE USER $name SET PASSWORD $password CHANGE NOT REQUIREDfollowed by oneGRANT ROLE<role>TO $nameper entry. If any grant fails, the plugin runsDROP USER $namebefore returning the error, so no half-configured user is left behind. There is no built-in default; a role withoutcreation_statementsfails to issue credentials.
revocation_statements, rollback_statements, and root_rotation_statements
are accepted by the database secrets engine framework but are not used by
this plugin. Revocation always runs DROP USER $name IF EXISTS, which is
idempotent if the user has already been removed. Password rotation, for both
root credentials and static roles, always runs ALTER USER $name SET PASSWORD $password CHANGE NOT REQUIRED.
Root credential rotation
$ bao write -force database/rotate-root/neo4j
Rotates the root user's password (the username/password pair configured
on database/config/:name) via ALTER USER ... SET PASSWORD. The old
password is not recoverable afterward.
Static roles
Static roles rotate the password of an existing Neo4j user on a schedule,
via ALTER USER ... SET PASSWORD:
$ bao write database/static-roles/svc \
db_name=neo4j \
username=svc \
rotation_period=24h
Neo4j has no native VALID UNTIL clause on users, so dynamic-role lease
expiry is enforced by OpenBao revoking the lease (DROP USER ... IF EXISTS),
not by the database itself.