Repository navigation
Releases: sprayberry-archive/fieldpass
Release list
v0.6.1
Fixed
PICKET_CDP/--browseraccept a browserless-style token on the URL
(http://host:port/?token=…), which is how askalf/browser-bridge's
BRIDGE_TOKENis presented. Before, the base was string-concatenated with
/json/version, so a token turned into…/?token=X/json/versionand the
connect failed with "Invalid URL". The resolver (bridgeEndpoint, now
exported fromcapture.mjsand shared by the MCP server and the CLI) parses
the base, carries the token on/json/versionand on the returned
WebSocket endpoint, rewrites the ws host back to the base (tunnelled bridges
advertise their internal address), and turns a 401 into a message that
names the token. Five unit tests (test/bridge-endpoint.test.mjs).
Security
- Scorecard alert #26 named three chromadb advisories the ignore file never
covered.examples/crewai-picket/osv-scanner.tomllistedPYSEC-2026-311,
which aliases to CVE-2026-45829 — a different chromadb advisory from the
three OSSF Scorecard actually reports (CVE-2026-45830 / -45833 / -45831,
GHSA-2wm9-hf6c-p5cr / GHSA-36p7-vc44-83pf / GHSA-xph7-9rjv-w5fr). The existing
entry does work — 45829 dropped out of Scorecard's list once it landed, which is
what proves Scorecard honours this file — it simply never named these IDs, so
the check stayed at "3 existing vulnerabilities detected". Added all three under
the same reachability analysis and revisit date. No patched chromadb exists
(OSVlast_affected1.5.9; 1.5.9 is the newest release on PyPI), and chromadb
is not declared here at all — it arrives transitively throughcrewai==1.15.7's
chromadb~=1.1.0. Examples only; nothing fieldpass ships has a Python
dependency.
v0.6.0
Ships the 0.5.1→0.6.0 window (31 commits). Full detail in CHANGELOG.md.
Highlights:
fieldpass scan <url>works with no CDP browser configured (#77). Every URL
used to route through the CDP path, sonpx -y @askalf/fieldpass scan https://…
threw a puppeteer assert stack unless a browser was already running. A URL
without a browser is now fetched and parsed statically, labelled
captured: static, withcapturedByin--jsonand exit 65 on fetch failure.- Two false-positive classes fixed (#78): invisible-only nodes, and the unanchored
agent:/model:role label that quarantined RFC 9110. Hostile fixtures
unchanged. - ClusterFuzzLite over the injection trust boundary (#64).
node-html-parserto ^9, andqsoverridden to ^6.16.0 — a runtime path via
@modelcontextprotocol/sdk → express → qs, closing GHSA-4mjr-xmp4-gh2g and
GHSA-x5fp-wj9c-mxmx.
v0.5.1
Fixed
- observe({page}) now routes through the live-capture path (#56). A caller-owned page (a ContextBroker checkout, an agent's active browser session) passed alone used to miss the bridge check and fall through to the static parser with no HTML — it now reads the live session via the CDP extractor: computed-style hidden detection, shadow-root descent, no navigation, lifecycle untouched. This is the seam askalf's fleet browser_use tool uses to firewall its current page state in place.
- Dropped an unused binding in the phishing-credentials incident fixture (#55).
v0.5.0
v0.5.0 — the incidents suite + a stronger detector
Added
- Incidents suite (
incidents/,npm run demo:incidents): the headline agentic-browser failures of 2025–2026 — CometJacking, PleaseFix, the Scamlexity counterfeit-store checkout, agent credential-phishing, and invisible (white-on-white / offscreen) instructions — reproduced as offline fixtures and driven through fieldpass, with shareable receipts inincidents/INCIDENTS.md. Runs browserless (CI) or through real Chrome withPICKET_CDP. Locked in as a regression + false-positive suite (test/incidents.test.mjs).
Changed
- Detector coverage: the "sensitive data" leg now recognizes the personal-data collections an agentic browser handles — a third-person reference to the user's emails / inbox / calendar / contacts / message-or-browsing history (gated so a page's own "check your email" copy can't trip it) — and the "instruction" leg now catches "supersede your … instructions" and a broader "do not <tell/reveal/surface/mention> … the user" set. CometJacking and PleaseFix now resolve to a lethal-trifecta BLOCK; the full false-positive corpus stays clean (145 tests).
Full changelog: https://github.com/askalf/fieldpass/blob/main/CHANGELOG.md
v0.4.1
Docs-only patch.
Changed
- README badge row — license, dependency, and "why this matters" are now flat shields.io badges matching the
ciand OpenSSF Scorecard style (one consistent badge row on npm + GitHub). The dependency badge corrects the count from "one" to the actual three runtime dependencies (@modelcontextprotocol/sdk,node-html-parser,zod). No code or API changes. (#41)
v0.4.0
@askalf/fieldpass v0.4.0
Added
- Session-recorder / canon-skill plane over MCP (#30) — the last plane that was reachable only as a JS import is now on the MCP server.
picket_record_startopens a named recording; addrecord: "<name>"topicket_observe/picket_gate/picket_loginto append each governed step (secrets redacted, withheld payloads never recorded).picket_skill_emitserializes it into a canon-pinnable manifest with itsskillHash— goldens reduced to fingerprints, so a withheld payload can't be recovered through the manifest, while the per-stepverdictstill signals recorded hostility.picket_skill_replayre-runs a recording (or a manifest) against the live browser and reports per-step drift +regressedToInjection.
With this, all five planes — perception, action, identity, verification, skill — are reachable over MCP. Additive and backward-compatible (MCP tool count 6 → 9).
Published to npm via OIDC trusted publishing. Full test suite (131) green on Node 20 and 22.
Full changelog: https://github.com/askalf/fieldpass/blob/main/CHANGELOG.md
v0.3.0
@askalf/fieldpass v0.3.0
Added
- Replay-verification oracle over MCP —
picket_verify/picket_snapshot/picket_replay. The deterministic anti-fabrication gate (re-capture the real page, check claims / snapshot goldens / detect a clean→injection regression) is now reachable from any MCP client, not just as a JS import. No withheld excerpt ever crosses the wire. (#26)
Security (from a full repo audit)
- Unicode confusable fold hardened — broadened the fold to close a homoglyph bypass outside the Cyrillic/Greek core (the Latin script-g
ɡ, U+0261), and made the safe view stop Latinizing/normalizing benign non-Latin page text (it now folds only to detect a fence/role forgery and neutralizes the exact original span). - Shadow DOM / declarative templates / pseudo-element capture — the live backend now descends open shadow roots and reads
::before/::aftercontent, so an injection planted there is no longer captured as zero nodes; the replay oracle sees that visible content too. (#25) - HTTP transport refuses an unauthenticated non-loopback bind — a
0.0.0.0bind with no bearer token would be an open, unauthenticated governed browser; it now throws unless a token is set orallowInsecureis passed. - Underlying confusables and Shadow-DOM-capture fixes (#24, #25), plus test coverage for the WardenClient escalation path and the split-trifecta quarantine branch.
Published to npm via OIDC trusted publishing. Full test suite green on Node 20 and 22.
Full changelog: https://github.com/askalf/fieldpass/blob/main/CHANGELOG.md
v0.2.1
Renamed
@askalf/picket→@askalf/fieldpass(#23) — npm-publishable name;picketis squatted unscoped and the registry create-policy blocks colliding scoped names. The GitHub repo is nowaskalf/fieldpass(old URLs redirect). Legacypicket/picket-mcpbin aliases retained; MCP tool names andPICKET_*env vars unchanged.
Added
- Streamable HTTP transport for the MCP server (#21) —
fieldpass-mcp --httpservespicket_observe/picket_gate/picket_loginas a URL-type MCP server, so clients that can't spawn a stdio process (the Claude API MCP connector, Managed Agents, remote agent runtimes) can attach. Spec session management with every session sharing one governed browser (verdict cache and keeper leases persist, same as stdio); binds127.0.0.1by default with DNS-rebinding protection on loopback, optional constant-time bearer auth (PICKET_MCP_TOKEN), and an unauthenticatedGET /healthzliveness probe. stdio stays the default transport. - Framework example series (#22) — four runnable, offline, no-API-key examples of real agent-framework engines browsing behind the firewall via the MCP server: LangGraph.js (
StateGraph), OpenAI Agents SDK (scripted offline model through the genuineRunner), CrewAI (Flow), and Microsoft AutoGen (AssistantAgent+McpWorkbench). Each reads a booby-trapped invoice page, proves the injection is withheld while benign content survives, has every hijack action refused at the gate, and shows login failing closed with no vault — with captured evidence and pinned versions from real runs in each example'sevidence/.
CI
- npm releases are now tokenless: OIDC trusted publishing via
publish.yml(#27), with a dailynpm-drift.ymlwatch comparing the latest GitHub release against the npm registry.
This version is live on npm as @askalf/fieldpass@0.2.1.
v0.2.0
The complete prototype→product roadmap since the initial release: LLM-judge escalation, an MCP server, a persona context broker, a replay-verification oracle, canon-pinnable browser skills, and a hardened firewall core.
Added
- LLM-judge escalation tier — a configurable Claude backend reviews only the ambiguous residue the deterministic detector can't rule on, with confidence calibration and a message-id round-trip fix (#1), plus a content-keyed verdict cache (bounded LRU, fail-safe) to cut repeat LLM calls (#3). Escalate-only and inert on error.
- MCP server —
picket_observe/picket_gate/picket_loginexposed over stdio via thepicket-mcpentrypoint, so any MCP client gets the governed browser (#4). Observe returns verdict and finding categories only — withheld excerpts never cross the wire. - ContextBroker — a pool of isolated, keeper-backed persona contexts on one shared browser: login-once per persona, LRU eviction, and non-destructive teardown (disconnect, never close) (#5).
- Replay-verification oracle — a deterministic snapshot / diff / claim-verification gate that culls fabricated "the page shows X" claims without an LLM, and flags clean-golden → injection regressions (#6).
- Canon browser skills — record a governed session and emit it as a canon-pinnable, deterministically replayable skill manifest; secrets are redacted and the sha256 skill hash matches canon's pin (#7).
- npm publish workflow and
publishConfig.access: public(#10).
Fixed
- Firewall + action-gate hardening (#2):
observe()now prefers the live CDP bridge over the static parser when both are available; cross-node split-trifecta detection catches legs scattered across sibling nodes; the gate default-denies unknown action types; credential typing is inferred from field shape even without the flag; the nav allowlist matcheshostname(not host:port); anddata:/javascript:/blob:URLs count as exfil sinks. - Live CDP capture parity (#8): low-contrast hidden text uses the same color-distance threshold as the static backend, and
valueattributes are scanned — closing two evasions that only affected the live path. - The oracle reuses the detector's canonical action lattice instead of a local copy (#9).
Docs
- README repositioned: picket is a standalone Own Your Stack tool that composes with the warden · canon · keeper trilogy (#11).
Full changelog: v0.1.0...v0.2.0
v0.1.0
First tagged release. A governed agentic browser — an indirect-prompt-injection firewall, an action gate, and an LLM judge between the agent and the open web, plus a verdict cache and an MCP server (picket_observe / gate / login). Part of the Own Your Stack agent-security stack.