DID & Credentials

Cryptographic identity and verifiable audit trails for agent executions

The DID (Decentralized Identifier) and Verifiable Credentials system provides cryptographic audit trails for agent executions, enabling compliance, traceability, and accountability.

Overview

Each agent execution can generate a Verifiable Credential (VC) that cryptographically attests to:

  • What input was received
  • What output was produced
  • Which agents were involved
  • When the execution occurred

Basic Usage

agent.reasoner('process', async (ctx) => {
  const result = await ctx.ai(`Process: ${ctx.input.data}`);

  // Generate credential for this execution
  await ctx.did.generateCredential({
    inputData: ctx.input,
    outputData: result
  });

  return result;
});

Configuration

DID/VC is enabled by default. Disable it in agent config:

const agent = new Agent({
  nodeId: 'my-agent',
  didEnabled: false  // Disable DID/VC
});

DidInterface Methods

generateCredential()

Generate a verifiable credential for the current execution.

const credential = await ctx.did.generateCredential({
  inputData: { userId: '123' },
  outputData: { result: 'processed' },
  status: 'completed',
  durationMs: 150
});

Prop

Type

exportAuditTrail()

Export credentials for auditing.

const audit = await ctx.did.exportAuditTrail({
  workflowId: 'wf-123',
  startTime: new Date('2025-01-01'),
  endTime: new Date('2025-01-31')
});

ExecutionCredential Structure

interface ExecutionCredential {
  vcId: string;              // Unique credential ID
  executionId: string;       // Execution this credential is for
  workflowId: string;        // Workflow ID
  sessionId?: string;        // Session ID
  issuerDid?: string;        // DID of issuing agent
  targetDid?: string;        // DID of target agent
  callerDid?: string;        // DID of calling agent
  vcDocument: any;           // Full W3C VC document
  signature?: string;        // Cryptographic signature
  inputHash?: string;        // Hash of input data
  outputHash?: string;       // Hash of output data
  status: string;            // Execution status
  createdAt: string;         // Timestamp
}

Examples

Automatic Credential Generation

agent.reasoner('financial_analysis', async (ctx) => {
  const { accountId, period } = ctx.input;
  const startTime = Date.now();

  try {
    const data = await fetchFinancialData(accountId, period);
    const analysis = await ctx.ai(`Analyze: ${JSON.stringify(data)}`);

    // Generate success credential
    await ctx.did.generateCredential({
      inputData: { accountId, period },
      outputData: { analysisId: analysis.id },
      status: 'completed',
      durationMs: Date.now() - startTime
    });

    return analysis;
  } catch (error) {
    // Generate failure credential
    await ctx.did.generateCredential({
      inputData: { accountId, period },
      status: 'failed',
      errorMessage: error.message,
      durationMs: Date.now() - startTime
    });
    throw error;
  }
});

Audit Trail Export

agent.skill('export_audit', async (ctx) => {
  const { workflowId, startDate, endDate } = ctx.input;

  const audit = await ctx.did.exportAuditTrail({
    workflowId,
    startTime: new Date(startDate),
    endTime: new Date(endDate)
  });

  return {
    totalCredentials: audit.totalCount,
    agentDids: audit.agentDids,
    executions: audit.executionVcs.map(vc => ({
      id: vc.vcId,
      executionId: vc.executionId,
      status: vc.status,
      timestamp: vc.createdAt
    }))
  };
});

Compliance Workflow

agent.reasoner('compliance_check', async (ctx) => {
  const { documentId, checkType } = ctx.input;

  // Perform compliance check
  const result = await performComplianceCheck(documentId, checkType);

  // Generate credential with full audit info
  const credential = await ctx.did.generateCredential({
    inputData: {
      documentId,
      checkType,
      checkedBy: ctx.agentNodeDid
    },
    outputData: {
      passed: result.passed,
      findings: result.findings.length,
      severity: result.maxSeverity
    },
    status: result.passed ? 'passed' : 'failed'
  });

  return {
    ...result,
    credentialId: credential.vcId,
    verifiable: true
  };
});

DID Properties in Context

Access DID information from the context:

agent.reasoner('example', async (ctx) => {
  // Available DID properties
  const callerDid = ctx.callerDid;      // Who called this agent
  const targetDid = ctx.targetDid;      // Target agent DID
  const agentNodeDid = ctx.agentNodeDid; // This agent's DID

  return { callerDid, targetDid, agentNodeDid };
});

Use Cases

  • Financial Services - Audit trails for trading decisions
  • Healthcare - Track data access and processing
  • Legal - Verifiable document processing
  • Supply Chain - Track provenance across agents
  • Compliance - Demonstrate regulatory adherence

Credentials are stored by the Agentfield control plane and can be exported for offline verification using the af verify CLI command.