SECRETS_KEK_SOURCE=kms unwraps KMS-wrapped KEKs once per isolate. Unset, the
SECRETS_KEK path is unchanged. With it on there is no plaintext fallback: a KMS
failure answers 503 secrets_unavailable and a workspace create fails instead of
starting without secrets. Tested against a fake KMS only.
Environment builds get only the team secrets an admin named, never a swapped model key, hand them to the install script alone, and fail with no snapshot (secret_in_image) when a value is still in a file the build changed.
Operator routes GET /v1/internal/secrets/kek and POST /v1/internal/secrets/rewrap
move every envelope-encrypted row (secrets, agent_credentials, github_user_tokens)
from a retired KEK to the active one: idempotent, resumable, conditional writes,
counts-only logs. A v2 row format behind SECRETS_SEAL_FORMAT=v2 (default v1)
keeps the KEK id out of the value layer's AAD so rotation re-wraps data keys
without decrypting values. Adds the KMS design doc.
The generator now emits VM_SCRIPTS_HASH and a monotonic VM_SCRIPTS_STAMP
(kept while the scripts are unchanged; max(previous + 1, now) on a change).
Provisioning records the stamp in /opt/orca/bin/.scripts-stamp (source
builds use the fetched commit's stamp), installEntryPoints writes the
Worker's, and ensureEntryPoints probes stamp + marker in one command and
skips images whose stamp is newer than the Worker's. Golden refreshes use
ensureEntryPoints too, so a lagging Worker cannot bake older scripts into
a refreshed golden.
billing: GET /v1/internal/accounts/:accountId/subscription -> {status, open}
(MEMBERSHIP_SYNC_TOKEN), so auth refuses to delete a team with an open subscription.
sandbox-control (auth's MEMBER_REMOVED_TOKEN, never the operator routes):
- GET /v1/internal/accounts/:accountId/delete-check -> {workspaces}: the team's
workspaces in any state but destroyed.
- POST /v1/internal/accounts/:accountId/secrets/purge -> {purged}: deletes the
team's org- and repo-scoped cloud secrets; 409 workspaces_exist while any remain.
Found by the dev shadow run: Stripe test clocks put current_period_start a month ahead, so the
grant read as not started and the resolver denied (subscription_inactive) where legacy allowed.
starts_at is now min(period start, first sync) and stays stable across syncs.
- catalog: Team v2 (same entitlements and policy as v1, so v1 subscribers see no change) adds the
sandbox_spec and ready_in_seconds features the desktop already localizes; currentVersion 2
- catalog plans take an optional supportUrl (https: or mailto: only) and GET /v1/plans returns it
per plan; clients fall back to the Enterprise contact
Neil's Q1 answer: a plan id on the Stripe Price/Product maps to the repo catalog's entitlements.
seatPriceMatch reads price.metadata.orca_plan (after env ids and price history, before lookup key
and product); the catalog sync logs a lookup-key/tag mismatch; stripe-test-setup tags every price.