SurrealDB Docs Logo

Enter a search query

DEFINE ACCESS ... TYPE JWT

Available since: v2.0.0

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 [ OVERWRITE | IF NOT EXISTS ] @name ON [ ROOT | NAMESPACE | DATABASE ] TYPE JWT [ ALGORITHM @algorithm KEY @key | URL @url ] [ AUTHENTICATE @expression ] [ 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.

Before you start

As the JWKS functionality requires establishing a network connection in order to download the JWKS object, you will require running the SurrealDB server with the network capability. For the strongest security, provide the specific hostname hosting the JWKS object when starting SurrealDB with —allow-net. For example: —allow-net example.com.

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" }

With AUTHENTICATE clause

The AUTHENTICATE clause allows you to define a custom expression that will be executed when the token is verified. This expression will be executed in the context of the token, allowing you to perform additional checks on the token claims before the token is accepted. If the expression returns any value or throws any error, the token will be rejected.

Example: JWT User Authentication with Issuer and Audience Check

This example sets up additional token verification logic for a system user on a database using JSON Web Tokens (JWT) to authenticate. In this example, the HS512 algorithm is used to sign the token. The AUTHENTICATE block contains conditions to verify the token’s validity: it checks that the issuer (iss) of the token is “surrealdb-test” and throws an error if it is not. Similarly, it checks that the audience of the token (defined in the aud claim, which can be provided either as an array of strings or a single string) includes “surrealdb-test” and throws an error if it does not. If both checks pass, the token is considered valid. The session duration is set to 2 hours.

DEFINE ACCESS user ON DATABASE TYPE JWT
ALGORITHM HS512 KEY "sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8"
AUTHENTICATE {
  IF $token.iss != "surrealdb-test" { THROW "Invalid token issuer" };
  IF type::is::array($token.aud) {
    IF "surrealdb-test" NOT IN $token.aud { THROW "Invalid token audience" }
  } ELSE {
    IF $token.aud IS NOT "surrealdb-test" { THROW "Invalid token audience" }
  };
}
DURATION FOR SESSION 2h;

Using IF NOT EXISTS clause

The IF NOT EXISTS clause can be used to define an access method of type JWT only if it does not already exist. You should use the IF NOT EXISTS clause when defining an access method in SurrealDB if you want to ensure that the access method is only created if it does not already exist. If the access method already exists, the DEFINE ACCESS statement will return an error.

It’s particularly useful when you want to safely attempt to define an access method without manually checking its existence first.

-- Create a JWT access method for the example database if it does not already exist
DEFINE ACCESS IF NOT EXISTS example ON DATABASE TYPE JWT ALGORITHM HS512 KEY
"sNSYneezcr8kqphfOC6NwwraUHJCVAt0XjsRSNmssBaBRh3WyMa9TRfq8ST7fsU2H2kGiOpU4GbAF1bCiXmM1b3JGgleBzz7rsrz6VvYEM4q3CLkcO8CMBIlhwhzWmy8";

Using OVERWRITE clause

The OVERWRITE clause can be used to define an access method of type JWT and overwrite an existing one if it already exists. You should use the OVERWRITE clause when you want to modify an existing access method definition. If the access method already exists, the DEFINE ACCESS statement will overwrite the existing access method definition with the new one.

-- Create a JWT access method for the example database and overwrite it if it already exists
DEFINE ACCESS OVERWRITE example ON DATABASE TYPE JWT ALGORITHM HS512 KEY 'secret';
© SurrealDB GitHub Discord Community Cloud Features Releases Install