Working Draft — This document is under active development and has not yet been adopted by Canton governance.

Canton Agent Identity Standard

Status
CIP Draft
Type
Daml Interface Standard
Author
John Lilic
Created
2025-06
Package
Canton.AgentIdentity.Interfaces
Requires
Daml-LF ≥ 1.15, Canton protocol ≥ 4
License
Apache 2.0
Interfaces
4
Helpers
4

Abstract

Four typed Daml interfaces for AI agent identity on Canton Network. Any application can import them. The Daml compiler checks the rest.

Definitions

Terminology

Agent
Autonomous software acting on behalf of an organization on Canton Network. Holds a Canton party ID and executes transactions without real-time human approval.
Principal
The organization legally responsible for an agent’s actions. A bank that deploys a trading agent is that agent’s principal.
Credential
A contract implementing the AgentIdentity interface. Issued by a trusted party, it binds an agent to its principal, capabilities, and limits.
Capability
A named permission granted to an agent (e.g. "transfer", "settle", "quote"). Checked at verification time against the credential’s capability list.
Delegation depth
How many levels of sub-delegation separate a child agent from the original parent. Depth 0 means direct delegation; the maximum depth caps how far delegation can chain.
Verification proof
A contract implementing the VerificationResult interface. Created after checking an agent’s credential and consumed by the counterparty to confirm the agent passed verification. Single-use and time-bounded.

§1

The Problem

Canton gives every participant a party ID and node identity. A party is a unique identifier representing an entity that can create and interact with contracts on the ledger. The Ledger API offers an object_metadata field for associating free-form attributes with a party, but there is no typed, on-ledger identity structure. That model is sufficient for organizations. It is not sufficient for autonomous software.

When an AI agent connects to your application and requests a transfer, a settlement, or a collateral move, Canton’s identity model cannot answer:

  • Is this party an AI agent or a human operator?
  • If it’s an agent, which organization is the principal?
  • What is the agent authorized to do?
  • What are its per-transaction and daily volume limits?
  • Who is legally responsible when something goes wrong?
  • Has this agent performed reliably in prior transactions?

This standard defines four Daml interfaces that any Canton application can import to answer these questions. Typed fields, compiler-checked implementations, and Canton-native privacy. No new infrastructure required.

§2

Interface Definitions

Each interface defines a view type and a set of methods that any implementing template must provide. Applications query agents through these methods without knowing the underlying template.

The four interfaces form a lifecycle: AgentIdentity is the credential that establishes who an agent is and what it can do. A counterparty checks that credential to produce a VerificationResult — a time-bounded, single-use proof that the agent passed verification. An agent with an identity can delegate a subset of its capabilities to a child agent via a DelegationGrant, with enforced depth limits. After each transaction, either party can record the outcome as an immutable PerformanceRecord for reputation tracking.

AI
AgentIdentity Core identity credential
data AgentIdentityView = AgentIdentityView with agent : Party principal : Party agentId : Text agentClass : Text deriving (Eq, Show)
getAgentId:Text
getAgentClass:Text
getCapabilities:[Text]
getPrincipal:Party
getMaxTxValue:Optional Decimal
getMaxDailyVol:Optional Decimal
getValidUntil:Optional Time

AgentIdentity_Revoke

Consuming. Archives the credential. Controller: getPrincipal this (the owning organization).

VR
VerificationResult Proof of verification
data VerificationResultView = VerificationResultView with verifier : Party agent : Party agentId : Text verifiedAt : Time expiresAt : Time deriving (Eq, Show)
getVerifier:Party
getVerifiedAgent:Party
getVerifiedAt:Time
getExpiresAt:Time
getAgentIdVr:Text
getCapabilitiesVr:[Text]

VerificationResult_Consume

Consuming. Single-use: archives after acting on it. Asserts now <= expiresAt. Controller: getVerifier this.

DG
DelegationGrant Scoped delegation
data DelegationGrantView = DelegationGrantView with parent : Party child : Party parentId : Text childId : Text depth : Int deriving (Eq, Show)
getParentAgent:Party
getChildAgent:Party
getDelegatedCapabilities:[Text]
getDelegationDepth:Int
getMaxDepth:Int
getDelegationExpiry:Time

DelegationGrant_Revoke

Consuming. Parent revokes the delegation. Controller: getParentAgent this.

PR
PerformanceRecord Transaction outcomes
data PerformanceRecordView = PerformanceRecordView with recorder : Party agent : Party agentId : Text outcome : Text recordedAt : Time deriving (Eq, Show)
getPerformanceAgent:Party
getPerformanceAgentId:Text
getTransactionType:Text
getOutcome:Text
getLatencyMs:Optional Int
getRecordedAt:Time

No choices. Performance records are immutable once created.

§3

Helper Functions

Four convenience functions ship with the interface package. They operate on interface values, so they work with any implementing template.

