Skip to Content
SimulatorsClerkThe signing key

Simulators

The signing key

The simulator signs session tokens with the key CLERK_TWIN_PRIVATE_KEY_FILE names. Without that variable, it makes an RSA key on its first start and keeps it in its data folder. It signs with the same key on every later start, so tokens issued earlier still verify. Your site reads the key’s public half from /_twin/config or the JWKS, so it needs no key file either.

The data folder is RYSTIC_DATA_DIR, which the container image sets to /var/lib/rystic/data:

How the simulator runsThe key
a container that restarts (docker compose restart)stays the same
a container recreated with a named volume at /var/lib/rystic/data, as a stack from rystic export compose or rystic compose mountsstays the same
a container recreated without that volume, or after docker compose down -v removes itis new
a process with RYSTIC_DATA_DIR unset, or set to a folder it cannot writeis new at each start, and the simulator prints a warning saying why

To see the key kept, start the simulator on a data folder, stop it and start it again on the same folder:

DATA=$(mktemp -d)
KEEP_URL=$(rystic run clerk-twin --runner native -d --name keep --port 0 --env RYSTIC_DATA_DIR="$DATA" --json | jq -r .data.url)
FIRST=$(curl -s "$KEEP_URL/v1/jwks" | jq -r '.keys[0].kid')
rystic stop keep > /dev/null
KEEP_URL=$(rystic run clerk-twin --runner native -d --name keep --port 0 --env RYSTIC_DATA_DIR="$DATA" --json | jq -r .data.url)
[ -n "$FIRST" ] && [ "$(curl -s "$KEEP_URL/v1/jwks" | jq -r '.keys[0].kid')" = "$FIRST" ] && echo "same key"
# -> same key
ls "$DATA"
# -> clerk-browser-key.pem
rystic stop keep > /dev/null

rystic export compose and rystic compose give every simulator service a named volume, rystic-<service>-data, at /var/lib/rystic/data. In a Compose file you write yourself, mount one on the Clerk simulator’s service:

services:
  clerk:
    volumes:
      - clerk-data:/var/lib/rystic/data
volumes:
  clerk-data: {}

A kept key the simulator cannot read, or that is not an RSA key of at least 2048 bits, stops the simulator at start, with an error naming the file. Delete the file to make a new key.

Last updated on