mint_url. There is no second field, so if both your product and the Patchwork runtime need tokens from you, that single endpoint has to serve both.
They are genuinely different callers with different proofs and — this is the part that catches people — different response shapes.
Branch on the signature
The one reliable discriminator is whether the request carries aPatchwork-Signature header. A browser never has one; Patchwork always does.
Relay: Patchwork asking
Patchwork needs a token for a subject it is already acting for. It proves it is Patchwork with the presenter signature, and names the subject in the body:Trust the subject, do not re-authorize it
The subject in the body is one Patchwork was already given — asserted by your own backend in relay, or verified from a token you signed in direct. You are not being asked whether this user exists; you are being asked to issue them a token. What you must do is mint for exactly that subject and no other. Never widen it, and never fall back to a default subject when the string is unfamiliar.Direct: your browser asking
Your own frontend, minting for the signed-in user. There is no signature — authenticate it the way you authenticate any other endpoint in your product.Patchwork’s own integration does exactly this. Its direct branch composes the subject as
user_id:workspace_id, the same composite pattern we recommend, derived from the session rather than from the request.What expires_in actually controls
Patchwork caches each minted token per (mint_url, subject) and reuses it, so a burst of tool calls mints once.
So
expires_in is not decorative. If you return an hour, Patchwork holds that token for an hour, and revoking early has no effect on calls already in flight. Keep it short.
Rotating your request secret
Verify the presenter signature against your current and previous secret, not just the current one:The Playground needs the relay branch
This is the consequence people hit first, and it hits during testing rather than in production. Playground runs are trusted-internal — there is no browser and no session token on the request — so egress can only take the relay path. A connection usingminted auth is testable in the Playground only if its mint URL handles the relay branch correctly.
The subject Patchwork sends is the persona’s subject verbatim, so if your tools resolve a subject, the persona must name one your backend can find — see The Playground.
Build only the direct branch and you get a working product with a Playground that fails inside a run:
Checklist
required
A connection declares one
mint_url. Handle both callers there.required
Present means relay. Absent means your own frontend.
required
{ token, expires_in } at the top level. No envelope.required
Current and previous, so rotation does not break minting.
required
Never widen it, never substitute a default.
recommended
It sets Patchwork’s cache lifetime, not just the token’s.