Skip to main content
Version: 2.x(alpha)

DEFINE ACCESS ... TYPE JWT

A JWT access method allows accessing SurrealDB with a token signed by a trusted issuer. The contents of the token will be trusted by SurrealDB as long as it has been signed with a trusted credential.

SurrealDB can work with third-party authentication providers such as OpenID Connect providers, OAuth providers and other trusted parties providing JWT (JSON Web Tokens, also referred to in this page as “tokens”). Let's say that your provider issues your client (e.g. a user or a service) a JWT once it has authenticated. By using the DEFINE ACCESS ... TYPE JWT statement, you can set the public key or shared secret that will be used to verify the authenticity of the token.

This verification is performed automatically by SurrealDB when provided with a JWT through any of its interfaces (i.e. the HTTP REST API through the “Authorization” header or any of the SDKs through the “Authenticate” methods) before trusting the claims contained in the token and allowing SurrealQL queries to access the values of those claims.

Bear in mind that table and field permissions only apply to record users, which must use tokens that are verified by a RECORD access method. Access provided by namespace and database tokens defined in a JWT access method is equivalent to access from system users, which is above fine-grained permissions. When application users will be the ones directly authenticating with JWT, defining a RECORD access method WITH JWT is most likely the right choice.

Requirements

Statement syntax

SurrealQL Syntax
DEFINE ACCESS [ IF NOT EXISTS ] @name
ON [ ROOT | NAMESPACE | DATABASE ]
TYPE JWT [ ALGORITHM @algorithm KEY @key | URL @url ]
[ DURATION FOR SESSION @duration ]

Verification Types

When defining a token, its type describes the cryptographic algorithm or specification that will be used to verify the token. This can be an HMAC algorithm, a public-key cryptography algorithm or a remote JWKS object containing all the required information to verify the token. When not specified, the type is defined as the HS256 HMAC cryptographic algorithm.

Hash-Based Message Authentication Code (HMAC)

With HMAC algorithms (HS256,HS384,HS512) the value of the defined token will be the secret used both to sign (by the issuer of the token) and verify (by SurrealDB) the token. Anyone with access to this secret will be able to issue tokens with arbitrary claims which will be trusted by SurrealDB.

The following example shows the definition of a token using an HMAC algorithm.

-- Specify the namespace and database for the token
USE NS abcum DB app_vitalsense;

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for database authentication
ON DATABASE
-- Specify the type of access being defined
TYPE JWT
-- Specify the cryptographic signature algorithm used to verify the token
ALGORITHM HS512
-- Specify the symmetric key used to sign and verify the authenticity of the token
KEY "sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8"
;

Public-Key Cryptography

With public-key cryptography algorithms (EDDSA, ES256, ES384, ES512, PS256, PS384, PS512, RS256, RS384, RS512) the value of the defined token will be the public key used to verify the signature of the token. This value is not secret and should be provided by the issuer of the tokens. Tokens will be signed using the private key, known only to the issuer. The public key value should be provided to SurrealDB including its header and footer. Any whitespace will be trimmed.

The following example shows the definition of a token using a public-key cryptography algorithm.

-- Specify the namespace and database for the token
USE NS abcum DB app_vitalsense;

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for database authentication
ON DATABASE
-- Specify the type of access being defined
TYPE JWT
-- Specify the cryptographic signature algorithm used to verify the token
ALGORITHM RS256
-- Specify the public key used to verify the authenticity of the token
KEY "-----BEGIN PUBLIC KEY-----
MUO52Me9HEB4ZyU+7xmDpnixzA/CUE7kyUuE0b7t38oCh+sQouREqIjLwgHhFdhh3cQAwr6GH07D
ThioYrZL8xATJ3Youyj8C45QnZcGUif5PkpWXDi0HJSoMFekbW6Pr4xuqIqb2LGxGDVJcLZwJ2AS
Gtu2UAfPXbBD3ffiad393M22g1iHM80YaNi+xgswG7qtXE4lR/Lt4s0MeKKX7stdWI1VIsoB+y3i
r/OWUvJPjjDNbAsyy8tQmxydv+FUnLEP9TNT4AhN4DXcJ+XsDtW7OWt4EdSVDeKpGbIMvIrh1Pe+
Nilj8UHNyNDHa2AjK3seMo6CMvaIQJKj5o4xGFblFGwvvPD03SbuQLs1FdRjsZCeWLdYeQ3JDHE9
sFG7DCXlpMJcaYT1mf4XHJ0gPekNLQyewTY3Vxf7FgV3GCNjV20kcDFgJA2+iVW2wSrb+txD1ycE
kbi8jh0pedWwE40VQWaTh/8eAvX7IHWya/AEro25mq+m6vktNZLbvLphhp586kJK3Tdt3YjpkPre
M3nkFWOWurIyKbtIV9JemfwCgt89sNV45dTlnEDEZFFGnIgDnWgx3CUo4XmhICEQU8+tklw9jJYx
iCTjhbIDEBHySSSc/pQ4ftHQmhToTlQeOdEy4LYiaEIgl1X+hzRH1hBYvWlNKe4EY1nMCKcjgt0=
-----END PUBLIC KEY-----"
;

JSON Web Key Set (JWKS)

