Skip to content

Secure Development Policy

Field Value
Status draft
Owner INFRA
Applies to All Partile code: backend (FastAPI/Python), mobile (React Native/TS), infra-as-code, and the Atelier development workflow.
Review cadence Annual, or on material change to the stack or threat model.
Mapped controls SEC-01–07 and SEC-10 (auth, authz, intake hardening, secret hygiene, rate limiting, signed-token validation), SEC-15 (IDOR regression test), OPS-04 (reviewed PRs).
Evidence partile-infra: app/models.py, app/api.py, app/auth/*, repositories/*; readiness/threat-model-and-auth-review.md; Git/PR history.
Exception handling A known weakness shipped knowingly is logged as risk-accepted (risk-management-policy.md) with a fix milestone.

Purpose

Make security properties a build-time default in Partile's code, grounded in the patterns already implemented in the backend rather than generic SDLC theory.

Secure-by-default patterns (already in the codebase — keep them)

  • Input is whitelisted, not blacklisted, then sanitized. Presence intake uses a Pydantic whitelist + extra="forbid" + banned-field rejection; 422 errors are sanitized to loc/msg/type with no echoed values (SEC-06).
  • Don't store the sensitive form. No raw boarding-pass artifacts; session tokens stored only as SHA-256 hashes; OAuth tokens never persisted; LinkedIn id_token verified via JWKS before identity is trusted (SEC-01, SEC-05, SEC-10, PRIV-06).
  • Authorize in the data layer. Object-level checks live in SQL; non-visible → 404, no existence leak (SEC-04). New read paths must follow this pattern.
  • Secrets never logged. Access logs are off in the container; no secret values in logs or errors (SEC-05).

Requirements for new code

  1. Threat-model the change when it touches auth, data, matching, messaging, safety, or admin surfaces — update readiness/threat-model-and-auth-review.md.
  2. No new IDOR. Every object read enforces ownership/visibility in the query; add/extend the cross-user 404 regression test (SEC-15).
  3. Enforce safety predicates in code, not docs. Block separation, consent tiers (ai-ml-data-governance-policy.md), and rate limits are enforced by the code path, with smoke tests (safety_smoke.py, rate_limit_smoke.py).
  4. No secrets in source. Configuration via env/Secret Manager; safe labels only in repo.
  5. Validate and minimize at the boundary. Reject unknown fields; persist only the minimal derived data the feature needs.
  6. Dependencies are added deliberately and tracked for vulnerabilities (vulnerability-management-policy.md).

Review & merge

All code lands via reviewed PRs through the Atelier checkpoint and merges to main (change-management-policy.md, ../procedures/release-review-procedure.md). Security-relevant PRs update the control register row.

Production preflight

Before any real-user data, the security preflight gates apply: assert APP_ENV=production (dev routes unmounted), Cloud Run edge/origin TLS, private Cloud SQL and Redis access through the VPC connector, rate limits live, sweeps running, block enforcement live, IDOR test green, and secrets confirmed in GCP Secret Manager (SEC-05, SEC-08, SEC-09; see readiness/threat-model-and-auth-review.md and technical/infrastructure-and-deployment.md).

Exceptions

Shipping a known weakness (e.g. deferring session idle timeout/rotation or production HA/restore-drill maturity) requires a dated risk-acceptance with a compensating control and a fix milestone, recorded on the control row and in the READINESS.md decision log.