Repository navigation
v1.0.0
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.jsondeclares 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-gov1.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_blockedhigh: 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 andpolicy-r0.yaml; on
R1 the stand's releasedscopyx:v0.1.2withwardryx: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 refusesdeny_policy_unreachableand records
web_blockedhigh while the gateway, by its own design, fails open (R0)
or closed (R1, the stand'sTOKENFUSE_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 CDPFetch.authRequired) and is not
built. - The
browsetool'swait_forandextractare frozen names; what the
chromium backend renders for them depends on the browser it drives, which
compat/1.0.jsonlists as experimental. - The
externalbackend'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