Part of the coding standards. AGENTS.md "Hard boundaries" owns which credentials may enter a job. docs/operations.md owns secret names and rotation.
npm run lintenforces SHA-pinned actions,persist-credentials: false, and a top-levelpermissions:block. Review what it cannot: each permission beyondcontents: readis the smallest that works and has a comment saying why (#27).- A job that loads protected secrets runs only on trusted refs. Check
github.ref == 'refs/heads/main'for manual dispatch, and requireworkflow_run.event == 'push'for chained workflows, because a fork PR can have a branch namedmain(#8, #21). - A manual dispatch path enforces the same build gate as the automatic one (#26).
- Guard steps that depend on files an earlier conditional step creates (#8).
- Never print an access code or token, even in a plan's example command (#8).
- Session state written by a test lives outside directories CI uploads as artifacts (#11).
- A suite that writes a real session into a browser restricts its base URL to loopback (#21).
- Documentation names the secret, never the account's email or password (#68).
- One secret, one purpose. Do not derive signing keys from the service-role key; rotating it would break every outstanding token (#13).
- An Edge Function that fetches a user-supplied URL connects only to an address it has just checked against the IANA special-purpose ranges, never to the hostname:
fetchresolves the name again, so a DNS answer that changes in between (rebinding) would reach a blocked range.import-sourcedials the checked address withpinned-fetch.ts, on every redirect hop. Citation verification does not fetch at all (verifyUrlinsupabase/functions/_shared/research.ts). Closed finding [7] of the 2026-08-19 review.
These were raised in review, judged valid, and accepted on purpose. Changing them needs Adam's decision, not a reviewer's.
- Live provider keys reach branch code in
live-e2e.yml(including its model-matrix job) andagentic-e2e.ymlwhen someone with push access dispatches them on a branch. Since 2026-10-29 these no longer run on pull requests. Adam accepted the original pull-request exposure on PR #68; the mitigation is dedicated low-limit keys (#68). - The production canary account's credentials reach
prod-canary.ymlthrough Actions secrets, approved 2026-09-24 and recorded in AGENTS.md (#68). - Manual canary runs can exhaust the account's daily quota; that shows as a quota error, not a false pass (#68).
- CodeRabbit rated the shared preview-origin allowlist from PR #95 as a high retained concern: an approved production preview runs unmerged code that can receive demo-session handoffs (#95 security review). docs/operations.md describes the current setup. This one has no recorded decision yet.
src/lib/observability.ts is the only path to PostHog and Sentry.
- Events use a closed allowlist of names, and string attributes accept only listed values. An open string field lets a caller send debate content (#22).
- Error boundaries report a fixed error with fixed context, never the caught error, whose message can contain user input (#16).
- Count only events that really happened. A route event fired before the auth redirect recorded denied access as a visit (#16 review).