Skip to content

[Security Gap] Move runtime HMAC secrets behind a KV credential registry #319

Open

Description

@seonghobae

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.md explicitly 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.yml still maps CLEARFOLIO_ARTIFACT_TOKEN_SECRET directly to clearfolio.artifact-token.secret and CLEARFOLIO_TENANT_CLAIMS_HMAC_SECRET directly to clearfolio.tenant-claims.hmac-secret;
  • ArtifactLinkService and TenantAccessService consume 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_registry
  • credential_reference
  • credential_snapshot
  • credential_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

Activity

  1. added
    area: authAuthentication, authorization, identity, or tenant isolation
    area: ci-cdCI, GitHub Actions, checks, release, or supply chain
    area: securitySecurity boundary, hardening, or vulnerability prevention
    status: triagedOpen issue has an organization taxonomy assignment
    type: featureNew or expanded product capability
    on Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionbugSomething isn't workingpriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions