You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The armed auto-action policy is now durable, so the terminal and a live orchestration loop share
one source of truth. synapse auto-action arm compact,log and disarm log add or remove
actions in a JSON policy file in the coordination home ($SYN_HOME or ~/synapse, overridable
with --store PATH), clear disarms everything, and show renders the persisted posture; the
bare command still previews the static model and touches no files. New participants.auto_action_store
(load_policy, save_policy) is the seam an orchestration harness loads to build its dispatch,
so what the operator arms is what the loop would fire. Persisting a policy still fires nothing —
an armed action fires only when its signal is raised at runtime and a handler was supplied.
Security
The cross-hub operator relay can now require two-person approval: a hub started with require_two_person_relay records an authorised relay pending instead of applying it, and
carries it out only when a second, different operator relays the same action, namespace, and
task. The same operator repeating the request cannot approve their own relay (it stays pending),
and both the pending request and the approval are audited, so a governed cross-hub force-release
under this policy names two distinct operators in the log. The RelayActionResult gains a pending field and synapse federation relay a new exit code 3 for a recorded-pending
verdict; both default off, so a single-operator hub and an older initiator read exactly as
before. The quorum lives in the new core.operator_relay_approval ledger (bounded, in-memory),
completing the operator-relay policy rituals begun with reason-required receipts and break-glass
tagging; break-glass does not bypass the quorum.
The cross-hub operator relay now carries a reason and a break_glass tag, recorded in the operator_relay audit on both the originating and the owning hub, so a governed force-release
across hubs leaves an auditable why and an emergency override stands apart from routine
governance in the log. synapse federation relay gains --reason and --break-glass, and a
hub started with require_relay_reason refuses a relay that carries no reason (reason-required
receipts) — deny-by-default, checked in authorise_relay after the peer and action gates. Both
wire fields default empty for backward compatibility. (Two-person approval of a relay is a
larger stateful workflow, tracked as a follow-up.)
The AES-GCM per-key message limit can now be enforced across restarts, not just within one
process. AtRestCipher takes an optional counter, and the new core.at_rest_counter
provides a crash-safe PersistentMessageCounter that persists the count to a sidecar file by
reserving a batch ahead of use — so a long-lived encrypted store resumes a key's cumulative
lifetime count after a restart or crash (over-counting by less than a batch and rekeying early,
never under-counting and risking a fresh nonce colliding with an old one). The default remains
the per-process InMemoryMessageCounter, byte-identical to before. AtRestCipher.from_key_file
and from_wrapped_key_file accept the counter so a store can opt in.
The WebAssembly sandbox now canonicalises a filesystem grant's host path before it
preopens it, and refuses the run fail-closed if the path resolves through a symlink or
is not an existing directory. A host path is resolved on disk at run time, so a symlink
swapped into a granted path between manifest authoring and execution could have
redirected a preopen to a directory the operator never granted; the sandbox now preopens
the resolved real directory and records it in the run receipt's new preopened_paths
field, so the run reaches exactly the directory the receipt shows and no moving target.
New core.sandbox_paths (resolve_preopen_host, harden_preopens).
SECURITY.md no longer describes at-rest encryption as unimplemented. The at-rest
encryption runtime (envelope encryption of SQLite stores, WAL/SHM sidecars, relay
logs, A2A state, archives, and backups; scrypt/PKCS#11/TPM2 key-encryption backends;
migration/rekey) has shipped, so the security posture doc now states it accurately,
with the transparent live-database (SQLCipher-class) boundary kept honest as the
remaining gap. Private channels are likewise no longer listed as future work.
Dashboard operator writes now require Content-Type: application/json, closing a
local cross-site-request-forgery hole. A cross-origin web page can POST a body to
the loopback dashboard without a CORS preflight only with a "simple" content type
(text/plain, form-encoded, multipart); the operator write path parsed JSON from any
content type, so a malicious page a local operator visited could drive /message, /task, and /task/update in synapse dashboard --operator without reading the
response. Requiring application/json forces a preflight the surface never answers
with cross-origin allow headers, so the browser blocks the write; a non-JSON operator
write is refused 415. The read-only dashboard and the same-origin cockpit (which
already sends application/json) are unaffected. The misleading docstring that claimed
loopback writes require the bearer token is corrected.