Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

API Keys

Require API keys for backend SDK requests to a self-hosted Core and rotate multiple keys without downtime.

Overview

The backend SDK uses API keys to authenticate requests to SuperTokens Core.

By default, there is no API key required. After you configure one, every backend SDK must send a matching key or Core responds with HTTP 401.

Before you start

Steps

1. Add the key to the core instance

Generate a high-entropy key and store it in your deployment’s secret manager. For example:

openssl rand -hex 32

The command prints a 64-character key that satisfies Core’s character restrictions. Store it as SUPERTOKENS_API_KEY in your deployment’s secret manager. Do not commit it to source control, logs, shell history, or an image layer. Set SUPERTOKENS_IMAGE to an immutable, verified image reference rather than an untagged image or latest.

: "${SUPERTOKENS_IMAGE:?Set an immutable Core image reference}"
: "${SUPERTOKENS_API_KEY:?Load a generated Core API key from secret storage}"
if [[ ! "$SUPERTOKENS_API_KEY" =~ ^[A-Za-z0-9=-]{20,}(,[A-Za-z0-9=-]{20,})*$ ]]; then
  echo "SUPERTOKENS_API_KEY must contain one or more valid comma-separated Core API keys" >&2
  exit 1
fi

docker run \
    --network app-network \
    -e API_KEYS="$SUPERTOKENS_API_KEY" \
    -d "$SUPERTOKENS_IMAGE"
# You need to add the following to the config.yaml file.
# The file path can be found by running the "supertokens --help" command
# Replace this entire placeholder from secret storage before starting Core.
# Core rejects the literal placeholder because underscores are not valid API-key characters.

api_keys: "<REQUIRED_SUPERTOKENS_API_KEY>"
  • The format of the value is key1,key2,key3.
  • Keys can only contain =, -, and alphanumeric characters.
  • Each key must have a minimum length of 20 characters. This is a syntax requirement, not an entropy recommendation.
  • Each backend sends only one key. Core can accept multiple independently generated keys separated by commas.

Keep the Core and backend secret records separate, even if both workloads expose their value as SUPERTOKENS_API_KEY. During rotation, the Core record contains old-key,new-key; each backend secret record contains exactly one of those keys.

2. Add the key to your backend code

Inject one key currently accepted by Core into each backend as SUPERTOKENS_API_KEY.

import supertokens from "supertokens-node";

const apiKey = process.env.SUPERTOKENS_API_KEY;
if (apiKey === undefined || apiKey.length === 0) {
  throw new Error("SUPERTOKENS_API_KEY is required");
}

supertokens.init({
  supertokens: {
    connectionURI: "<CONNECTION_URI>",
    apiKey,
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [],
});
import (
	"os"

	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	apiKey := os.Getenv("SUPERTOKENS_API_KEY")
	if apiKey == "" {
		panic("SUPERTOKENS_API_KEY is required")
	}
	supertokens.Init(supertokens.TypeInput{
		Supertokens: &supertokens.ConnectionInfo{
			ConnectionURI: "<CONNECTION_URI>",
			APIKey: apiKey,
		},
	})
}
import os

from supertokens_python import init, InputAppInfo, SupertokensConfig

api_key = os.environ["SUPERTOKENS_API_KEY"]
if not api_key:
    raise RuntimeError("SUPERTOKENS_API_KEY is required")

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    supertokens_config=SupertokensConfig(
        connection_uri='<CONNECTION_URI>',
        api_key=api_key
    ),
    framework='...',
    recipe_list=[
      #...
   ]
)

3. Rotate a key safely

Use an overlap period so that Core never rejects a backend that has not been updated yet:

  1. Generate a new independent key and store it in secret storage. Keep the old key active.
  2. Set Core’s API_KEYS value to old-key,new-key, deploy or restart every Core instance, and explicitly test a protected API with each key from a trusted network. Do not continue unless both work.
  3. Rotate all backends to the new key. Use a staged deployment where possible. Monitor backend request failures, the HTTP 401 rate in Core or edge telemetry, and deployment health throughout the change. Core does not identify which matching key was used, so use controlled old-key and new-key probes to verify both paths during the overlap.
  4. Confirm every backend is healthy on the new key and that no planned rollback still depends on the old key. Then remove the old key from Core and deploy every Core instance. Verify the new key works and the old key now receives HTTP 401.
  5. Retain the old key securely for a defined rollback window, but do not leave it active in Core. A rollback must first re-add the old key to Core, verify both keys, and only then roll back a backend. Destroy the old key after the window.

Never replace the old key in Core before all Core instances accept the new key, and never remove it while any backend still uses it.

API reference

API schema and response details