> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blindcast.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Configure the key server with environment variables: master key, authentication, CORS, presign, and database.

The key server is configured entirely via environment variables. No config files needed.

## Required variables

| Variable         | Description                                                                                  |
| ---------------- | -------------------------------------------------------------------------------------------- |
| `MASTER_KEY_HEX` | Master key as hex string (64 chars = 32 bytes). From `blindcast keygen`.                     |
| `SALT_HEX`       | Salt as hex string (64 chars = 32 bytes). From `blindcast keygen`.                           |
| `CORS_ORIGINS`   | Allowed CORS origin. Must match your app's domain exactly (e.g., `https://app.example.com`). |

<Warning>
  Never set `CORS_ORIGINS=*` in production. The key server sends `Access-Control-Allow-Origin` with the exact matching origin and includes `Vary: Origin` for correct caching.
</Warning>

## Authentication

Set one of these to enable JWT validation on key requests. If neither is set, the key server runs in **development mode** with no authentication.

| Variable          | Description                                                                                                |
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
| `AUTH_JWT_SECRET` | Base64-encoded shared secret for HS256 JWT validation                                                      |
| `AUTH_JWKS_URL`   | URL to a JWKS endpoint for RS256/ES256 validation (e.g., `https://auth.example.com/.well-known/jwks.json`) |

If both are set, `AUTH_JWKS_URL` takes precedence.

### How auth works

1. The player sends `Authorization: Bearer <token>` on every key request
2. The key server validates the JWT signature
3. If valid, the key is derived and returned
4. If invalid or expired, the server returns `401 Unauthorized`

```bash theme={null}
# Example: Auth0
docker run -d \
  -e MASTER_KEY_HEX=... \
  -e SALT_HEX=... \
  -e CORS_ORIGINS=https://app.example.com \
  -e AUTH_JWKS_URL=https://your-tenant.auth0.com/.well-known/jwks.json \
  -p 4100:4100 \
  blindcast/keyserver
```

## Optional variables

| Variable                | Default                       | Description                                                   |
| ----------------------- | ----------------------------- | ------------------------------------------------------------- |
| `PORT`                  | `4100`                        | Port to listen on                                             |
| `ENABLE_PRESIGN`        | `false`                       | Enable the presign endpoint for browser uploads               |
| `S3_BUCKET`             | —                             | S3 bucket for presigned URLs (required if presign is enabled) |
| `S3_REGION`             | `us-east-1`                   | AWS region                                                    |
| `AWS_ACCESS_KEY_ID`     | —                             | AWS credentials (for presign)                                 |
| `AWS_SECRET_ACCESS_KEY` | —                             | AWS credentials (for presign)                                 |
| `DATABASE_URL`          | `sqlite:///data/blindcast.db` | Database URL for lease storage                                |
| `LEASE_TTL_MS`          | `300000` (5 min)              | Default lease TTL in milliseconds                             |

## Docker volumes

| Path    | Purpose                                        |
| ------- | ---------------------------------------------- |
| `/data` | SQLite database file (persist across restarts) |

```bash theme={null}
docker run -d \
  -v blindcast-data:/data \
  -e MASTER_KEY_HEX=... \
  -e SALT_HEX=... \
  -e CORS_ORIGINS=https://app.example.com \
  -p 4100:4100 \
  blindcast/keyserver
```

## Health check

`GET /health` returns `200 OK` with `{ "status": "ok" }`. Use this for Docker health checks and load balancer probes.

```bash theme={null}
curl http://localhost:4100/health
# {"status":"ok"}
```