With JWKS, a set of JWK (JSON Web Key) objects will be dynamically fetched from a remote location and used to verify tokens following the RFC 7517 specification. When defining a JWKS token verification method, its value should contain a valid URL that is reachable by SurrealDB and allowed by the configured network capabilities. This URL should point to a valid JWKS object (as described in Section 5 of RFC 7517) in the form of a JSON document. This is the recommended method to integrate with authentication providers that support JWKS. Providers like Google, AWS Cognito, Azure Active Directory, Auth0, Keycloak or OneLogin provide JWKS endpoints to verify tokens issued by their services.

The following example shows the definition of a token using a JWKS.

-- Specify the namespace and database for the token
USE NS abcum DB app_vitalsense;

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for database authentication
ON DATABASE
-- Specify the type of access being defined
TYPE JWT
-- Specify the URL where the JWKS object can be found
URL "https://example.com/.well-known/jwks.json"
;

Validating tokens generated by third-party authentication providers using JWKS ensures that keys can be revoked directly from the third-party service and will no longer be accepted by SurrealDB after the local cache for those keys expires. Likewise, it ensures that token verification will not break if keys are rotated, as any new keys will be automatically fetched from the authentication provider if a JWT is received containing a new key identifier in its kid header.

To avoid performing requests to the remote URL for each token that is verified, SurrealDB caches every JWKS object that it pulls for a period of 12 hours. The cache can be purged earlier (e.g. in the event a key is compromised) by restarting the SurrealDB server. If a JWT is received containing a reference to a new key identifier in its kid header, the JWKS object will be fetched again and updated in the cache if the key identifier is found in the remote JWKS object; this operation will only be performed once every 5 minutes to prevent malicious actors from abusing this process to perform denial of service.

Using Tokens

The DEFINE ACCESS ... TYPE JWT statement lets you specify the amount of permission granting authority you want to give to a token issuer. You are able to specify if the provider can grant namespace or database access to token holders. For this to work, the JWT issued to be used with SurrealDB must contain claims to specify which namespace or database the token bearer is authorized to act on.

The following claims should be added to the JWT payload by the issuer of the token:

  • exp: The token expiration Unix time. The token will not be valid after.
  • ac: The name of the access method used to verify the token.
  • ns: The namespace that the token is issued for.
  • db: The database that the token is issued for.

The names of these claims can be in all lowercase (i.e. ac) or all uppercase (i.e. AC), and can be optionally prefaced with the https://surrealdb.com namespace (e.g. https://surrealdb.com/ac) in order to separate claims directed to SurrealDB from claims directed to other services. When using a namespace, the claim name can also be used without abbreviation, such as in https://surrealdb.com/access, https://surrealdb.com/database...

The following optional claims are also processed by SurrealDB:

  • id: The identifier of the resource (e.g. user) associated with the token.
  • nbf: The token acceptance Unix time. The token will not be valid before.

The expected claims depend on the level at which the token was defined:

  • For tokens defined ON ROOT: exp, ac.
  • For tokens defined ON NAMESPACE: exp, ac, ns.
  • For tokens defined ON DATABASE: exp, ac,ns,db.

For tokens defined for system users, the optional rl claim containing an array of capitalized system user roles (e.g. ["Viewer", "Editor", "Owner"]) can be provided. Doing so will apply the access policy for those roles to any action made using the token. By default, sessions established with tokens without the rl claim will only have the Viewer role.

When calling any of the SurrealDB interfaces using a JWT, SurrealQL queries will gain access to the claims in the token through the $token variable. For example, if the token contains custom claims such as “name” or “email”, the values of those claims will be accessible through $token.name and $token.email.

The signature of the token is verified with method defined when creating the token. If the signature of the token is invalid, calls to SurrealDB interfaces using that token will fail.

Root

Root tokens can be used to select, create, update, and delete on all tables in all databases of all namespaces, as well as to define and remove namespaces and databases from the SurrealDB instance.

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for root authentication
ON ROOT
-- Specify the type of access being defined
TYPE JWT
-- Specify the cryptographic signature algorithm used to verify the token
ALGORITHM HS512
-- Specify the symmetric key used to sign and verify the authenticity of the token
KEY "sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8"
;

The root token payload should at least include the following claims when used to authenticate with SurrealDB.

JWT Payload
{
"exp": 2147483647,
"ac": "token_name",
}

Namespace

Namespace tokens can be used to select, create, update, and delete on all tables in all databases, as well as to define and remove databases and tables from the namespace.

-- Specify the namespace for the token
USE NS abcum;

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for namespace authentication
ON NAMESPACE
-- Specify the type of access being defined
TYPE JWT
-- Specify the cryptographic signature algorithm used to verify the token
ALGORITHM HS512
-- Specify the symmetric key used to sign and verify the authenticity of the token
KEY "sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8"
;

The namespace token payload should at least include the following claims when used to authenticate with SurrealDB.

JWT Payload
{
"exp": 2147483647,
"ac": "token_name",
"ns": "abcum"
}

Database

Database tokens can be used to select, create, update, and delete on all tables in a specific database, as well as to define and remove tables from the database.

-- Specify the namespace and database for the token
USE NS abcum DB app_vitalsense;

-- Set the name of the token
DEFINE ACCESS token_name
-- Use this token provider for database authentication
ON DATABASE
-- Specify the type of access being defined
TYPE JWT
-- Specify the cryptographic signature algorithm used to verify the token
ALGORITHM HS512
-- Specify the symmetric key used to sign and verify the authenticity of the token
KEY "sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8"
;

The database token payload should at least include the following claims when used to authenticate with SurrealDB.

JWT Payload
{
"exp": 2147483647,
"ac": "token_name",
"ns": "abcum",
"db": "app_vitalsense"
}