Secure Software Development Lifecycle¶
Statement¶
ClaimGuard's development lifecycle is structured to keep the application's security posture from regressing. The high-level shape:
- Documented invariants that all engineers can read in one place
(
docs/security/README.md). - Branch-protected
mainwith required code review. - A protocol for security-relevant changes
(
docs/security/PROTOCOL.md) that enumerates when extra review or an explicit deferral is required. - A versioned
.snykpolicy file so every accepted-risk decision is visible in source control and re-reviewed annually. - A change journal (
docs/security/HARDENING-LOG.md) that records security-relevant cloud and code changes step-by-step.
Implementation¶
Single source of invariant truth¶
docs/security/README.md is the authoritative engineer-facing document
for security-relevant code paths. It lists the behaviors the codebase
depends on under headings:
- Outbound HTTP —
safeFetchkeystone, undici rebinding pin, allowed vs raw-fetchpaths, blocklist scope. - Auth, authorization, and rate limiting —
JWT_SECRETmandatory-at-boot, audit-log org scoping, rate limiter mount point, CSP default. - Paths and uploads —
safePathNUL handling,uploadClaim.jscontainment. - Dependency pins —
undici,react-router-dom ≥ 6.30.x, Python pin floors forh11,urllib3,python-multipart,requests. .snykpolicy — what categories of deferral are acceptable.
Engineers touching server code, Python tools, outbound HTTP, auth, rate limiting, uploads, or dependency manifests read this file first. The invariants are written so a reviewer can check a PR against them by inspection.
Engineering protocol¶
docs/security/PROTOCOL.md complements the README by specifying how to
make changes safely:
- When a PR touches an outbound HTTP sink, it must use
safeFetchor document why a rawfetchis acceptable (the only legitimate cases are on-VM127.0.0.1calls, listed by line in the protocol). - When a PR adds a new env var that holds a secret, it must be added to
the
SECRET_MAPinserver/src/lib/secrets.jsand provisioned in Secret Manager (see Secrets management). - When a PR removes or weakens an invariant, the change must come with
either a new invariant or a
.snykentry plus a documented reason.
Branch protection and review¶
The main branch is protected; merges require pull requests. The
remediation work that produced the current security posture was reviewed
via a multi-agent code review (/ultrareview) before merge — see commit
5c0f0d0 ("Merge security/remediation-2026-04 into main") and its
predecessor regression-gap commit (7e8becc).
.snyk policy as a contract¶
Every accepted-risk decision lives in the root .snyk file with three
required fields:
- Reason: what specifically dispositions the finding (false positive, scanner gap, non-reachable vector, dev-only).
- Created: when the deferral was decided.
- Expires: one year from creation, forcing annual re-review.
Deletion or weakening of an existing entry requires a corresponding code change (the underlying issue was fixed) or a documented reason update. "Silently strip" is not an acceptable disposition.
Change journal¶
Cloud and code changes that affect security posture are captured in
docs/security/HARDENING-LOG.md as they happen, with the same shape every
time:
- What: the action.
- Why: the plan step or motivation.
- Commands: the exact, reproducible invocation.
- Verify: how we confirmed it landed.
- Notes: surprises and follow-ups.
The journal is the canonical record. This trust portal points back at it rather than duplicating its contents.
Status¶
implemented — the documented invariants, protocol, branch protection,
.snyk policy file, and journal are all in place and active. Verified
2026-04-29.
Roadmap¶
- CI integration — Snyk Open Source + Snyk Code on every PR (planned; see Snyk summary roadmap section).
- SAST and SCA dashboards linked from this page once CI is wired.
- Pre-commit hooks for engineering invariants (e.g., flag a raw
fetch(outside the documented allowlist) — under evaluation.