ArangoDB v4.x is under development and not released yet.
This documentation is not final and potentially incomplete.
Authentication HTTP API
You can gain access to a protected ArangoDB server via HTTP authentication using a username and password, or a JSON Web Tokens (JWT) generated from the user credentials or the JWT secret of the deployment
Client authentication can be achieved by using the Authorization HTTP header
in client requests. ArangoDB supports authentication via the following:
- HTTP Basic Authentication with a username and either a password or access token.
- Bearer Token Authentication using JWT, which can be session tokens for regular users or non-expiring superuser tokens.
Authentication is enabled for all incoming requests to the HTTP API by default.
The only exception are endpoints that start with the path /_open that never
require authentication.
You can turn authentication off via the
--server.authentication
startup option. If you do, the access requirements stated for the endpoints,
including the need for a superuser JWT, generally don’t
apply. Any client that can reach the server has full access.
OPTIONS method are answered by
ArangoDB in any case, even if no authentication data is sent by the client or if
the authentication data is wrong. This is required for handling CORS preflight
requests (see Cross Origin Resource Sharing requests).
The response to an HTTP OPTIONS request is generic and doesn’t expose any
private data.Whenever authentication is required and the client has not yet authenticated,
ArangoDB returns HTTP 401 (Unauthorized). It also sends the
Www-Authenticate response header, indicating that the client should prompt
the user for username and password if supported. If the client is a browser,
then sending back this header normally triggers the display of the
browser-side HTTP authentication dialog. As showing the browser HTTP
authentication dialog is undesired in AJAX requests, ArangoDB can be told to
not send the Www-Authenticate header back to the client. Whenever a client
sends the X-Omit-Www-Authenticate HTTP header (with an arbitrary value) to
the server, ArangoDB only sends status code 401, but no Www-Authenticate
header. This allows clients to implement credentials handling and bypassing
the browser’s built-in dialog.
HTTP Basic Authentication
ArangoDB supports basic authentication with a user name and password. The name
and the password of an ArangoDB user account need to be separated by a colon and
the entire string needs to be Base64-encoded. The resulting value can be used
in the Authorization header of an HTTP request, indicating that the
authorization scheme is Basic.
For example, if the name is user and the password pass, the temporary string
that needs to be encoded is user:pass. The Base64-encoded value is
dXNlcjpwYXNz (e.g. using the btoa() JavaScript function in a browser).
The HTTP request header to authenticate is a follows:
Authorization: Basic dXNlcjpwYXNz
If you use a tool like cURL, you can manually specify this header as follows:
curl -H 'Authorization: Basic dXNlcjpwYXNz' ...
However, cURL can also take care of the authentication and specifically the encoding of the credentials for you:
curl -u user:pass ...
You can also authenticate with Access tokens. Use the access token as the password. You can omit the user name in this case:
curl -u:the_access_token
If you specify the user name, it must match the name encoded in the token.
Bearer Token Authentication
ArangoDB supports authentication with JSON Web Tokens (JWT). For more information on JWT, please consult RFC 7519 and jwt.io .
To authenticate via JWT, send the token in the Authorization HTTP header of
your requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiI..x6EfI
The server signs tokens with its active JWT secret. You can set the JWT secrets on server startup in one of the following ways:
- Set
--server.jwt-secret-keyfileto let the server read the JWT secret from the specified file. - Set
--server.jwt-secret-folderto specify a path and let the server read JWT secrets from multiple files (only one is used for signing). - Not specify either option to let the server generate a random JWT secret.
A JWT secret can be one of the following:
- A shared secret with a length of up to 64 bytes. Tokens are signed via HMAC
with SHA-256 (
HS256). Everyone who knows the secret can both verify and sign tokens. - From v3.12.8 onward, a private key for the P-256 elliptic curve in PEM format.
Tokens are signed via ECDSA with SHA-256 (
ES256). The corresponding public key can only verify tokens but not sign them. The active JWT secret that the server uses for signing needs to be a private key, but if you use--server.jwt-secret-folder, the other files can also contain public keys in PEM format, for example, to accept tokens that another party signs with its private key.
For example, you can create a private key and the corresponding public key for
ES256 with OpenSSL like this:
openssl ecparam -name prime256v1 -genkey -noout -out jwt-private.pem
openssl ec -in jwt-private.pem -pubout -out jwt-public.pem
JWT types
ArangoDB distinguishes the following kinds of JWTs:
| Type | How to obtain | Authenticates as | Expiry time |
|---|---|---|---|
| Session token | Request it from the server with a username and password or an access token. No JWT secret is needed. | The user, with the user’s permissions | Always, after one hour by default |
| User token | Generate and sign it yourself using the active JWT secret. | The user, with the user’s permissions | Optional, usually none |
| Superuser token | Generate and sign it yourself using the active JWT secret. | No user, with full access including internal APIs | Optional, usually none |
The decoded payload of a JWT can contain the following fields (claims):
| Claim | Description |
|---|---|
iss | Required. Must be the string "arangodb". |
preferred_username | The name of the user account to authenticate as. Session tokens and user tokens contain it. The user account must exist and be active. |
server_id | An arbitrary string identifier. Required if preferred_username is not set, which makes the token a superuser token. |
exp | The expiry time as Unix timestamp in seconds. Optional, but session tokens always have it. |
iat | The time the token has been issued as Unix timestamp in seconds. Optional. |
allowed_paths | An array of request paths that the token can be used for, without the /_db/<database-name> prefix, like "/_api/version". Requests to other paths are rejected. Optional. |
If you generate tokens yourself, set the alg field in the JWT header to the
algorithm that matches the active JWT secret, HS256 for a shared secret or ES256
for a private key.
Validity and revocation of JWTs
JWTs are stateless: the server doesn’t store the tokens it issues. It accepts every token with a valid signature, and it cannot revoke individual tokens. A JWT is valid until one of the following happens:
- It reaches its expiry time (
exp), if it has one. - The server no longer has a JWT secret that can verify the token.
If you rotate the secret using the
--server.jwt-secret-folderstartup option, tokens signed with a previous secret remain valid as long as the folder contains that secret as a passive secret. Any of the JWT secrets can verify tokens, but only the active one signs them. You can hot-reload the JWT secrets without a restart. - For session tokens and user tokens, no active user account exists for the
username in the token’s
preferred_usernamefield. This is the case if the account has been removed or, from v3.12.12 onward, deactivated by settingactivetofalsewith the User Management API.
Changing the password of a user account doesn’t invalidate tokens that have already been issued for it. Tokens also aren’t bound to a particular user account instance, only to the username: if you remove a user account and later create a new account with the same username, previously issued tokens for that username become valid again, regardless of the new account’s password. User tokens and superuser tokens without an expiry time stay valid until the JWT secret that signed them is removed, so treat them as sensitive as the JWT secrets themselves.
JWT session tokens
A session token is a JWT that the server issues for a user account. You don’t need to know the JWT secret, only the credentials of the user account. The web interface and the client tools use session tokens, for example.
To obtain a session token, send a POST request to the following endpoint:
The request body needs to contain the username and password JSON-encoded like so:
{
"username": "root",
"password": "rootPassword"
}
You can also use Access tokens for creating JWTs. Provide the
access token as the password. You can omit the username:
{
"password": "theAccessToken"
}
If you specify the user name, it must match the name encoded in the token.
On success, the endpoint returns a 200 OK and an answer containing the JWT in a JSON-encoded object like so:
{ "jwt": "eyJhbGciOiJIUzI1NiI..x6EfI" }
This JWT should then be used within the Authorization HTTP header in subsequent requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiI..x6EfI
--server.session-timeout
startup option.From v3.12.6 onward, you can request a different lifetime for a token by
specifying the expiryTime attribute in the request body, in seconds. It needs
to be within the bounds that the --auth.minimal-jwt-expiry-time (default:
10) and --auth.maximal-jwt-expiry-time (default: 3600) startup options
define:
{
"username": "root",
"password": "rootPassword",
"expiryTime": 600
}
You can find the expiration date of the JWT token in the exp field, encoded as
Unix timestamp in seconds. As an example, the decoded JWT body of a session
token looks like this:
{
"exp": 1540381557,
"iat": 1540377957,
"iss": "arangodb",
"preferred_username": "root"
}
Create a JWT session token
Obtain a JSON Web Token (JWT) from the credentials of an ArangoDB user account
or a user’s access token.
You can use the JWT in the Authorization HTTP header as a Bearer token to
authenticate requests.
The lifetime for the token is controlled by the --server.session-timeout
startup option, unless you specify a different lifetime with the
expiryTime attribute.
expiryTime number
Introduced in: v3.12.6
The lifetime of the token in seconds. Fractional values are truncated.
It needs to be greater than or equal to the value of the
--auth.minimal-jwt-expiry-timestartup option and less than or equal to the value of the--auth.maximal-jwt-expiry-timestartup option.If not specified, the value of the
--server.session-timeoutstartup option is used.
JWT user tokens
If you know the active JWT secret, you can generate and sign a token for a user
account yourself. A user token authenticates as the user specified in the
preferred_username field and grants the permissions of this user, the same as
a session token.
Unlike for session tokens, you decide which claims the token contains. In particular, a user token doesn’t need an expiry time. Without one, it stays valid until the JWT secret that signed it is removed or the user account is removed or deactivated. See Validity and revocation of JWTs.
You can generate a user token with the
ArangoDB Starter CLI
by specifying the user with the --auth.user option.
Should you wish to generate the JWT token yourself with a tool of your choice,
the body must contain the iss field with string value arangodb and the
preferred_username field with the name of the user account:
{
"iat": 1537800279,
"iss": "arangodb",
"preferred_username": "root"
}
For example, to generate such a token via the jwtgen tool :
jwtgen -s <my-secret> -v -a "HS256" -c 'iss=arangodb' -c 'preferred_username=root'
JWT superuser tokens
To access specific internal APIs as well as Agency and DB-Server instances a session token or user token is not good enough. For these special APIs, you need to generate a special JWT token which grants superuser access. Note that using superuser access for normal database operations is not advised.
For your convenience it is possible to generate this token via the ArangoDB Starter CLI.
Should you wish to generate the JWT token yourself with a tool of your choice,
you need to include the correct body. The body must contain the iss field
with string value arangodb and the server_id field with an arbitrary string
identifier, but no preferred_username field. The exp field is optional.
Without it, the token stays valid until the JWT secret that signed it is removed.
The following example body includes an expiry time:
{
"exp": 1537900279,
"iat": 1537800279,
"iss": "arangodb",
"server_id": "myclient"
}
For example to generate a token via the jwtgen tool (note the lifetime of one hour):
jwtgen -s <my-secret> -e 3600 -v -a "HS256" -c 'iss=arangodb' -c 'server_id=myclient'
curl -v -H "Authorization: bearer $(jwtgen -s <my-secret> -e 3600 -a "HS256" -c 'iss=arangodb' -c 'server_id=myclient')" http://<database-ip>:8529/_api/version
Access tokens
Access tokens act like passwords in authentication. Unlike normal credentials comprised of a username and a password, you can create multiple access tokens for a single user account. This is akin to having multiple passwords. You can set a desired expiration date for each access token (typically a few weeks or months) and individually revoke tokens on the server-side if necessary. You can use every access tokens for a different purpose, like different services that access ArangoDB using the same account, for fine-grained access control without having to change the password if you want to revoke access for one of the services.
You can use access tokens instead of the password to generate JWT session tokens (recommended) or use them directly as password in HTTP Basic Authentication (for backwards compatibility).
You need to create any user accounts first that you want to add access tokens to, see Create a user.
Create an access token
Create a new access token for the given user.
The response includes the actual access token string that you need to store in a secure manner. It is only shown once.
The user account you authenticate with needs to have rw access
to the _system database if you want to create an access token for a
different user. You can always create an access token for yourself,
regardless of database access levels.
Creating access tokens is not possible if the server is in read-only mode, unless you authenticate with a superuser JWT (introduced in v3.12.11).
valid_until integer, required
A Unix timestamp in seconds with the desired expiration date and time.
The server caps it to the moment of the request plus the maximum configured lifetime for access tokens (introduced in v3.12.10-1), see the
--auth.maximal-access-token-expiry-timestartup option.
403 Forbidden
The request is not authorized. The reason can be one of the following:
- The access level of the user account you authenticated with is too
low for the
_systemdatabase. It needs to berwto manage access tokens for other users. The error number isERROR_FORBIDDEN(11). - The server is in read-only mode, which doesn’t allow to create
access tokens, except with a superuser JWT. The error number is
ERROR_ARANGO_READ_ONLY(1004) (introduced in v3.12.11).
Response Body application/json object- The access level of the user account you authenticated with is too
low for the
Create an access token for the root user:
curl -X POST --header 'accept: application/json' --data-binary @- --dump - 'http://localhost:8529/_api/token/root' <<'EOF'
{
"name": "Token for Service A",
"valid_until": 1782864000
}
EOFShow output
HTTP/1.1 200 OK
content-type: application/json
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0, s-maxage=0
connection: Keep-Alive
content-length: 280
content-security-policy: frame-ancestors 'self'; form-action 'self';
expires: 0
pragma: no-cache
server: ArangoDB
strict-transport-security: max-age=31536000 ; includeSubDomains
x-arango-queue-time-seconds: 0.000000
x-content-type-options: nosniff
{
"id" : 1,
"name" : "Token for Service A",
"valid_until" : 1782864000,
"created_at" : 1755773629,
"fingerprint" : "v1...78227d",
"active" : true,
"token" : "v1.7b2265223a313738323836343030302c2263223a313735353737333632392c2275223a22726f6f74222c2272223a2234626d6668785a49633047683068643749575878227d"
}List all access tokens
List the access tokens for a given user.
This only returns the access token metadata. The actual access token strings are only shown when creating tokens.
The user account you authenticate with needs to have rw access
to the _system database if you want to list the access tokens for a
different user. You can always list your own access tokens,
regardless of database access levels.
List the access tokens of the root user:
curl --header 'accept: application/json' --dump - 'http://localhost:8529/_api/token/root'Show output
HTTP/1.1 200 OK
content-type: application/json
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0, s-maxage=0
connection: Keep-Alive
content-length: 141
content-security-policy: frame-ancestors 'self'; form-action 'self';
expires: 0
pragma: no-cache
server: ArangoDB
strict-transport-security: max-age=31536000 ; includeSubDomains
x-arango-queue-time-seconds: 0.000000
x-content-type-options: nosniff
{
"tokens" : [
{
"id" : 1,
"name" : "Token for Service A",
"valid_until" : 1782864000,
"created_at" : 1755773629,
"fingerprint" : "v1...78227d",
"active" : true
}
]
}Delete an access token
Delete an access token with the specified identifier for the given user.
The user account you authenticate with needs to have rw access
to the _system database if you want to delete an access token for a
different user. You can always delete your own access tokens,
regardless of database access levels.
Deleting access tokens is not possible if the server is in read-only mode, unless you authenticate with a superuser JWT (introduced in v3.12.11).
403 Forbidden
The request is not authorized. The reason can be one of the following:
- The access level of the user account you authenticated with is too
low for the
_systemdatabase. It needs to berwto manage access tokens for other users. The error number isERROR_FORBIDDEN(11). - The server is in read-only mode, which doesn’t allow to delete
access tokens, except with a superuser JWT. The error number is
ERROR_ARANGO_READ_ONLY(1004) (introduced in v3.12.11).
Response Body application/json object- The access level of the user account you authenticated with is too
low for the
Delete an access tokens of the root user:
curl -X DELETE --header 'accept: application/json' --dump - 'http://localhost:8529/_api/token/root/1'Show output
HTTP/1.1 200 OK
content-type: text/plain
cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0, max-age=0, s-maxage=0
connection: Keep-Alive
content-length: 0
content-security-policy: frame-ancestors 'self'; form-action 'self';
expires: 0
pragma: no-cache
server: ArangoDB
strict-transport-security: max-age=31536000 ; includeSubDomains
x-arango-queue-time-seconds: 0.000000
x-content-type-options: nosniffHot-reload JWT secrets
To reload the JWT secrets of a local arangod process without a restart, you
may use the following HTTP API. A POST request reloads the secret, a
GET request may be used to load information about the currently used secrets.
Get the hashes of the loaded JWT secrets
Hot-reload the JWT secret(s) from disk
Sending a request without payload to this endpoint reloads the JWT secret(s)
from disk. Only the files specified via the arangod startup option
--server.jwt-secret-keyfile or --server.jwt-secret-folder are used.
It is not possible to change the locations where files are loaded from
without restarting the process.
This endpoint requires a superuser JWT. User accounts,
including root, are not sufficient.
Example result:
{
"error": false,
"code": 200,
"result": {
"active": {
"sha256": "c6c1021286dfe870b7050f9e704df93c7f1de3c89dbdadc3fb30394bebd81e97"
},
"passive": [
{
"sha256": "6d2fe32dc4249ef7e7359c6d874fffbbf335e832e49a2681236e1b686af78794"
},
{
"sha256": "448a28491967ea4f7599f454af261a685153c27a7d5748456022565947820fb9"
},
{
"sha256": "6745d49264bdfc2e89d4333fe88f0fce94615fdbdb8990e95b5fda0583336da8"
}
]
}
}
