Client Credential Store: Threat Model & Build-vs-Integrate
Status: decision record for M19 (issue #240). This document decides the architecture the rest of the milestone implements; the M19-5 security review gate (#244) audits the built system against the mitigations promised here.
Context
Taking a Bloom project live needs client deployment credentials (a Cloudflare token, an npm
publish token, Supabase keys - the scheme's required_client_credentials, M18). The M18 interim
handoff was repository Actions secrets set by hand from a terminal. M19 replaces that with a
first-class flow: the client provides credentials once through the dashboard (#241), they are
stored encrypted with least-privilege access (#242), and project CI obtains them at deploy time
through a short-lived, scoped exchange (#243) - hands-free from then on.
Bloom's relevant topology: the FastAPI API on an exe.dev VM; Supabase Postgres for state; the dashboard SPA on Cloudflare Pages; project repos deploying via GitHub Actions; and the engine runner on a separate VM, which must never be in the secrets path.