Security Audit — {{PROJECT_NAME}}
- Date: 2026-05-30 · Trigger: pre-deployment (before the intranet goes live, ADR-0008)
- Auditor: Security review (function unstaffed; run by the operating org), independent of the deploy decision
- Scope: the whole repo + the intranet build artifact — secrets, PII/confidentiality, dependencies, least-privilege (tools/permissions), CI/hooks secret handling, and the deploy/auth posture.
- Method: evidence-based —
git ls-files/git grepsecret & PII sweep,.gitignorereview,npm audit, a fullintranet/distbuild + leak scan, settings/permissions review, and per-agent tool-scope review.
Verdict
No critical or high-severity issues. Clear to deploy — conditional on one control: Vercel Deployment Protection (Vercel Authentication) MUST be enabled at/before the first deploy (SOP-003 step 3), because the published bundle contains the full internal corpus (by design). Four lower-severity findings; the two safe ones are remediated in this commit.
Findings
| # | Severity | Finding | Status |
|---|---|---|---|
| S-1 | Medium | External Reviewer over-privileged. Its charter says “read-only on the org,” but its tools granted Write, Edit, Bash — Edit/Bash exceed the mandate (could alter org files / run commands). |
Fixed — scoped to Read, Write, Grep, Glob (Write retained only to author reviews/ reports). |
| S-2 | Low | .gitignore lacked .env* — no secrets are committed today, but an accidental local .env could be added later. |
Fixed — added .env, .env.*, *.pem, *.key. |
| S-3 | Low–Med | PA inherits all tools (no tools: line) — the broadest surface in the org, and PA is the sole personal-info holder. Likely intended (handles email/calendar/files), but should be a conscious grant, not implicit. |
Closed — accepted, see hr/policies/pa-tool-scope.md |
| S-4 | Moderate (low real exposure) | Astro ≤6.1.9 advisory (XSS in define:vars; server-island replay). We use neither feature, content is first-party/trusted, and the site is static behind auth. Fix requires Astro 6 (breaking from our v5). |
Open — schedule the Astro 6 upgrade; not a deploy blocker. |
| S-5 | Informational (by design) | The built bundle publishes the entire internal corpus (security policy, the 360 review, reports, ORG, ADRs). Acceptable only behind the single-user gate. | Control: Deployment Protection ON before first deploy (SOP-003). |
Clean (verified, no issue)
- No committed secrets — no provider keys, private keys, JWTs, or
KEY=valuesecret literals anywhere tracked (excl. lockfile). - No Principal PII — personal email / personal data absent from repo and from
dist/. Commit identity is the bot, not a personal account. - Secrets handled correctly in CI/hooks —
NOTION_TOKEN,ANTHROPIC_API_KEY, etc. are referenced only via${{ secrets.* }}/ env and are gated (no-op when unset); never hard-coded. - Archivist GitHub scope is least-privilege — read/verify + branch/PR/
push_files; no merge, delete, admin, secret-scanning, or repo-creation scope. - Project permissions scoped —
.claude/settings.local.jsonlists specific commands/tools; no blanketBash(*). - Auth model sound — Vercel Authentication ties visibility to the Principal’s account (no shared password, no SSR secret); the site stays static (no server-side key surface).
- Reproducible installs —
package-lock.jsonpresent.
Recommendations (priority order)
- Before deploy: enable Deployment Protection (SOP-003 step 3) — the single gating control (S-5).
- Decide S-3: accept the PA’s broad tool grant explicitly (note it in the confidentiality/security policy) or scope it.
- Schedule S-4: plan the Astro 6 upgrade; re-run
npm auditafter. - Ongoing: keep secrets in env/Action secrets only; new integrations/tooling go through SOP-001 (access request) with least privilege, as the Archivist GitHub grant did.