66 lines
3.3 KiB
Markdown
66 lines
3.3 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
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):
|
|
|
|
```bash
|
|
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
|
|
```
|