Skip to content

v0.2.0a21

Pre-release
Pre-release

Choose a tag to compare

@yfxiao16 yfxiao16 released this 26 Oct 01:32
99ebb16

Upgrade with pip install --pre -U "sponsio==0.2.0a21", then re-run sponsio host install <host> and sponsio doctor --tier.

This release lets Sponsio run out of the agent's reach. Tier 2 (sudo sponsio install --system) runs the daemon as its own user behind root-owned hooks. Tier 3 (sponsio run --sandbox) starts the agent in a sandbox whose only route out is an egress proxy Sponsio decides. Both are opt-in: a default install stays at Tier 1. A fleet of daemons can also pair with Sponsio Cloud, for signed rulebooks, rule changes decided by a person in the console, and an audit chain the cloud checks. @sponsio/sdk (TypeScript) is unchanged at 0.2.0-alpha.10.

Added

  • Tier 2: sudo sponsio install --system (macOS and Linux). A
    _sponsio service user runs the daemon under launchd or systemd; the
    engine and hook shims are root-owned; the rules, history, audit log
    and config live in a directory only _sponsio can open; Claude Code
    gets its hooks from managed settings (managed-settings.d), with
    allowManagedHooksOnly on unless --allow-user-hooks. Libraries under
    ~/.sponsio/plugins are imported once. sponsio uninstall --system
    removes it. The install stops if a shared directory above Sponsio's
    own (/opt, /usr/local, ...) is writable by a user other than root.
    See running Sponsio on a host.

  • Tier 3: complete mediation. The MCP gateway runs the upstream MCP
    servers with their credentials and gives the host one MCP server whose
    tool list follows the session's contract state. sponsio run --sandbox starts an agent in a sandbox (bubblewrap on Linux, Seatbelt
    on macOS, or a container recipe under deploy/tier3) whose only route
    out is an egress proxy that decides every connection against
    egress.allow and the _egress library.

  • SDK backend="daemon". A guard can hand its decisions to the
    daemon, and every adapter offers the model the tools the session's
    state allows on each turn.

  • Hash-chained audit log. Every record carries seq, prev_hash
    and hash; sponsio admin audit verify checks the chain against the
    daemon's head, and records can be exported over OTLP. The integrity of
    the log while the daemon is stopped depends on that remote copy.

  • Signed rules. With signing: in daemon.yaml, a covered bucket
    serves only rule files with a valid Ed25519 signature by the pinned
    key; anything unverified (an unsigned edit, a removal, a file that
    does not load) leaves the last signed rules enforcing, or holds the
    bucket. Needs the signing extra.

  • Project layer. A repository's .sponsio/host.yaml adds contracts
    for hook calls made in it, and can never weaken a protected one;
    attempts are recorded as tamper_attempt.

  • Standing approvals reach the runtime. "Always allow" in the console
    was recorded server-side only, so the SDK refused the same call on every
    run and re-asked a question a person had answered. A guard built from a
    sponsio:// rulebook now loads the project's standing approvals once at
    construction, and EscalateToHuman releases a covered call (exact match
    on agent, tool and contract) as observed, naming the approval, without
    paging anyone. Any fetch failure loads nothing and every escalation waits
    on a human as before. A standing approval can only release an
    escalation, never a DetBlock rule. SPONSIO_STANDING=0 opts out.
    This matters since 0.2.0a17, when EscalateToHuman started refusing the
    call: before that there was nothing to release.

  • Proposal review on the admin socket (sponsio admin proposals),
    and the daemon's own cloud key (sponsio admin cloud-key).

  • A fleet of daemons paired with Sponsio Cloud. sponsio pull -o FILE writes the signature the cloud made over a published book to
    FILE.sig, and --public-key refuses to write anything that key did
    not sign; sponsio signing-key prints the signing: block to pin.
    With cloud.proposals: true a daemon uploads its proposals and applies
    what a person decides in the console, only when its own copy matches
    what that person saw. Exported audit records carry a stream id kept in
    the state dir, so the cloud checks each daemon's chain on its own and
    catches a log cut while the daemon was stopped. See the
    daemon reference.

Changed

  • A check costs the same on a long session. Contracts are evaluated
    incrementally: at 5,000 events a check takes about as long as at 500.
  • sponsio doctor --tier reports Tier 2 only when every guarantee
    holds on the machine as Claude Code will load it: managed settings and
    every directory above the shim and engine root-owned and not writable
    by your user, no disableAllHooks, and a sandbox that covers this
    platform.
  • A call denied because its library would not load no longer tells the
    agent how to let it through.
    The reason used to end "set
    SPONSIO_HOOK_ON_ERROR=allow to fail open": the agent reads that reason,
    and under the daemon that variable has no effect anyway (the switch is
    on_error in daemon.yaml). It now says the call is denied until the
    contract library is fixed.
  • A bucket whose rules must be signed refuses changes made on the
    machine.
    sponsio plugin append, a proposal, or approving one from
    before signing was turned on now fails with signed: an appended file
    is no longer signed, so the daemon kept the last signed rules and the
    change was never enforced, while the proposal read approved. Change a
    signed bucket by publishing its book and pulling it.
  • sponsio rules status reads the files as they are now, not as the
    last hook call saw them, and shows a signed bucket whose file on disk
    is not what is enforced.

Fixed

  • Fixes from a second review of the Tier 2 and Tier 3 work: the audit
    log, rule signing, the MCP gateway, the system install and doctor
    (27 issues, each with a regression test).
  • sponsio pull -o creates the bucket's directory on a first pull.