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

2.1 KiB

@suaveplan/api-secrets-worker-proxy — worker-side proxy to main-process secrets adapter

Package: @suaveplan/api-secrets-worker-proxy Status: PROPOSED Type: new-package Stage: 3 (Worker isolation infrastructure)

Why

Per design doc §5.2a, every capability ships a proxy surface. Secrets are unusually sensitive: a worker reading a value it didn't manifest is a security incident. So the main-side adapter does the allow-check before the value crosses the wire (design doc §5.2b sandboxed gating), and this proxy is the worker-side transport. The proxy MUST NEVER cache a secret value in the worker heap beyond the immediate caller's scope — that's the proxy's job to enforce by not exposing any internal storage.

What changes

Net-new package.

ADDED exports:

  • ./client — createSecretsProxyClient(port): WorkerProxyOf<SecretsLike>. Worker-side ctx.secrets.get(name) → main-side allow-check + read → marshalled value.
  • ./error-codes — SECRETS_PROXY_* codes (SECRETS_PROXY_NOT_MANIFESTED, SECRETS_PROXY_NOT_FOUND, SECRETS_PROXY_PORT_CLOSED).
  • ./testing — paired MessageChannel + stub main-side server.

Out of scope

  • Manifest allowlist enforcement — main-side per §5.2b.
  • Concrete secrets source — api-secrets-env / api-secrets-bun / api-secrets-vault are Stages 4 / 8.
  • Secret rotation hooks — not in foundation scope.

Source mapping

Genesis-original. Design doc sections: §5.2a, §5.2b.

Requirement Design doc section
Proxy over abstract SecretsLike §5.2
Non-manifested key rejected main-side §5.2b
No worker-side caching of values §5.2a (cloneable boundary)

Verification approach

  • src/client/client.test.ts — manifested key returns value; non-manifested throws SECRETS_PROXY_NOT_MANIFESTED.
  • src/client/no-cache.test.ts — calling get(name) twice issues two main-side calls (no worker-side caching).
  • tests/conformance/run-secrets-conformance.test.ts — runSecretsConformance from @suaveplan/api-secrets/testing passes. Required before Stage 4 can complete.

Migration impact

None — additive only.