A GitHub App user token generally can't read orgs the App isn't installed on, which is
exactly when canInstall is asked. Read the owner type anonymously first (GET /users/{owner}):
another user's account is false; an org is true only for active admin, false for another
role/state, and null for 403/404/errors/timeouts. Owner-type lookup failures are null.
Present while the Orca GitHub App isn't installed for the repo owner ('missing', or
'public' with no installation). true: the caller's connected GitHub login is the owner,
or their membership in the owner org is active admin. false: member, non-member (403/404),
or another user's account. null: no connected GitHub user token, the token can't be read
or refreshed, or GitHub errored / timed out (3 s). Never fails the answer.
The token comes from memberGitIdentity (decrypt + refresh near expiry).
ownersForSandbox resolves no personal owner unless the row is private, so a workspace shared with the team gets team and repository secrets only (values and placeholders). The egress proxy's cached keys are keyed by visibility so sharing takes effect at once. Share toast and Personal tab say so.
POST /v1/internal/entitlements/features now also returns subscribed: the
account has a subscription that is active, trialing, past_due or unpaid.
Auth counts it as Orca Cloud access, so a paying team that is not on the
per-account rollout is no longer told to choose a plan (and then refused
at checkout as already subscribed).
Read from the subscription row Stripe's webhooks keep, in every
ENTITLEMENTS_MODE. Canceled, incomplete, expired and paused
subscriptions, the no-card trial and no subscription are false.
Co-Authored-By: Claude <noreply@anthropic.com>
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.
Turning overage off left the card's save flag set, so the off view showed a stuck
check-mark "Saving…" in place of the Turn on button. Replace the flag with a save
state (saving -> saved | error) that always ends with the request, and keep Turn on
rendered in the off view at all times.
Co-Authored-By: Claude <noreply@anthropic.com>
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 lockfile still listed apps/eval (renamed apps/acceptance) and pinned jose 6.2.13 in three importers
while only jose@6.2.16 was in packages (a bad merge), so pnpm install --frozen-lockfile failed. Ran
pnpm install --fix-lockfile --lockfile-only: importer apps/eval -> apps/acceptance, jose -> 6.2.16
(the one already locked; satisfies ^6.2.13), two orphaned packages dropped. No other version changes.
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.