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 (the internal security README).
- Branch-protected
mainwith required code review. - A protocol for security-relevant changes (the internal architecture-protocol document) that enumerates when extra review or an explicit deferral is required.
- A versioned the deferral policy file so every accepted-risk decision is visible in source control and re-reviewed annually.
- A change journal (the internal hardening journal) that records security-relevant cloud and code changes step-by-step.
Implementation¶
Single source of invariant truth¶
the internal security README is the authoritative engineer-facing document for security-relevant code paths. It lists the behaviors the codebase depends on under headings:
- Outbound HTTP — the outbound-HTTP wrapper keystone, 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. - the deferral policy file policy — 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¶
the internal architecture-protocol document complements the README by specifying how to make changes safely:
- When a PR touches an outbound HTTP sink, it must use the outbound-HTTP wrapper or
document why a raw
fetchis 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 the deferral policy file entry 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).
the deferral policy file policy as a contract¶
Every accepted-risk decision lives in the deferral policy 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 the internal hardening journal 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, the deferral 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.