| Asset | Exposure |
|---|---|
HARNESS_SECRET (and HARNESS_SECRET_PREVIOUS) |
Workers secret; signs confirm/unsubscribe/status tokens (ADR 0006) |
ADMIN_TOKEN |
Workers secret; gates /v1/<module>/admin/* |
RESEND_API_KEY, TURNSTILE_SECRET |
Adapter secrets, read by the venture's runtime composition |
| Subscriber/waitlist tables (D1/SQLite) | Email addresses + state; per-venture database |
| Public HTTP surface | /v1/email-signup, /v1/waitlist (+ confirm/unsubscribe/status), /__health, /__ready |
- No enumeration. Signup and waitlist writes answer a byte-identical
202for every row state; tests compare all four responses byte for byte. - Signed, purpose-scoped, expiring tokens. HMAC-SHA256 with key
rotation by
kid; MAC comparison constant-time (subtle); single-use via row state. - Fixed redirects. Confirm/unsubscribe/status redirect only to URLs
from
Ventureconfig or module builders; a test asserts no route readsredirect/return/nextquery parameters. - Admin auth.
factory0_core::admin::require_admin: disabled (401) whenADMIN_TOKENis unset, SHA-256-digest constant-time compare, 403 on a wrong token; the token never appears in tracing fields. - CSV formula-injection guard.
factory0_core::csv::escapeprefixes= + - @ \t \rleading cells with'before RFC 4180 quoting. - Rate limits on every public route — including confirm and status —
keyed
ip:<cf-connecting-ip>(neverx-forwarded-foron Workers) andemail:<normalized>; 429 carriesRetry-After. - Captcha mandatory in production when any module has
public_writes():fz doctorfails the build;--allow-no-captcha <reason>downgrades to a warning for the stated reason. - PII minimalism and retention. See PRIVACY.md.
- Redaction. Field names matching
(?i)secret|token|key| authorization|passwordare replaced with[redacted]; email values appear only as a 12-hexsubject_hash(rules infactory0_core::logging, shared by every runtime formatter; verified by tests). - No
unsafein core or any module (#![forbid(unsafe_code)]); the onlyunsafe-adjacent code isworker::send::SendWrapperinside theworkercrate (ADR 0002).
cargo deny checkruns in CI on every PR: advisories (vulnerabilities and yanked crates) are deny, licenses restricted to the allowlist indeny.toml, unknown registries and git sources denied.- Runtime dependency boundaries are enforced in CI:
factory0-coreand everyfactory0-module-*must build towasm32-unknown-unknownand must not pullworker,wasm-bindgen,tokio,reqwest,sqlxorrusqlite(the example venture'sworker-buildjob catches it). - Ventures pin exact crate versions; Renovate opens bumps, CI re-runs the full deny + build gate on every bump.
- The Cloudflare account, D1 infrastructure and Workers secrets provisioning (managed by each venture's deployment workflow).
- The
factory0.ventureswebsite and any front end that posts to the API. - The phase-3 native runtime and Postgres adapter (separate review when they land).
Report privately to security@factory0.ventures (or a GitHub security
advisory on Cratefield/harness). Please include reproduction steps
and affected commit; do not open a public issue for exploitable
findings. We aim to respond within 72 hours and will credit reporters
unless anonymity is requested.