SurrealDB has four authentication methods. Which one you want depends on who is signing in: a person administering the instance, an end user of your application, a client an external identity provider has already authenticated, or another system.
Each method is defined in SurrealQL and then used the same way from every interface, so the choice below decides the rest of the page.
Choosing a method
| Method | Who it is for | Defined with | Signed in with |
|---|---|---|---|
| System users | Operators and services administering an instance | DEFINE USER at root, namespace or database level | A username and password |
| Record users | End users of your application, one record each | DEFINE ACCESS ... TYPE RECORD, whose SIGNUP and SIGNIN clauses are queries you write | Whatever fields your SIGNIN query reads |
| JWT access | Clients an external provider has already authenticated | DEFINE ACCESS ... TYPE JWT, holding the issuer's public key or shared secret | A token the provider issued |
| Bearer access | Other systems and software | DEFINE ACCESS ... TYPE BEARER, plus an ACCESS ... GRANT per client | The key from a grant |
System users and record users answer to credentials SurrealDB holds. JWT access holds no end user credential: it checks the signature on a token an external provider issued, then trusts the claims inside it, which is how an OpenID Connect or OAuth provider is brought in. It does hold the material for that check, and which kind matters - a public key or a JWKS URL can only verify, while an HMAC key is symmetric and can also sign. Bearer access sits between the two, issuing a key per client that you can audit and revoke without touching the user it acts as.
TYPE JWT uses HS256 when no algorithm is given, and the HMAC algorithms (HS256, HS384, HS512) take one secret that both signs and verifies. Anyone holding it can issue tokens with any claims they like, and SurrealDB will trust them. Protect that key on the SurrealDB side as well as at the issuer, or define the access method with a public key or a JWKS URL, neither of which can sign.
A record user is scoped to one database and restricted by table and field permissions. A root system user is not restricted by permissions at all, so it is the wrong credential to put in an application.
Signing in
Every interface signs in with the same credentials, so an example written for one carries over to the others.
SurrealQL, HTTP and the SDKs are covered end to end on Users, which defines a user of each kind and then signs in as it.
Over HTTP, post the credentials to POST /signin, or create a record user with POST /signup. Both return a token for later requests:
curl -X POST \
-H "Accept: application/json" \
-d '{"user":"root", "pass":"secret"}' \
http://localhost:8000/signinFrom an SDK, each language documents its own signin call and the shape of the credentials it takes:
Rust · JavaScript · Python · Go · Java · Kotlin · .NET · PHP · Swift · Mojo
After signing in
Sessions - what the connection carries once authenticated, and how tokens and sessions expire.
Permissions and row-level security - what the authenticated user is then allowed to read and write.
Tokens and JWTs - the claims SurrealDB reads from a token, and the parameters they populate.
Security best practices - choosing expiry, storing secrets, and what to expose to a browser.