# Deployment

## Dependencies

- Go 1.26 or newer
- MySQL 8 with `multiStatements=true` in the DSN
- Redis
- HTTPS termination through a trusted reverse proxy or load balancer

## Required Production Configuration

```text
APP_ENV=production
MYSQL_DSN=...
REDIS_ADDR=...
SESSION_COOKIE_NAME=auth_session
COOKIE_SECURE=true
RATE_LIMIT_ENABLED=true
LICENSE_SIGNING_PRIVATE_KEY=base64-encoded-ed25519-seed-or-private-key
LICENSE_SIGNING_KEY_ID=license-2026-01
LICENSE_CODE_ENCRYPTION_KEY=base64-encoded-32-byte-aes-key
RELEASE_DIR=/srv/auth-center/releases
ADMIN_BOOTSTRAP_USERNAME=admin
ADMIN_BOOTSTRAP_PASSWORD=use-a-long-unique-secret
INSTANCE_TOKEN_TTL=8760h
LICENSE_LEASE_TTL=60m
```

The Ed25519 private key and AES key must come from the deployment secret manager. They must not be committed, logged, returned by an API, or stored in business database columns. All authorization nodes must use the same active signing key ID and private key.

`RELEASE_DIR` must point to a local, read-only directory containing the signed base release ZIP files. The service creates a short-lived, per-download ZIP beside those artifacts and appends a signed `license-delivery.json`; the base ZIP files are never modified. All authorization nodes must have the same release artifacts and signing key so a delivery can be verified from the public key endpoint.

Set `ADMIN_BOOTSTRAP_USERNAME` and `ADMIN_BOOTSTRAP_PASSWORD` together only for first startup. When no administrator exists, the server creates or promotes that username to `admin`; once an administrator exists, bootstrap configuration is ignored. Store the bootstrap password in the secret manager and remove it after verifying `/admin/login`.

All authorization nodes must synchronize their clocks with a reliable NTP source. Monitoring should alert before clock drift reaches one minute; clients reject responses more than five minutes in the future or ten minutes in the past.

## Startup

```powershell
cd backend
go build -o auth-server.exe ./cmd/server
./auth-server.exe
```

Startup connects to MySQL and Redis and applies embedded migrations under a MySQL advisory lock. Back up the database before production migrations.

## Verification

```powershell
go test -p 1 ./...
curl https://license.example.com/api/health
curl https://license.example.com/api/v1/licenses/public-key
```

The public key response must expose the configured `keyId`, `Ed25519`, and a 32-byte unpadded Base64URL public key. The private key must never appear in application logs or responses.
