Skip to content

Secure Software Development Lifecycle

Statement

ClaimGuard's development lifecycle is structured to keep the application's security posture from regressing. The high-level shape:

  1. Documented invariants that all engineers can read in one place (docs/security/README.md).
  2. Branch-protected main with required code review.
  3. A protocol for security-relevant changes (docs/security/PROTOCOL.md) that enumerates when extra review or an explicit deferral is required.
  4. A versioned .snyk policy file so every accepted-risk decision is visible in source control and re-reviewed annually.
  5. 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 HTTPsafeFetch keystone, undici rebinding pin, allowed vs raw-fetch paths, blocklist scope.
  • Auth, authorization, and rate limitingJWT_SECRET mandatory-at-boot, audit-log org scoping, rate limiter mount point, CSP default.
  • Paths and uploadssafePath NUL handling, uploadClaim.js containment.
  • Dependency pinsundici, react-router-dom ≥ 6.30.x, Python pin floors for h11, urllib3, python-multipart, requests.
  • .snyk 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

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 safeFetch or document why a raw fetch is acceptable (the only legitimate cases are on-VM 127.0.0.1 calls, 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_MAP in server/src/lib/secrets.js and 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 .snyk 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).

.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.