Repository navigation
[Security Gap] Move runtime HMAC secrets behind a KV credential registry #319
Description
Buyer/operator outcome
Make Clearfolio production authentication and artifact-signing secrets restart-safe, rotatable, least-privilege, and consistent with CWL credential governance without making raw environment variables the runtime source of cryptographic authority.
Fresh protected-main evidence
At protected main 83ec6f7fe2b04bdcd28bf98ec350e41e55730a18:
AGENTS.mdexplicitly requires runtime config/secrets to be read from a KV / credential registry, with environment variables used only as bootstrap transport;- the same guide marks Clearfolio's current artifact-token and tenant-claims HMAC secret injection as a known deviation to migrate;
src/main/resources/application-buyer-demo.ymlstill mapsCLEARFOLIO_ARTIFACT_TOKEN_SECRETdirectly toclearfolio.artifact-token.secretandCLEARFOLIO_TENANT_CLAIMS_HMAC_SECRETdirectly toclearfolio.tenant-claims.hmac-secret;ArtifactLinkServiceandTenantAccessServiceconsume those configured secret values at runtime.
Draft #313 hardens production key presence, stable artifact signing, minimum effective key size, normalization ambiguity, and purpose separation. It does not replace the secret transport/source-of-truth architecture and must not be duplicated here.
Required architecture
Introduce a provider-neutral versioned credential lookup boundary, for example:
credential_registrycredential_referencecredential_snapshotcredential_rotation_event
The implementation may use a DB-backed encrypted KV or another reviewed secret-management adapter, but Clearfolio business/auth code must depend on a narrow registry interface rather than environment-variable names or a single vendor SDK.
Environment variables, GitHub Actions secrets, Kubernetes Secret projection, Vault bootstrap tokens or equivalent may bootstrap the registry/secret-manager connection, but raw tenant/artifact HMAC values are not the long-lived runtime authority in application config.
No cross-service application-database writes are introduced. Standalone deployment must remain possible through a supported local credential-store adapter with the same lookup/rotation semantics.
Security invariants
- tenant-claim signing and artifact-token signing remain separate credential purposes;
- registry lookups fail closed for missing, malformed, stale, unauthorized or ambiguous values;
- secret values never enter logs, metrics, PR bodies, model prompts, public exceptions, browser code, SBOMs or provenance payloads;
- access is purpose-scoped and least-privilege;
- rotation supports an explicit compatibility window only where the signed-token protocol requires it; do not silently accept arbitrary historical keys;
- restart/replica behavior is deterministic and does not generate ephemeral production authority;
- bootstrap transport is distinguishable from runtime secret source in code and documentation;
- audit evidence records credential identifier/version/purpose and controlled outcome, never raw bytes.
Test-first acceptance
Before implementation add RED tests proving the current direct-env/config dependency. Then require at least:
- production startup reads tenant/artifact HMAC material through the credential-registry interface;
- direct application-level env fallback is rejected in production after migration;
- missing/unavailable registry fails closed;
- exact key-purpose separation and fix(security): enforce production HMAC signing key readiness #313 effective-key/readiness rules remain enforced;
- rotation tests for active/previous version behavior according to explicit token-compatibility policy;
- concurrent lookup/rotation race tests;
- restart/replica parity tests;
- least-privilege adapter authorization failure tests;
- no raw-secret logging/error/telemetry tests;
- standalone local-registry and composed/MSA adapter contract tests;
- exact 100% owned production statement/branch coverage for new code and complete public Javadocs;
- exact-head CI, Security Scan, SAST, applicable fuzz/property tests, SBOM/provenance, independent review, migration/rollback/recovery acceptance.
Documentation / data model
Update canonical PRD/TRD/Architecture, ADRs, UML, DATA_MODEL, API/config contracts, Security, Threat Model, Test Strategy, Operability, Migration/Rollback, Traceability, Acquisition Diligence, AGENTS/CLAUDE/README/CHANGELOG with truthful maturity.
If persistence is introduced, use descriptive two-or-more-word snake_case objects such as credential_record, credential_version, credential_purpose, credential_rotation_event, and explicitly document encryption/KMS ownership. Do not invent a database solely to satisfy the model.
Dependency order / non-duplication
- Do not race fix(security): enforce production HMAC signing key readiness #313 while it owns
ProductionAuthReadinessConfigand related signing-readiness tests. - Do not duplicate fix(security): harden audit pseudonymization and refresh Netty evidence #270/fix(security): require signed tenant claims on admin endpoints #268 tenant/object authorization or audit-pseudonymization logic.
- Re-evaluate the stable protected baseline after fix(security): harden audit pseudonymization and refresh Netty evidence #270/fix(security): enforce production HMAC signing key readiness #313 integration, then implement the smallest registry abstraction/migration slice.
- This issue is credential-source architecture, not OIDC/JWT federation ([Product Gap] Add production OIDC/JWT identity federation with tenant-scoped authorization #314).
Activity