Skip to main content
The KYA SDK checks a KYA credential in your own code. It comes in TypeScript and Python. Both are tested against the same shared test data, so they give the same answer for the same credential. You will build four things, in this order:
  1. Install the SDK.
  2. Set up one verifier.
  3. Add the two routes: a nonce route (POST /nonces) and a token route (POST /oauth/token).
  4. Ask agents for a credential by answering protected pages with 401 and a KYA-Disclosure-Scope header.
You also need a profile published at /.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.
TypeScript runs anywhere with WebCrypto Ed25519 and 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, pydantic and rfc8785.

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.
  • InMemoryNonceStore is 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.
Turn on 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:
  1. It calls your nonce route to get a one-time code, so a copied credential can’t be reused. Each nonce works once.
  2. It sends its credential to your token route, which checks it and returns your token.
The token route passes the scope from your published profile to 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:

Ask agents for a credential

When an agent with no token asks for a page that needs a verified person, answer 401 with a KYA-Disclosure-Scope header. The value is <profile_id>#<scope_name> from your published profile:
The agent reads your profile, gets a credential minted with that scope’s fields, and comes back through your two routes. See Asking for fields.

What gets checked

The SDK runs these checks in order and stops at the first failure:
  1. The presentation is well formed.
  2. It is a KYA credential.
  3. Baselayer issued it, and Baselayer’s signing keys can be fetched.
  4. The signature is valid and the credential is inside its time window.
  5. It hasn’t been revoked.
  6. The shared fields match what Baselayer signed.
  7. It is being presented by the agent it was issued to, with a nonce you issued, for your domain.
  8. 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).
On a pass, 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