Skip to content

Per-component process.env from granted secrets, with load-gating on declared secrets #1550

Description

@kriszyp

Consumption side of the secrets store (#715); phase 1b of the secrets-management plan.

  • Each component gets a synthetic process.env object materialized at load: real env plus the secrets granted to that component (decrypted via the registered secret decryptor from feat(env): dormant decrypt hook + enc:v1 contract for env-secret encryption #1528). Env-shaped on purpose — the npm ecosystem configures itself from process.env.FOO, so no glue code. Eager decrypt of the granted set (enumeration via Object.keys/spread must work for dotenv-style consumers).
  • Components declare expected secrets in config (parseable without loading component code):
    secrets:
      STRIPE_SECRET_KEY: { required: true, description: Stripe API key }
      SENTRY_DSN: { required: false }
  • Load gate: a required declaration that is unsatisfied (undefined or ungranted) stops THAT component from loading with a clear error naming the missing vars — the instance keeps running. Component status exposes the unsatisfied set (names/descriptions) so Studio can render a configure-me flow and deploy responses can print it.
  • Declarations are requests, not authority — grants (Secrets store: hdb_secret system table, grants, and operations API #715) stay authoritative.
  • Document loudly: child processes inherit the REAL env, not the synthetic object; secrets need explicit propagation to spawns.
  • JS-level scoping is a slowdown layer against generic env scrapers, not a hardened boundary — containers/uids remain the tenant boundary. No SES requirement.

🤖 Drafted by Claude (Fable 5) on Kris's behalf.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions