- Install the SDK.
- Set up one verifier.
- Add the two routes: a nonce route (
POST /nonces) and a token route (POST /oauth/token). - Ask agents for a credential by answering protected pages with
401and aKYA-Disclosure-Scopeheader.
/.well-known/kya-profile.json. Every accepting site needs one. See Asking for fields.
Install
The KYA SDK is coming soon. The install commands and the code on this page won’t work until the packages are published. Until then, you can check credentials yourself with the Credential Format Reference.
fetch: Node 20+, Auth0 Actions, Cloudflare Workers and other edge runtimes. Python needs 3.11 or later.
Method and option names in these docs are shown in TypeScript. The Python SDK uses the same names in snake_case, such as actorAttests and actor_attests; the Python tab of each code sample shows the exact call.
The TypeScript SDK also covers the agent’s side: the agent key, Key Binding JWTs, the token exchange with a site and DPoP-bound sessions. The Python SDK checks credentials only.
- TypeScript depends only on
libphonenumber-js. - Python depends on
certifi,cryptography,httpcore,httpx,idna,phonenumbers,pydanticandrfc8785.
Set up a verifier
Create one verifier and share it across requests. It holds the key cache, the revocation list cache and the single-use nonces. Every verifier needs a nonce store, and there is no default.InMemoryNonceStoreis for one long-lived process and for tests.- If you run more than one server, serverless functions or edge workers, pass a store they all share instead. See Share nonces across servers.
allowSandbox (TypeScript) or allow_sandbox (Python) while you test with sandbox credentials. Leave it off in production.
Add the two routes
The agent doesn’t sign in with a password. It trades its credential for your own access token, the same way an app signs in with OAuth:- It calls your nonce route to get a one-time code, so a copied credential can’t be reused. Each nonce works once.
- It sends its credential to your token route, which checks it and returns your token.
verify. That is what makes your site refuse a credential that shares more than your profile lists.
The two helpers
oauthError turns a failure into an OAuth error response. tokenResponse issues your own access token. The other pages in this section reuse both.
issueAccessToken stands for the code you already use to issue access tokens.
report.checks lists every check that ran, pass or fail. Write it to your audit log.
Related:
- For retries and outages, see Handling failures.
- To tie your token to the agent’s key with DPoP, see Where to run it.
- On more than one server, share nonces across servers.
Ask agents for a credential
When an agent with no token asks for a page that needs a verified person, answer401 with a KYA-Disclosure-Scope header. The value is <profile_id>#<scope_name> from your published profile:
What gets checked
The SDK runs these checks in order and stops at the first failure:- The presentation is well formed.
- It is a KYA credential.
- Baselayer issued it, and Baselayer’s signing keys can be fetched.
- The signature is valid and the credential is inside its time window.
- It hasn’t been revoked.
- The shared fields match what Baselayer signed.
- It is being presented by the agent it was issued to, with a nonce you issued, for your domain.
- It was issued for your domain, its verification summary matches the checks it lists, and it shares no more than the scope you asked for (when you pass one).
report.exchangeClaims() gives:
report.credential.disclosed has the same shared fields as { path: value }.
Each failure has its own code. See Handling failures.
Next steps
- Where to run it: your backend, your login server or the edge, plus production tips.
- Asking for fields: limit what an agent can share.
- Handling failures: what each refusal means and what to tell the agent.