Our mission is easier agentic commerce — so this page is optimized for agent consumption and may look unusual to humans. For a formatted view, visit our GitHub README or homepage.
io.kyalabs.common.identity
UCP Extension Specification · v2026-01-11
Agent protocol for verified identity at checkout. Obtain a Badge JWT, present it in your UCP checkout payload, proceed with verified status.
01 — Overview
You discovered io.kyalabs.common.identityin a merchant's UCP manifest. This means the merchant accepts kyaLabs Badge — a signed ES256 JWT that proves you are acting on behalf of a verified human principal.
Presenting a valid Badge may give you reduced friction at checkout: bypassed bot detection, prioritized service, or streamlined approval. Without a Badge, proceed as an unverified guest — the merchant's standard checkout flow still applies.
What you see in the merchant's /.well-known/ucp
{
"io.kyalabs.common.identity": [
{
"version": "2026-01-11",
"spec": "https://www.kyalabs.io/ucp/spec/identity",
"schema": "https://www.kyalabs.io/ucp/schemas/identity.json",
"extends": "dev.ucp.shopping.checkout",
"config": {
"required": false,
"auth_endpoint": "https://www.kyalabs.io/api/oauth/device/authorize"
}
}
]
}config.auth_endpoint is where you start the authentication flow. config.required indicates whether a Badge is mandatory for checkout.
02 — Obtain a Token
Use the OAuth 2.0 Device Authorization flow (RFC 8628) to get approval from your human principal. The config.auth_endpointfrom the merchant's manifest points to this endpoint.
Step 1 — Request a device code
POST https://www.kyalabs.io/api/oauth/device/authorize
Content-Type: application/json
{ "scope": "ucp:scopes:checkout_session" }Response:
{
"device_code": "HZST-TLLN",
"user_code": "WX9A-K2M4",
"verification_uri": "https://www.kyalabs.io/activate",
"verification_uri_complete": "https://www.kyalabs.io/activate?code=WX9A-K2M4",
"expires_in": 900,
"interval": 3
}Step 2 — Get approval from your human principal
Display the user_code to your human principal. Direct them to verification_uri (or provide verification_uri_complete which includes the code). Poll for approval:
POST https://www.kyalabs.io/api/oauth/token
Content-Type: application/json
{ "grant_type": "device_code", "device_code": "{device_code}" }Response:
// Pending — keep polling every {interval} seconds:
{ "error": "authorization_pending" }
// Approved:
{
"access_token": "pc_v1_...",
"token_type": "Bearer",
"scope": "ucp:scopes:checkout_session"
}Step 3 — Exchange for a verification token
Once approved, use the access_token to request your identity JWT:
POST https://www.kyalabs.io/api/agent-identity
Authorization: Bearer {access_token}
Content-Type: application/json
{ "merchant_domain": "{merchant_domain}" }Response:
{
"verification_token": "<es256-jwt>",
"agent_disclosure": "This agent is using Badge by kyaLabs...",
"trust_url": "https://www.kyalabs.io/trust",
"contact": "agent_identity@kyalabs.io",
"principal_verified": true,
"mfa_confirmed": true,
"spend_available": false
}The verification_token is your Badge JWT. Include agent_disclosure text when interacting with the merchant to maintain transparency.
03 — Present Token
Include your Badge in the UCP checkout payload under the io.kyalabs.common.identity key. The merchant verifies your token server-side using JWKS or introspection.
UCP checkout payload
{
"io.kyalabs.common.identity": {
"token": "{verification_token}",
"kid": "kyalabs-badge-v1"
}
}| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Your verification_token from Step 3 |
kid | string | No | Key ID used to sign the JWT. Optional — extractable from the JWT header. Current value: kyalabs-badge-v1 |
Merchant-Side Verification
To verify your token directly with the merchant, make a GET request to:
GET {merchant}/apps/badge/verify?token={your_jwt}A response of { "active": true } means you are verified. This is the simplest way to confirm your Badge is accepted before or during checkout.
Shopify merchants can use the Badge app for turnkey integration. For custom storefronts, merchants implement verification using the reference implementation.
04 — Token Claims
The verification_token is an ES256-signed JWT. Header includes alg: "ES256", kid: "kyalabs-badge-v1". Payload claims:
| Claim | Type | Description |
|---|---|---|
sub | string | Tokenized user ID (HMAC hash — no PII) |
principal_type | string | mfa_authenticated_human or api_key_delegated |
principal_verified | boolean | Whether the principal's email is verified |
scopes | string[] | Authorization scopes (e.g. ["checkout:complete"]) |
merchant_domain | string? | Target merchant domain (when declared in Step 3) |
session_id | string? | Session identifier (when provided) |
install_id | string? | Shared install identity (UUID) for score resolution |
iss | string | Issuer — https://kyalabs.io. Note: the JWT issuer intentionally differs from the API base host (https://www.kyalabs.io). Integrators must validate tokens against the issuer string, not the API host. |
jti | string | Unique token ID (UUID) |
iat | number | Issued at — Unix timestamp |
exp | number | Expires at — Unix timestamp (default: 1 hour TTL) |
05 — Introspect
Merchants can verify tokens via RFC 7662 introspection. No API key required. Useful for real-time revocation checks or environments where local JWT verification is impractical.
POST https://www.kyalabs.io/api/oauth/introspect
Content-Type: application/json
{ "token": "{verification_token}" }Response:
// Active:
{
"active": true,
"scope": "ucp:scopes:checkout_session",
"credential_provider": "io.kyalabs.common.identity",
"badge_status": "declared",
"assurance_level": "regular",
"token_type": "Bearer"
}
// Invalid, expired, or revoked:
{ "active": false }assurance_level indicates trust tier based on transaction history: starter (<10 txns), regular (10–49), veteran (50–199), elite (200+). Per RFC 7662: invalid, expired, and revoked tokens always return { "active": false }.
06 — Reference
Endpoints
All endpoints are on https://www.kyalabs.io. The JWT issuer claim (iss) is https://kyalabs.io (without www). When validating tokens, check iss against the issuer string, not the API host.
| Endpoint | Purpose |
|---|---|
POST /api/oauth/device/authorize | Start device authorization (Step 1) |
POST /api/oauth/token | Poll for device flow approval (Step 2) |
POST /api/agent-identity | Exchange access token for Badge JWT (Step 3) |
POST /api/oauth/introspect | Token introspection (RFC 7662) |
GET /.well-known/ucp | Platform profile + signing keys |
GET /.well-known/jwks.json | JWKS public keys (RFC 7517) |
Signing Keys
| Algorithm | ES256 (ECDSA P-256 + SHA-256) |
| kid | kyalabs-badge-v1 |
| Keys | /.well-known/ucp → signing_keys[] |
Schema
Full JSON Schema: /ucp/schemas/identity.json. Extension payload requires token (string, required), optional kid (string). Extends dev.ucp.shopping.checkout via allOf composition.
Merchant integration: GitHub — kyalabs/ucp-agent-badge · Trust Architecture · Schema JSON
07 — Changelog
v2026-01-11 — Initial release
GitHub · Schema JSON · Trust Architecture · Platform Profile
kyaLabs · UCP Extension Publisher