agentHasCapability
  : AgentIdentity → Text → Bool

Check whether a specific capability is present on an agent identity contract.

agentIsValid
  : AgentIdentity → Time → Bool

Check whether an agent credential is still time-valid. Returns True if no expiry is set.

verificationIsValid
  : VerificationResult → Time → Bool

Check whether a verification result has not yet expired.

delegationIsValid
  : DelegationGrant → Time → Bool

Check whether a delegation grant is still within its time window.

Source Daml
-- Check whether a specific capability is present
agentHasCapability : AgentIdentity -> Text -> Bool
agentHasCapability ai cap =
  cap `elem` getCapabilities ai

-- Check whether an agent credential is still time-valid
agentIsValid : AgentIdentity -> Time -> Bool
agentIsValid ai now = case getValidUntil ai of
  None   -> True
  Some t -> now <= t

-- Check whether a verification result is still valid
verificationIsValid : VerificationResult -> Time -> Bool
verificationIsValid vr now = now <= getExpiresAt vr

-- Check whether a delegation grant is still time-valid
delegationIsValid : DelegationGrant -> Time -> Bool
delegationIsValid dg now = now <= getDelegationExpiry dg

§4

Implementation Guide

Add the interface DAR as a dependency, then implement the interfaces in your own templates. The Daml compiler enforces that you provide all required methods.

Step 1 — Add the dependency to daml.yaml YAML
dependencies:
  - daml-prim
  - daml-stdlib
  - canton-agent-identity-0.1.0.dar
Step 2 — Import the interfaces Daml
module YourApp.AgentCredential where

import Canton.AgentIdentity.Interfaces
Step 3 — Implement AgentIdentity in your template Daml
template YourAgentCredential
  with
    issuer       : Party
    agent        : Party
    agentId      : Text
    agentClass   : Text
    capabilities : [Text]
    principal    : Party
    maxTxValue   : Optional Decimal
    maxDailyVol  : Optional Decimal
    validUntil   : Optional Time
  where
    signatory issuer
    observer agent

    interface instance AgentIdentity
      for YourAgentCredential where
        view = AgentIdentityView with
          agent; principal; agentId; agentClass
        getAgentId      = agentId
        getAgentClass   = agentClass
        getCapabilities = capabilities
        getPrincipal    = principal
        getMaxTxValue   = maxTxValue
        getMaxDailyVol  = maxDailyVol
        getValidUntil   = validUntil
Step 4 — Query agents through the interface Daml
-- In your settlement workflow
verifyAgent : ContractId YourAgentCredential -> Update ()
verifyAgent credCid = do
  now  <- getTime
  cred <- fetch credCid

  -- Convert to interface — works with any implementation
  let ai = toInterface @AgentIdentity cred

  -- Use helper functions
  assertMsg "Credential expired"
    (agentIsValid ai now)
  assertMsg "Missing transfer capability"
    (agentHasCapability ai "transfer")

  -- Read typed fields through interface methods
  let principal = getPrincipal ai
  let agentClass = getAgentClass ai
  pure ()

§5

Design Principles

Correctness

Typed, not strings

Agent class, capabilities, and limits are typed Daml fields. The compiler checks your implementation at build time. No string parsing, no naming conventions to get wrong.

Privacy

Private by default

Canton’s sub-transaction privacy means credential data is visible only to signatories and observers. Counterparties share credentials via Explicit Disclosure, not public registries.

Flexibility

Implement or extend

Use an existing implementation like KYA, or write your own templates that implement the interfaces. The standard defines the shape; you control the behavior.

Simplicity

No new infrastructure

Daml interfaces are a language feature, not a protocol change. No new tokens, no new participant nodes, no consensus modifications. Import a DAR and start implementing.

§6

Implementations

KYA — Know Your Agent

Reference implementation and verification service

KYA is the first application built on the Canton Agent Identity Standard. It provides typed credential templates, a verification workflow with compliance hooks, delegation management, performance tracking, and integration with Canton’s Featured App rewards.

KYA implements all four interfaces:

KyaAgentCredential AgentIdentity KyaVerificationProof VerificationResult KyaDelegationGrant DelegationGrant KyaPerformanceRecord PerformanceRecord
Room for others. Any Canton application can implement these interfaces for its own agent identity needs. A custody platform, a trading venue, or a collateral management system can define their own credential templates while remaining interoperable with every other application that imports the standard.

§7

CIP Status

Draft Canton Agent Identity Standard
Draft
Review
Accepted
Final

This standard is being submitted as a Canton Improvement Proposal for governance review. If adopted by Super Validator vote, the interface package becomes a recognized Canton standard — distributed as a standalone DAR that any participant can import, so every application speaks the same agent-identity language at the type level.

The proposal includes the four Daml interfaces, their view types, helper functions, and guidelines for implementing applications. The interface package is designed for separate DAR distribution, enabling clean upgradeability per the CIP-56 pattern.