# Authentication

The Go SDK provides methods for signing in, signing up, and managing authentication at root, namespace, database, and record levels.

The Go SDK supports signing in at different access levels, signing up record users, and managing authentication tokens. Authentication is required before most operations and determines what data the connection can access.

This page covers the different authentication levels, how to use refresh tokens, and how to manage authentication state on a connection.

## API references

<table>
	<thead>
		<tr>
			<th scope="col">Method</th>
			<th scope="col">Description</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#signin"><code>db.SignIn(ctx, authData)</code></a></td>
			<td scope="row" data-label="Description">Signs in an existing user and returns a JWT token</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#signinwithrefresh"><code>db.SignInWithRefresh(ctx, authData)</code></a></td>
			<td scope="row" data-label="Description">Signs in and returns both an access token and a refresh token</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#signup"><code>db.SignUp(ctx, authData)</code></a></td>
			<td scope="row" data-label="Description">Signs up a new record user and returns a JWT token</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#signupwithrefresh"><code>db.SignUpWithRefresh(ctx, authData)</code></a></td>
			<td scope="row" data-label="Description">Signs up a new record user and returns both tokens</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#authenticate"><code>db.Authenticate(ctx, token)</code></a></td>
			<td scope="row" data-label="Description">Authenticates the connection with a JWT token</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#invalidate"><code>db.Invalidate(ctx)</code></a></td>
			<td scope="row" data-label="Description">Invalidates the current authentication</td>
		</tr>
		<tr>
			<td scope="row" data-label="Method"><a href="/docs/reference/golang/api/core/db.md#info"><code>db.Info(ctx)</code></a></td>
			<td scope="row" data-label="Description">Returns the record of the currently authenticated user</td>
		</tr>
	</tbody>
</table>

## Authentication levels

SurrealDB supports four authentication levels. The fields you provide in the authentication data determine which level is used.

| Level | Required fields | Access to |
|---|---|---|
| Root | `Username`, `Password` | All namespaces and databases |
| Namespace | `Namespace`, `Username`, `Password` | All databases in the namespace |
| Database | `Namespace`, `Database`, `Username`, `Password` | A single database |
| Record | `Namespace`, `Database`, `Access`, `Username`, `Password` | Records determined by the access method |

You can provide credentials using either the [`Auth`](/docs/reference/golang/api/types.md#auth) struct or a `map[string]any`.

## Signing in as a system user

To sign in as a root, namespace, or database user, provide the appropriate fields. The level is determined by which fields are set.

```go
token, err := db.SignIn(ctx, surrealdb.Auth{
	Username: "root",
	Password: "secret",
})
```

```go
token, err := db.SignIn(ctx, surrealdb.Auth{
	Namespace: "my_ns",
	Database:  "my_db",
	Username:  "db_user",
	Password:  "db_pass",
})
```

## Signing in as a record user

Record-level authentication requires the `Access` field, which specifies which [`DEFINE ACCESS`](/docs/reference/query-language/statements/define/access.md) method to use.

```go
token, err := db.SignIn(ctx, surrealdb.Auth{
	Namespace: "my_ns",
	Database:  "my_db",
	Access:    "user_access",
	Username:  "tobie",
	Password:  "s3cret",
})
```

You can also use a `map[string]any` to pass additional fields required by the access method:

```go
token, err := db.SignIn(ctx, map[string]any{
	"NS":   "my_ns",
	"DB":   "my_db",
	"AC":   "user_access",
	"user": "tobie",
	"pass": "s3cret",
})
```

## Signing up new record users

The `.SignUp()` method creates a new record user using a `DEFINE ACCESS ... TYPE RECORD` access method. The access method must be defined before calling `.SignUp()`.

```go
token, err := db.SignUp(ctx, map[string]any{
	"NS":    "my_ns",
	"DB":    "my_db",
	"AC":    "user_access",
	"user":  "new_user",
	"pass":  "s3cret",
	"email": "user@example.com",
})
```

## Using refresh tokens

SurrealDB v3 supports refresh tokens for `TYPE RECORD` access methods that have `WITH REFRESH` enabled. Use `.SignInWithRefresh()` or `.SignUpWithRefresh()` to receive both an access token and a refresh token.

```go
tokens, err := db.SignInWithRefresh(ctx, map[string]any{
	"NS":   "my_ns",
	"DB":   "my_db",
	"AC":   "user_access",
	"user": "tobie",
	"pass": "s3cret",
})
```

The returned [`Tokens`](/docs/reference/golang/api/types.md#tokens) contains an `Access` field (JWT) and a `Refresh` field. To obtain new tokens without re-entering credentials, pass the refresh token:

```go
newTokens, err := db.SignInWithRefresh(ctx, map[string]any{
	"NS":      "my_ns",
	"DB":      "my_db",
	"AC":      "user_access",
	"refresh": tokens.Refresh,
})
```

> [!NOTE]
> Refresh tokens are only available with `TYPE RECORD` access methods that have `WITH REFRESH` enabled (SurrealDB v3+).

## Using bearer access

For `TYPE BEARER` access methods (SurrealDB v3+), use the `key` parameter with a bearer key obtained from `ACCESS ... GRANT`. No username or password is required.

```go
token, err := db.SignIn(ctx, map[string]any{
	"NS":  "my_ns",
	"DB":  "my_db",
	"AC":  "bearer_api",
	"key": bearerKey,
})
```

## Authenticating with an existing token

Use `.Authenticate()` to apply a previously obtained JWT to the connection. This is useful when restoring a session from a stored token or transferring authentication to a new connection.

```go
if err := db.Authenticate(ctx, token); err != nil {
	log.Fatal(err)
}
```

## Invalidating authentication

Call `.Invalidate()` to remove the current authentication from the connection. After calling this, the connection returns to an unauthenticated state.

```go
if err := db.Invalidate(ctx); err != nil {
	log.Fatal(err)
}
```

## Retrieving user information

The `.Info()` method returns the record of the currently authenticated user. This is only available when signed in as a record user.

```go
info, err := db.Info(ctx)
if err != nil {
	log.Fatal(err)
}
fmt.Println(info)
```

## Learn more

- [DB API reference](/docs/reference/golang/api/core/db.md) for complete method signatures and parameters
- [Types reference](/docs/reference/golang/api/types.md) for `Auth` and `Tokens` type definitions
- [Connecting to SurrealDB](/docs/reference/golang/concepts/connecting-to-surrealdb.md) for connection protocols and their effect on authentication
- [DEFINE ACCESS statement](/docs/reference/query-language/statements/define/access.md) for configuring access methods
- [Security best practices](/docs/learn/security/best-practices/security-best-practices.md) for token and session duration configuration
