Skip to main content

ZSC — the Zeq Secure Context

ZSC is a core feature: the framework's entire secret surface. There are no .env files anywhere in Zeq. Every secret — session keys, Stripe keys, the node's Ed25519 identity, database URLs for sub-systems — lives encrypted at rest in the zsc_secrets table and is decrypted into process.env only in memory, only at boot.

The cipher

Each secret row stores value_enc + value_iv, sealed with:

  • AES-256-GCM, 12-byte IV, 16-byte auth tag appended to the ciphertext, hex-encoded.
  • Key = PBKDF2-SHA256(node field-key bytes, HULYAS salt, 200,000 iterations, 32-byte output).
  • HULYAS salt = HULYAS.ZeqField.f=1.287Hz.τ=0.777s.α=1.29e-3 — the kernel constants, bound into the key derivation itself.

The algorithm is defined once in shared/api-core/src/lib/zeqField.ts and mirrored byte-for-byte by the launcher and the bootstrap tool, so a value sealed by any of them opens with any of the others.

The bootstrap problem, and the vault-adjacent answer

The vault is opened by exactly two bootstrap pointers that, by definition, cannot live inside the thing they unlock:

  • ZEQ_FIELD_KEY — 64 hex; the root the row key is derived from.
  • DATABASE_URL — where the vault rows are read from.

At boot, zeq-dev-launch.mjs takes those two, connects to Postgres, decrypts every zsc_secrets row, populates process.env, and spawns the server. A shell-set value always wins over a vault row — the operator's incident-response override path.

Because those two pointers can't be in the vault, they live vault-adjacent: a sealed store (infra/zsc-bootstrap.mjsinfra/per-domain/.zsc-bootstrap), ciphertext-only on the host, encrypted with the same zeqField cipher under one master pointer, ZEQ_BOOTSTRAP_KEY. The master pointer is itself a zsc_secrets row — so the vault protects the keys to its own front door — and is held by the operator. One pointer opens the store; the store yields each domain's two pointers in memory; those open each domain's vault. No secret is ever written to disk in plaintext, and nothing sensitive is printed.

Recreating a node

export ZEQ_BOOTSTRAP_KEY=<the master pointer, from your ZSC vault>
node infra/zsc-bootstrap.mjs up <domain> --force-recreate # decrypt in-memory → compose up
node infra/zsc-bootstrap.mjs seal # after rotating a key: reseal from the running fleet

Why it matters

Secrets bound to the kernel constants, decrypted only in memory, with the bootstrap keys themselves sealed under a single vault-held master — that is what lets a Zeq node boot from cold with no plaintext secret ever touching the filesystem. ZSC is the security spine the rest of the framework stands on.