Repository navigation
stack-single 1.2.0
stack-single 1.2.0
This is a minor release, not a patch. The first re-run mints client keys, starts two keyryx services, moves wardryx approvals to keyryx, moves the containers onto new networks and new uids, and refuses some values that were accepted before.
Upgrade first
1. Re-run ./install.sh on every existing box, once, before the new images take traffic. The compose file now requires GATEWAY_CLIENT_KEYS, and services run under new uids: wardryx 20001, vouchryx 20002, typryx 20005, the gateway planes 20010 to 20013, keyryx 20100 and 20101. The gateway's policy-plane key is rewritten from viewer to pep. A box that is not re-run has no client key in .env, and docker compose up stops at the missing key. ./install.sh status says the same and names the fix.
2. Client keys are required, and agents must send one. The installer mints a key for Felyx (GENARYX_COPILOT_FUSE_KEY in .env) and one for the operator's agents ($STACK_DIR/agent-key, mode 0600, never printed). An agent must send x-fuse-key with an agent id under agents/, and every MCP broker tools/call needs x-fuse-agent-id. To bring your own keys, give CLIENT_KEYS_FILE and IDENTITY_MAP_FILE together: a map alone is refused, because its bindings would name keys the box does not have.
3. The MCP broker blocks raw secrets and flagged tool listings. A tool call that carries a raw cloud key is refused, and so is a tool listing that is flagged. The broker asks wardryx about every tool call and fails closed, so a tool the policy denies stays denied, and wardryx must be up. Agents that send raw secrets as tool arguments need to take them from the vault instead.
4. Approvals are signed through keyryx. wardryx signs approvals with keyryx by default (WARDRYX_APPROVAL_SIGNER=keyryx). An HMAC approval is refused from the switch unless WARDRYX_APPROVAL_V2_UNTIL is set to an instant at least ten minutes after the re-run. If holds granted under the old signer are still pending, set it in .env before the re-run. If none are pending, leave it unset.
5. keyryx starts on every box. keyryx (custody) and keyryx-witness run with no profile. The root keys are written once to $STACK_DIR/keyryx (mode 0400) and never replaced. An existing root key file that is empty is refused, and nothing is overwritten. Back up $STACK_DIR/keyryx, because the root key wraps custody's private keys.
6. Event streams change owner on the first re-run. Each stream is owned by the plane that writes it, mode 0640, group 10001, and no plane can create files in the bus directory. A reader outside group 10001 can no longer read a stream. To see them: docker run --rm -v agent-stack_events:/vol busybox ls -ln /vol.
7. The networks change. The default network is replaced by edge, front, core, agents and browser-policy. A container you run beside the stack that must reach an agent moves to agent-stack_agents. A hand-configured costcrew SSO needs edge added by hand. The old agent-stack_default network stays after the re-run as an orphan, and you can remove it once nothing is attached to it.
8. The gateway holds the provider key only if you give it one. ANTHROPIC_KEY_FILE=/path/to/key ./install.sh writes the key to ./upstream/anthropic (mode 0400, uid 10001). Without it, the gateway forwards the caller's own key, as before, and says so at startup. OPENAI_KEY_FILE does the same for the OpenAI door.
9. Mail is sent over TLS. heraldyx 0.8.0 uses STARTTLS by default, and a server on port 465 selects implicit TLS by itself. A server that does not offer STARTTLS is refused, and plain is allowed only for a loopback host. Set SMTP_TLS in .env before you start if your server needs a different mode. The installer asks for the mode after the server address, and refuses a value it does not read before anything is installed.
10. The demo issuer's line gets |unbound. vouchryx 0.5.0 and later refuse a subject token with no cnf.jkt unless its issuer line ends in |unbound, and the demo IdP sends unbound tokens. A rerun with WITH_DELEGATION_DEMO_ISSUER=1 rewrites the demo line in .env and changes no other line. An operator's own VOUCHRYX_TRUSTED_ISSUERS line is never touched. Add |unbound to your own line only if your identity provider issues unbound tokens on purpose.
11. Agent tokens stay off unless you turn them on (WITH_AGENT_TOKENS=1). When they are on, the audience is one https identifier, https://stack-single.<trust domain>, shared by the gateway and the broker. An agent asks for it in its token request with resource= (RFC 8707; audience= also works). A request that names no audience is refused audience_not_allowed, because vouchryx would otherwise fall back to its own issuer, which the allow-list does not name. The agent's DPoP proof to the gateway or the broker carries ath, the hash of the token (RFC 9449). A token minted for the old http:// audience stops verifying, so the enrolled agent must exchange its secret again. Do the rerun in one restart window. A box that gave its own keys file must add a broker:<secret> line first.
12. Install needs outbound HTTPS, and every image is checked before it starts. The installer downloads cosign v3.1.3 from GitHub, checks it against a pinned SHA-256, and runs cosign verify on each TAIPANBOX image before pulling it. It needs outbound HTTPS to github.com, release-assets.githubusercontent.com, tuf-repo-cdn.sigstore.dev and ghcr.io. An image without a signature from a TAIPANBOX release workflow is refused, and nothing is started. A box that cannot reach those hosts cannot install or re-run. BUILD_FROM_SOURCE=1 builds locally and is not signed or checked, as before.
13. A downgraded typed box needs one run. A box that ran WITH_TYPED=1 with a .env that says TYPED_MODE='off', or that lost the stub on an earlier re-run, needs one WITH_TYPED=1 ./install.sh to record the stub. TYPED_MODE=off turns the stub off, and it stays off. An unknown TYPED_MODE value is refused.
14. Some trust domains are refused. RECORD_TRUST_DOMAIN may use letters, digits, dots and hyphens. Underscores are refused, and so is mockryx.local, because the fire drills' key is bound to it.
15. A compose.override.yaml you wrote is refused when TYPED_MODE is jev or own-model, because typryx then needs a route out and the installer does not overwrite a file it did not write. Move the file aside, or set TYPED_MODE=stub.
16. The pins moved. tokenfuse v1.18.0 (with the taint-gateway key file the installer writes when agent tokens are on), tokenfuse-control-plane v1.18.0, vouchryx v0.6.0, wardryx v2.2.1, idryx v1.2.2, keyryx v0.1.1, agent-conform v2.0.1, heraldyx v0.8.0, scopyx v1.1.0 (and chromium), typryx v0.5.0, costcrew v0.9.0, genaryx-console, stack-caddy and stack-wg v1.1.48, trailryx-node v1.3.1. Each is pinned by digest in compose.yaml and components.json. costcrew 0.8.0 names analysts agent://<host>/costcrew/<name>. This launcher binds no analyst id, so nothing needs rebinding here.
What is new, by PR
- #131, typed stub.
WITH_TYPED=1records the stub asTYPED_MODE='stub', so a plain re-run keeps the typed plane.TYPED_MODE=offturns it off and keeps it off. See item 13. - #132, client keys and the broker. Keys are minted when none are given, the gateways run identity strict enforce, and the broker blocks raw secrets and flagged tool listings. Tool pinning stays off, because it needs an approved lock file. See items 2 and 3.
- #133, pins and the pep key. tokenfuse v1.15.0, wardryx 2.0.0, vouchryx v0.3.0 and costcrew v0.7.0. The gateway's policy-plane key becomes
pep, which a re-run writes. A box that is not re-run keepsviewer, and wardryx 2.0.0 then refuses it with 403, so the gateway and the broker fail closed. - #134, networks. Agent-facing containers sit on internal networks.
edgeis the only route out, and the browser is offcore. See items 7 and 15. - #135, provider key. The gateway reads the provider key from a 0400 file that the installer writes, so no agent-facing service holds it. The fire drills' key is minted and bound to
agent://mockryx.local/*. See item 8 and item 14. - #136, agent tokens. With
WITH_AGENT_TOKENS=1, vouchryx runs, the installer mints one enrolment key per agent, and the gateway and the broker accept an agent token beside the static keys. Static keys keep working. See item 11. - #138, keyryx. The installer installs keyryx v0.1.0 (custody and a separate witness), writes the root keys as files, re-owns every stream to its producer at 0640, and wires wardryx approvals through keyryx. See items 4, 5 and 6.
- #139, digest pins and signatures. Every image is pinned by digest, and every TAIPANBOX image is checked against its keyless signature before it is pulled. See item 12.
- #140, the wave's pins. The images of the 2026-10-17 agent-security wave, the nine conflicts closed, and the demo issuer and mail TLS items above. The agent-tokens gate now checks one https audience for both doors, and the demo-issuer migration has its own gate.
#137 (an actions bump) is open and is not in this release.
Not proven
install.shhas not been run on a box that was installed before this release and then re-run. CI's install legs install fresh on Ubuntu. The re-owned streams, the pep rewrite, the approval switch and the network move have not been measured on an old box.- The approval switch and
WARDRYX_APPROVAL_V2_UNTIL: the rule is written from the wardryx 2.0.0 and 2.2.0 notes. No pending HMAC hold was measured across the switch. - The agent-token door was measured on a compose stack, not on an installed box (see
docs/evidence/agent-token-audience/RUN.md). The gateway's and the broker's live admission of a real agent framework was not measured. - Mail through each TLS mode against a live server. The mode values come from heraldyx's tests and this repository's gates.
- The network move under real agent traffic. CI runs a probe that an agent-network container reaches the gateway and not the internet.
- A box with no route to GitHub, sigstore or ghcr.io. The refusal is checked by the verify gate's harness, not by a live outage.
- The keyryx custody and witness running for days. CI starts them; their behaviour under load is not measured.