Delegation Layer

Learn how authority is securely delegated in KYA-OS using verifiable credentials.


Why Delegation Matters

Without delegation, AI agents would need full access to a user's account—posing risks for security, privacy, and compliance.

Delegation in KYA-OS solves this by using VCs to:

  • Scope authority to only what’s necessary
  • Prove user consent cryptographically
  • Support revocation and expiration
  • Allow audit of each request

Delegation Credential Structure

Delegation is encoded inside a VC that includes:

  • The issuer (user/delegator DID)
  • The subject (agent/delegatee DID)
  • The scope of allowed actions and constraints
  • The expiration timestamp
  • A cryptographic proof signed by the issuer

→ See Credential Models for the full schema


Delegation Process

The delegation process typically follows these steps:

Loading diagram...

Delegation Lifecycle Diagram

The following diagram shows how a credential is issued, optionally rotated, and eventually revoked:

Loading diagram...
  • A credential may be valid until expiration or actively revoked
  • Rotation means a new VC replaces the old one with updated scope or subject
  • Verifiers must reject expired or revoked credentials

Delegation Chain

KYA-OS supports chained delegation:

  • User → Agent A → Agent B
  • Each link in the chain is a separate credential
  • The verifier must validate each link on the chain recursively
Loading diagram...

When verifying a delegation chain:

  1. Start with the leaf credential (the one presented by the requesting agent)
  2. Verify each credential in the chain recursively
  3. Ensure each delegation's scope is a subset of its parent
  4. Check for circular dependencies
  5. Verify no credential in the chain is expired or revoked

Each VC must:

  • Be valid (not expired or revoked)
  • Be signed by the correct issuer
  • Match the scope requested
  • Link to previous subject DID

Delegation Validation Failures

Delegation fails if:

  • A link is missing (e.g., broken chain)
  • A VC is revoked or expired
  • Signature is invalid
  • Scope is insufficient or fails constraint expressions

The protocol error codes for these failures (SPEC.md Appendix A) are:

CodeMeaning
delegation_invalidDelegation verification failed (structure, signature, chain, or constraints)
delegation_revokedA credential in the chain has been revoked
insufficient_scopeThe requested operation is outside the delegated scope
needs_authorizationNo sufficient delegation was presented; the response carries a signed consent challenge (SPEC.md §9)

Card-era chain evaluation additionally returns fail-closed, human-readable reasons[] describing exactly which invariant broke (for example a broadening hop, broken continuity, invocationTarget drift, or excessive depth) — an empty reasons array is the only success state.

→ These checks run inside the resource server's own verifier on every request — verification is in-process, not delegated to a fronting proxy


Scope Definition

Scopes in KYA-OS follow a standardized format to ensure clear and consistent authorization:

action:resource[/subresource][#instance]

Examples:

  • read:email - Permission to read emails
  • write:calendar/events - Permission to create calendar events
  • transfer:finance#account123 - Permission to transfer funds from account123

The CRISP Constraint Envelope

Scopes live inside the CRISP constraint envelope (SPEC.md §6.3), which also carries temporal bounds, audience restrictions, and extended constraints:

interface DelegationConstraints {
  notBefore?: number;          // Unix epoch seconds
  notAfter?: number;
  scopes?: string[];           // simple scope list
  audience?: string | string[]; // server DID or domain
  crisp?: {
    budget?: {
      unit: "USD" | "ops" | "points";
      cap: number;
      window?: { kind: "rolling" | "fixed"; durationSec: number };
    };
    scopes: Array<{
      resource: string;
      matcher: "exact" | "prefix" | "regex";
      constraints?: Record<string, unknown>;
    }>;
  };
}

Two rules govern how constraints behave across a chain:

  • Attenuation — a child delegation's constraints must be equal to or narrower than its parent's; any broadening hop invalidates the whole chain
  • Designation — a multi-scope delegation authorizes, but an invocation must designate the specific scope being exercised, and the verifier confirms the designated scope is a member of the delegation's authorized scopes (SPEC.md §6.4.1)

Revocation

KYA-OS requires implementation of credential revocation to enable withdrawal of delegation. Revocation is two-track, matching the two schema eras:

Track 1 — StatusList2021 (legacy VC 1.0 era)

Legacy-era credentials carry a StatusList2021Entry:

{
  "credentialStatus": {
    "id": "https://example.com/status/123#94",
    "type": "StatusList2021Entry",
    "statusPurpose": "revocation",
    "statusListIndex": "94",
    "statusListCredential": "https://example.com/status/123"
  }
}

Track 2 — Bitstring Status List v1.0 (card era)

Card-era credentials use the W3C Bitstring Status List v1.0 — the successor format — via a BitstringStatusListEntry. The checker is fail-closed: an unreachable list, malformed credential, mismatched statusPurpose, or out-of-range index all resolve to revoked.

In both tracks each bit in a gzip-compressed bitstring represents one credential's status, and the status list does not have to be public: a verifier that issues and gates its own delegations may check revocation entirely from local state. For on-chain publication, CheqdStatusListResolver (@kya-os/mcp/cheqd) resolves and verifies status lists anchored as cheqd DID-Linked Resources, pinning the expected issuer and verifying the list's own signature.

Revocation Semantics

  • Evaluated on every verification — revocation status and expiry are checked on every call; verdicts are never cached (the v1.13.0 security fix)
  • Cascading — revoking a delegation revokes every descendant delegation in the graph
  • Authorized revokers — the direct issuer, any ancestor issuer in the chain, or the root Responsible Party; a delegate cannot revoke its own delegation

Revocation Process

Loading diagram...