Files
2026-05-27 23:29:53 +01:00

2.7 KiB

Capability Spec Delta: api-secrets-worker-proxy (api-secrets-worker-proxy)

Package: @suaveplan/api-secrets-worker-proxy Status: PROPOSED

Every requirement below carries a **Verified by:** line at authoring time.

ADDED Requirements

Requirement: Proxy preserves SecretsLike surface and forwards every call to main

The package SHALL expose createSecretsProxyClient(port) returning a WorkerProxyOf<SecretsLike>. Every method call SHALL be marshalled to the main process — there MUST be no worker-side cache of secret values, neither in module state nor in client-instance state. Two sequential get("X") calls MUST produce TWO main-side RPC invocations (so a rotated secret is picked up immediately AND a compromised worker cannot exfiltrate cached values).

Scenario: two gets produce two RPC calls

  • WHEN worker code calls ctx.secrets.get("X") twice in succession
  • THEN the stub main-side server records two distinct receive events

Verified by: src/client/no-cache.test.ts::"two gets produce two main-side RPC calls"


Requirement: Non-manifested key throws reconstructed SECRETS_PROXY_NOT_MANIFESTED

The package SHALL surface main-side rejection of non-manifested keys as SECRETS_PROXY_NOT_MANIFESTED reconstructed via api-worker-rpc's error-reconstruction. Manifested keys whose value is absent in the configured source MUST surface as SECRETS_PROXY_NOT_FOUND — the two cases are distinct so the operator can tell "your plugin didn't declare this" from "your plugin declared it but the source is missing it."

Scenario: non-manifested key is rejected

  • WHEN worker code calls ctx.secrets.get("NOT_DECLARED")
  • THEN the call rejects with SuaveplanError of code SECRETS_PROXY_NOT_MANIFESTED

Scenario: manifested-but-absent key surfaces SECRETS_PROXY_NOT_FOUND

  • WHEN the manifest declares STRIPE_KEY but the source has no value AND worker calls ctx.secrets.get("STRIPE_KEY")
  • THEN the call rejects with SECRETS_PROXY_NOT_FOUND

Verified by: src/client/client.test.ts::"non-manifested key rejects" AND src/client/not-found.test.ts::"manifested-but-absent key surfaces NOT_FOUND"


Requirement: Conformance suite passes against this proxy

The package SHALL be runnable as the surface argument to runSecretsConformance from @suaveplan/api-secrets/testing. Every scenario MUST pass identically to a direct in-process adapter. This is the Stage-4-precondition gate.

Scenario: runSecretsConformance passes

  • WHEN runSecretsConformance("worker-proxy", makeFactory) runs
  • THEN every scenario passes

Verified by: tests/conformance/run-secrets-conformance.test.ts::"runSecretsConformance passes against proxy"