Skip to content

v0.98.2

Choose a tag to compare

@github-actions github-actions released this 05 Jul 22:07
· 1031 commits to main since this release

Added

  • Cross-hub operator relay — synapse federation relay release relays a governed
    operator action to a peer hub over the existing federation transport, the first
    being a force-release of a stuck lease the peer holds. The peer authorises the
    relay deny-by-default (mutual TLS + the peering's bounded scope granting the
    action's verb in the namespace + the peer must own the namespace) and refuses an
    unverified peer or an unregistered action fail-closed. An applied release is
    journalled twice on the acting hub: a standard release for state reconstruction
    and a new audit-only operator_relay event carrying the cross-hub provenance a
    release never records — the verified peer, the asserting operator and origin hub,
    and the previous holder — and the hub's own agents are told the lease was revoked.
    New core.operator_relay (deny-by-default policy + relayable-action registry),
    core.operator_relay_wire, core.operator_relay_transport, and a serving handler,
    plus SynapseState.force_release. Relayable actions are an explicit allowlist, so a
    new cross-hub capability is a deliberate registry entry, never an accident of the wire.
  • Origin-side routing for the cross-hub operator relay — an operator can target their
    own hub, and a hub configured with a relay-peer route to the namespace's owner
    forwards the relay on their behalf and relays the verdict back, so the operator never
    needs the owning hub's credentials (the origin-side counterpart of claim forwarding).
    The relay is now audited on both hubs: the origin hub records an outbound
    operator_relay event (a new direction field distinguishes it from the owning hub's
    inbound one) naming the requester and the destination owner, and stamps its own id as
    the forwarded request's origin so the owner attributes the relay to the hub that
    relayed it, never a value the requester asserted. Routing is deny-by-default: a relay
    for a namespace the hub neither owns nor has a route to is refused fail-closed. New
    core.operator_relay_routing (pure route resolution) and core.operator_relay_forwarding
    (the origin-side gate), plus SynapseHub(relay_peers=…, relay_forwarder=…), a route map
    kept separate from the claim-forwarding peers because relaying a force-release is more
    privileged than forwarding a claim.
  • TPM 2.0 hardware key-encryption-key backend for at-rest wrapped keys (optional
    synapse-channel[tpm2] extra). A decrypt-only RSA-2048 key-encryption key is derived
    from the device's storage seed and a fixed template — the identical key every process,
    so no handle is persisted — and wraps and unwraps the data key with RSA-OAEP; the RSA
    private key is generated inside the TPM and never leaves it.
    synapse encrypt-key generate-wrapped-tpm2 writes such a file (--tcti / TPM2_TCTI,
    defaulting to the in-kernel resource manager device:/dev/tpmrm0), recording only the
    template version — never a device path. New core.at_rest_tpm2
    (Tpm2KeyEncryptionKey, generate_wrapped_key_file_tpm2,
    cipher_from_wrapped_key_file_tpm2) implementing the KeyEncryptionKey protocol over
    the same wrapped-key file format. CI installs swtpm so the backend is exercised, not
    skipped. This completes the pluggable hardware backend family (passphrase, PKCS#11, TPM).
  • PKCS#11 hardware key-encryption-key backend for at-rest wrapped keys (optional
    synapse-channel[pkcs11] extra). A key-encryption key held on a PKCS#11 token — a
    YubiKey PIV, a cloud or network HSM, or SoftHSM for tests — wraps and unwraps the
    data key on the device via RFC 3394 AES key wrap (C_WrapKey / C_UnwrapKey), so
    the token key never leaves the hardware. synapse encrypt-key generate-wrapped-pkcs11
    writes such a file (--pkcs11-module / PKCS11_MODULE, --token-label,
    --key-label, --no-create-kek; PIN from PKCS11_PIN or a prompt), recording only
    the token and key labels — never the PIN or module path. New core.at_rest_pkcs11
    (Pkcs11KeyEncryptionKey, generate_wrapped_key_file_pkcs11,
    cipher_from_wrapped_key_file_pkcs11) implementing the KeyEncryptionKey protocol
    over the same wrapped-key file format. CI installs SoftHSM2 so the backend is
    exercised, not skipped.
  • Envelope-encrypted (KEK-wrapped) at-rest key files with a pluggable
    key-encryption-key backend, the foundation for hardware-backed keys (PKCS#11 /
    TPM / YubiKey / cloud HSM). A random data key does the bulk AES-GCM while a
    key-encryption key wraps it with RFC 3394 AES-KW; the wrapped-key file records
    which backend produced it (passphrase-scrypt today, hardware backends as
    optional extras next) so a fresh process rebuilds the matching key. synapse encrypt-key generate-wrapped writes one and synapse encrypt-key rewrap rotates
    its passphrase without re-encrypting any data, because only the
    key-encryption key changes and the data key underneath is unchanged. New
    KeyEncryptionKey protocol and PassphraseKeyEncryptionKey, wrap_data_key /
    unwrap_data_key / generate_wrapped_key_file / rewrap_wrapped_key_file, and
    AtRestCipher.from_wrapped_key_file in core.at_rest. The optional PKCS#11 / TPM
    / YubiKey key-encryption-key backends implement the same protocol and plug into
    this same wrapped-key format.
  • synapse auto-action gives the opt-in auto-action reactor a discoverable CLI
    surface. The reactor (which turns the session advisor's per-round signals into
    automatic compact/log/handover actions) was previously reachable only in-process
    through react_to_advice, so an operator could not see what it does. The command
    prints the signal-to-action map, the signals that deliberately map to no action,
    and — with --arm/--all — a preview of a policy's armed posture. It reads the
    static model only (starts nothing, fires nothing), and states honestly that
    arming happens in the orchestration loop, not through a hub-side toggle. New
    read-only describe_auto_actions/auto_action_report_to_json/
    render_auto_action_report in participants.auto_action.
  • synapse encrypt-key generate --from-passphrase derives the at-rest key from a
    passphrase (prompted twice) via scrypt instead of random bytes, with the scrypt
    cost tunable through --scrypt-n (a power of two), --scrypt-r, and --scrypt-p
    for a security/performance trade-off. A fresh random salt is drawn per derivation
    and discarded — the written file is a normal owner-only 32-byte key of record,
    protected exactly like a random one, and the passphrase alone cannot reconstruct
    it. The default remains a random key; the passphrase path (and its scrypt
    parameters, previously reachable only through the AtRestCipher.from_passphrase
    library API) is now exposed on the CLI. New generate_key_file_from_passphrase.

Security

  • AtRestCipher now enforces the AES-GCM per-key safety bound for random 96-bit
    nonces. It counts the messages it seals (exposed as encrypted_count), logs a
    one-time rekey warning once it passes fifteen-sixteenths of the GCM_MESSAGE_LIMIT
    (2**32), and raises the new AtRestKeyExhausted rather than encrypt past it —
    so a key is rotated before the nonce-collision probability can rise past the
    2**-32 bound. The count is per cipher instance and resets when the cipher is
    rebuilt, guarding a single long-running process rather than a key's cumulative
    lifetime across restarts.