Files
CASAN/infra/production/README.md
T

3.3 KiB

CASAN Linux Production Handoff

This directory turns the local production-like lab into a deployment that fails closed. It is deliberately parameterized: a real DNS name, enterprise OIDC tenant, Vault policy/token and S3 bucket are tenant-owned secrets and must not be invented or committed.

One-time infrastructure

  1. Create the DNS record for CASAN_PUBLIC_FQDN to the Linux host and allow TCP 443 only. Obtain a certificate whose SAN includes that exact name; place it at /opt/casan-control-panel/tls/tls.crt and tls.key (mode 0600).
  2. Register https://<fqdn>/oauth2/callback with the enterprise IdP. Map the groups claim to CASAN groups such as casan-org-admin and casan-approver. Copy oauth2-proxy.env.example outside the repo and fill it using the secret manager.
  3. Create a Vault Transit key casan-audit-key with exportable=false; give a workload identity only transit/sign/casan-audit-key and read-key metadata. Render a short-lived token into vault.env outside Git. Never use Vault dev mode or the root token.
  4. Create a versioned S3 bucket with Object Lock enabled at creation time. Require default COMPLIANCE retention, SSE-KMS with CASAN_S3_KMS_KEY_ID and deny delete/retention bypass. The runtime identity requires s3:PutObject plus s3:GetObjectLockConfiguration, scoped to the audit prefix.
  5. Let CI publish the API/UI as immutable @sha256 images, attest those artifacts and put the resulting digests in casan-prod.env.

Deploy

cp infra/production/casan-prod.env.example infra/production/casan-prod.env
# Fill non-secret paths, FQDN, image digests, S3 bucket and region.

sudo install -d -m 0700 /opt/casan-control-panel/tls /srv/casan/state /srv/casan/output
sudo install -m 0600 /dev/null /opt/casan-control-panel/oauth2-proxy.env
sudo install -m 0600 /dev/null /opt/casan-control-panel/runtime.env
sudo install -m 0600 /dev/null /opt/casan-control-panel/vault.env

bash packages/casan-harness/scripts/bash/production-preflight.sh infra/production/casan-prod.env
set -a; source infra/production/casan-prod.env; set +a
docker compose -f docker-compose.control-panel.yml up -d

The preflight performs a real Object Lock anchor write. It will reject local URLs, image tags, expired/near-expiry TLS, dev/root Vault tokens, incomplete OIDC, missing paths, and buckets without Object Lock. After login, run managed-prod-smoke.sh with an authenticated cookie jar.

Operational anchors

Run audit-ship-s3.sh after every audit seal from the same workload identity. Use a systemd timer or an orchestrated job; it produces a unique immutable key per audit head and asks S3 for COMPLIANCE retention on every write.

Install the included timer after the first successful preflight (the runtime identity must also have s3:GetObject so retries can be idempotent):

sudo install -D -m 0644 infra/production/systemd/casan-audit-anchor.service /etc/systemd/system/casan-audit-anchor.service
sudo install -D -m 0644 infra/production/systemd/casan-audit-anchor.timer /etc/systemd/system/casan-audit-anchor.timer
sudo install -D -m 0600 infra/production/casan-prod.env /etc/casan/production.env
sudo systemctl daemon-reload
sudo systemctl enable --now casan-audit-anchor.timer
systemctl list-timers casan-audit-anchor.timer