Documentation Index
Fetch the complete documentation index at: https://docs.getbindu.com/llms.txt
Use this file to discover all available pages before exploring further.
Security and Correctness Pass, Two Features Along for the Ride
This is mostly a security-and-correctness release. The x402 payment middleware was rewritten on top of the x402 SDK v2 — that single migration closes four payment-bypass bug classes (body-parse fail-open, replay, unverified signatures, skipped balance check) and clears every high-severity x402 entry frombugs/known-issues.md. Three additional server bug classes are closed too: malformed context_id no longer silently spawns new conversations, task cancel is now CAS-protected, and a new optional auth.allowed_dids admission allowlist gates which Hydra-registered DIDs can reach handlers at all.
The two operator-facing features riding along: the x402 middleware is now extensible to any EVM chain (SKALE Europa ships as the worked example), and agents can expose a second skill surface — private_skills — gated by Hydra auth plus a DID allowlist, for operators whose skill descriptions are themselves the commercial product.
The frontend drops parquetjs, which removes 130+ transitive packages and two unpatched Apache Thrift advisories. Roughly 90 Dependabot alerts get patched via lock refresh.
What You Need to Change
Security
Four x402 Bug Classes Closed
The old x402 middleware onv0.2.1 carried four payment-bypass shapes. All four are now closed:
| Bug | Before | After |
|---|---|---|
| Body-parse fail-open | Bare except Exception swallowed JSON errors and fell through to the handler | Narrow except (JSONDecodeError, UnicodeDecodeError) returning HTTP 402 |
| Replay | No nonce store; signed payloads replayable indefinitely | (network, asset, nonce) claimed via Redis SETNX before the facilitator round-trip (InMemoryNonceStore fallback for dev) |
| Unverified signatures | Signature verification was a stub that never ran | Full EIP-712 recovery runs on the facilitator |
| Balance check skipped | Fall-through allowed requests when the asset contract had no code on chain | Fall-through removed |
invalid_exact_evm_signature before the handler runs. Bindu Core’s high-severity count drops from 4 to 0.
DID Admission Control
Before, any Hydra-registered DID could call any agent. In multi-tenant or shared-Hydra deployments, anyone withhydra create oauth2-client could mint a token for their own DID and burn your agent’s compute budget.
New AuthSettings.allowed_dids: list[str] | None = None. Default is None (admit all, behavior unchanged). When set, the Hydra middleware runs an allowlist check after signature verification and rejects unlisted DIDs with HTTP 403 before any handler runs.
Cancel Race Closed
Thecancel_task handler used to read state, compare to terminal states, then call scheduler.cancel_task with no atomic guarantee between the steps. A worker that completed mid-cancel left the handler cancelling an already-terminal task and returning a response that didn’t match the actual final state.
The Storage ABC gains update_task_state_if(task_id, from_state, to_state) -> bool. Postgres implements it as a conditional UPDATE ... WHERE state = :from RETURNING id; the in-memory backend implements it as a compare-and-swap with no inter-await yield. The cancel handler CAS-claims the transition before signaling the scheduler — on a miss it reloads and reports the actual post-race state.
Dependency Refresh
Direct bumps and lock refreshes clear ~90 Dependabot alerts:pynacl==1.5.0→>=1.6.2,<2(libsodium incomplete-disallowed-inputs)web3==7.13.0→>=7.15.0,<8(SSRF via CCIP Read OffchainLookup)cryptography==44.0.2→>=46.0.5,<47pypdf<6→>=6.10.2,<7(clears 44 alerts via lock refresh)cdp-sdk==0.21.0→>=1.45.0,<2(frees the cryptography pin)- Frontend:
ip-address^9.0.5→^10.1.1(Address6 XSS);cookie^0.7.0override;minimatch^9.0.7override scoped totypescript-estree - TruffleHog pre-commit tightened to
--results=verifiedso the scanner stays usable (signal-to-noise jumps from 7% to 100% on a historical scan)
Headline Features
Operator-Extensible EVM Chains for x402
x402 v2 ships built-in pricing for Base mainnet and Base Sepolia. Operators wanting SKALE / Polygon / Avalanche / anything else previously had to fork the SDK. NewX402Settings.extra_networks config surface — a Pydantic dict keyed on a friendly chain slug, carrying CAIP-2, asset address, and EIP-712 domain metadata. Each entry registers a money parser scoped to its CAIP-2, so the SDK’s built-in Base parser still wins for Base. SKALE Europa ships as the default extra network, matching facilitator.x402.fi’s advertised bridged-USDC asset (decimals=6, name=“USDC”, EIP-712 version=“2”) exactly.
Add chains by extending the dict — no Bindu code change required.
Private Skill Catalogs Gated by DID Allowlist
For operators whose skill catalogue is the commercial product (compliance, legal, regulated workflows), exposing skills publicly on/.well-known/agent.json leaks the product menu.
Two new optional keys on AgentManifest — private_skills and allowed_dids — expose a second endpoint at /agent/private.json. The Hydra middleware fronts it like any non-public route; the handler adds an allowlist check that rejects authenticated-but-unlisted DIDs with HTTP 403. The route isn’t registered when unused — opt-in only.
This closes the IP-leak shape with auth gating rather than encryption-at-rest. The JWE/E2E option remains as a Phase 2 if a real customer demands “operator doesn’t trust the server itself” semantics.
Documentation Refresh
README.mdslimmed to a transformers-style layout; leads with the Trade Compliance OS pitchdocs/PAYMENT.mdrewritten in the teaching voice: end-to-end paywall walkthrough with success and failure paths against a mock facilitatordocs/PRIVATE_SKILLS.md— new, teaching-voice doc
Performance Impact
- x402 v2 middleware: replay short-circuits at the nonce store before any facilitator round-trip, so duplicate-payment requests are cheaper to reject than they were to accept under v0.2.1
- Admission control: a Python
incheck on a list — operators with long allowlists may want a pattern-match variant in a future release; exact-match is shipping first because it covers the common case - CAS cancel: one extra
UPDATEon Postgres, one extra dict read on in-memory storage. Both inside the existing request span - The Storage ABC change is additive — existing backends gain one new method but their hot paths are unchanged
Testing
- 993 unit tests passing, 3 skipped, 12 warnings, runtime ~3.3s.
ruffclean.ty: 0 diagnostics. - 7 admission tests covering default admit-all, exact-match hits, misses, deny-all empty-list posture, missing
client_did, and 403-doesn’t-forward - 3 storage CAS tests (success, mismatch, missing task)
- 2 cancel-race tests (CAS-success happy path; CAS-failure does NOT signal the scheduler)
- 7 context-id tests covering all four
_parse_context_idbranches plus the_create_error_responsecode-override path - 1 regression test for
send_messagereturning-32602on malformedcontext_id - 8 private-skills endpoint tests exercising the auth + allowlist gate end-to-end
- 11
extra_networkstests covering schema validation, money parser registration, non-default decimals (WETH 18-decimals), and fall-through - 10 nonce-store tests covering key construction, replay rejection, TTL expiry, and concurrent claim races
- 9 x402 middleware tests exercising the full v2 dispatch path with a mocked ResourceServer
- 2 opt-in live-facilitator smoke tests confirming the shipped SKALE Europa default matches
facilitator.x402.fi’s/supportedresponse
Known Issues
skale-facilitator-cert-expired(low, ops): the only public x402 facilitator advertising SKALE chains isfacilitator.x402.fi, whose TLS certificate is currently expired. Bindu’s defaults still point at Coinbase’s facilitator; SKALE operators setX402__FACILITATOR_URLthemselves and either accept the cert error or front the upstream with a reverse proxy. Not a Bindu code bug — recommended production posture is self-hostingx402-facilitator.authz-scope-check-behind-optional-flag(medium, security): the scope-check flag (auth.require_permissions) defaults toFalseand authorization disappears when it’s not flipped on. Deferred to the planned Ory Kratos migration rather than patched in place.no-rate-limit-or-quota-per-caller(medium): no per-DID quota or body-size limit on the Starlette app. Operators exposing Bindu directly on the public internet should add their own rate limiting at the proxy until this lands natively.- Historical Auth0
client_secretvalues committed in October 2025 ate28e3417are still reachable viagit log(removed from HEAD but the blob persists). Rotation is an operator action, not a code fix.