AUTH__ENABLED=true, every call to a Bindu agent has to do two things at once:
- Prove you’re allowed — attach a short-lived bearer token from Hydra.
- Prove you’re really you — sign the request body with your DID’s private key and attach the signature.
The four headers
Every call to an auth-on Bindu agent carries these four headers:Gate 4 collapses two sub-causes (clock skew and bad signature) into one
invalid_signature reason. If you get this error, re-signing with a fresh timestamp eliminates clock-skew and replay as the cause.I just want it to work — use a built-in caller
Most teams should not hand-roll this. Three callers in the Bindu repo do the whole chain for you:
Quick smoke test against an auth-on agent, using the inbox:
ok:true, status:200 back means every gate above passed. You’re done.
The rest of this page is for people writing the caller from scratch in a new language.
Hand-rolling it: one-time setup
You need three durable artifacts:- A seed — your 32-byte secret. Generates the Ed25519 keypair.
- A DID — your public name, deterministically derived from the seed.
- An OAuth client in Hydra — registered against the DID, with the public key in metadata.
1
Generate seed, DID, public key
2
Register the OAuth client in Hydra
The DID is the Save
client_id. The public key goes in metadata.public_key — that’s how the agent finds your key during signature verification.CLIENT_SECRET. You need it to mint tokens.Hand-rolling it: every request
Four steps. The first runs once per hour (token cache). The other three run on every call.1
Mint a bearer token
expires_in runs out.2
Build the JSON-RPC body
Serialize the body once and keep the exact bytes. The bytes you sign must equal the bytes you send.
3
Sign
The signing payload is a second JSON object that wraps the body as a string. Sort keys and keep Python’s default whitespace.
4
Send with all four headers
What can go wrong
The middleware collapses four sub-causes of “signature didn’t verify” into one
invalid_signature reason. To narrow it down, re-sign with a fresh timestamp first — that eliminates clock skew and replay. If it still fails, you have a body-byte or key-mismatch issue.active: true, client_id == your DID, and exp > now. Anything off here is your bug.
Canonical fixture
Use this to verify your sign-and-encode implementation against every other Bindu caller, in any language.
Signing payload (note spaces after
: and ,):
nacl-base58 is the same).
What’s next
Security Stack
How mTLS, Hydra, and DID signatures compose on a single request
DID Identity
The signing side in depth — Ed25519, canonical JSON, key rotation