Skip to content

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 20:29
· 33 commits to main since this release
51a8c39

Scopyx 1.0.0

The web-egress enforcement point of the TAIPANBOX stack: an agent's browsing
goes through it, every destination and every redirect hop is decided against
Wardryx before a backend fetches it, and what happened is written to the
shared agent-event bus. It decides; it does not fetch anything the operator's
own backend could not.

What 1.0 promises

compat/1.0.json, rendered as COMPATIBILITY.md and held by
scripts/compat-surface.sh on every push: the three MCP methods, the
browse tool with its three arguments and three extract values, the
X-Scopyx-Key header, the seventeen SCOPYX_* names with the backend and
robots values they accept, and the two event types this plane emits
(web_fetch, web_blocked). A frozen name is not removed or renamed within
this major; a new tool, a new optional argument, a new event type under this
source, or a new SCOPYX_* name with a default that keeps today's behaviour
is additive. The two image variants (scopyx:<tag> and
scopyx:<tag>-chromium) stay. Support line: the newest minor gets every fix;
the previous minor gets security-relevant fixes for 90 days after the newer
one is tagged.

Since 0.1.2

  • The SSRF address gate refuses the ranges the first sweep missed: IETF
    protocol-assignment space, benchmarking space, 240.0.0.0/4, limited
    broadcast, deprecated IPv6 site-local, and both families' unspecified
    address; every one was confirmed reachable under the unfixed code first
    (#31).
  • components.json declares the open-bind refusal matrix, all seventeen
    environment names, and the two images; a test starts the real binary four
    ways to prove the matrix, and refuses a name read by the code that the
    manifest does not declare, in both directions (#24).
  • agent-stack-go v1.0.0, the contract at 1.0 (#35); Go 1.27 (#26).
  • Every release is signed and attested by digest, both images, with SBOMs
    and a provenance bundle on the release page (#36); workflows run read-only
    except where they publish (#38), actions are pinned to commits (#32), and
    an OpenSSF Scorecard is published (#34); SECURITY.md written.
  • Nothing on the wire moved: the same two event types under schema v0.2, the
    same tool schema, the same door.

Proven, by the 1.0 proving run (estate-gates PROVEN.md, section "The 1.0 proving run")

  • POL-3, R0 and R1. The five gates in order, each refusal on the bus as
    web_blocked high: the address rule (deny_address), an allowed origin
    fetched, a denied origin (deny_policy), an allowed origin redirecting into
    a denied one refused on the target host, robots (deny_robots, github.com
    /search$), and the policy plane killed (deny_policy_unreachable). On R0
    a stack-up build of that day's main with Wardryx and policy-r0.yaml; on
    R1 the stand's released scopyx:v0.1.2 with wardryx:v0.1.0, the same
    five answers.
  • INT-3, R0. An MCP client on browse: the allowed destination fetched,
    the denied one refused.
  • FAIL-2, R0 and R1. Wardryx killed under a running gateway and this
    plane: this plane refuses deny_policy_unreachable and records
    web_blocked high while the gateway, by its own design, fails open (R0)
    or closed (R1, the stand's TOKENFUSE_WARDRYX_FAILMODE: closed); both
    recover when the policy plane is back.

Upgrade note, 0.1.x to 1.0.0

Nothing to migrate: this plane keeps no state beyond the optional NDJSON
journal, which 1.0.0 appends to in the same envelope (prev_hash chain
continues), and the hourly cap, which resets on every restart as before.
Every SCOPYX_* name and default is unchanged. An address that 0.1.2
fetched and 1.0.0 refuses is in one of the ranges #31 added; that is the fix,
not a regression. The image tags are v1.0.0 and v1.0.0-chromium.

Not in this release, said plainly

  • During a chromium fetch the loopback proxy this process owns is usable by
    any process on the same machine that guesses its ephemeral port; such a
    request is decided against the same policy as the fetch, not refused
    outright. The fix shape is written beside the code (Proxy-Authorization
    with a per-fetch secret, answered over CDP Fetch.authRequired) and is not
    built.
  • The browse tool's wait_for and extract are frozen names; what the
    chromium backend renders for them depends on the browser it drives, which
    compat/1.0.json lists as experimental.
  • The external backend's request shape is experimental and always
    navigation_only: subresources of a page fetched by the operator's own
    service are not decided here.
  • No health path, on purpose: nothing in the estate polls this plane.

Full changelog: v0.1.2...v1.0.0