Skip to content
AgentField
Governance

Verifiable Credentials

Execution VCs with 3-tier hierarchy, offline verification, and VC chain export

Verifiable credentials per execution

Cryptographic proof of what each agent did, when, and with what inputs -- tamper-evident and offline-verifiable.

Every execution can produce a signed verifiable credential (VC) containing SHA-256 hashes of inputs and outputs, tied to the agent's DID. VCs form chains across workflows, enabling offline verification and tamper-evident audit trails for regulated environments.

from agentfield import Agent

app = Agent(
    node_id="claims-processor",
    version="1.0.0",
    vc_enabled=True,  # Every execution → signed VC with SHA-256 I/O hashes
)

@app.reasoner(vc_enabled=True)
async def process_claim(claim: dict) -> dict:
    result = await app.ai(system="Assess this insurance claim.", user=str(claim))
    # This execution is now signed — the VC proves:
    # - WHO processed it (agent DID)
    # - WHAT input was given (SHA-256 hash)
    # - WHAT output was produced (SHA-256 hash)
    # - WHEN it happened (timestamp)
    return result

# Verify a VC from another agent's execution
result = app.vc_generator.verify_vc(vc_document)
# result["valid"] == True means the signature is valid

# Get the full VC chain for a workflow
chain = app.vc_generator.get_workflow_vc_chain(workflow_id)
import { Agent } from '@agentfield/sdk';

const agent = new Agent({
  nodeId: 'claims-processor',
  version: '1.0.0',
  didEnabled: true, // VCs require DID — 3-tier: platform, node, per-execution
});

agent.reasoner('processClaim', async (ctx) => {
  const result = await ctx.ai(
    `Assess this insurance claim: ${JSON.stringify(ctx.input.claim)}`,
    { system: 'You are an insurance claim assessor.' },
  );
  // VC auto-generated with SHA-256 hashes of input and output
  // Tied to ctx.agentNodeDid — cryptographic proof of who ran this
  ctx.note(`Claim processed, execution ${ctx.executionId}`, ['audit', 'claims']);
  return result;
});
a, err := agent.New(agent.Config{
    NodeID:    "audited-agent",
    Version:   "1.0.0",
    VCEnabled: true, // Ed25519-signed, tied to agent's DID
})
# Get the signed VC for a specific execution
curl http://localhost:8080/api/ui/v1/executions/exec_a1b2c3/vc

# Get the full VC chain for a workflow (every step, topological order)
curl http://localhost:8080/api/ui/v1/workflows/wf_d4e5f6/vc-chain

# Verify all VCs in a workflow at once
curl -X POST http://localhost:8080/api/ui/v1/workflows/wf_d4e5f6/verify-vc

# Submit any VC for verification against the DID registry
curl -X POST http://localhost:8080/api/ui/v1/vc/verify \
  -H "Content-Type: application/json" -d @audit.json

# Offline verification (no network needed)
af vc verify audit.json --issuer-key issuer_pubkey.jwk

What just happened

The example walked from a single execution credential to a full workflow VC chain and then to verification endpoints. That is the production story this page should tell immediately: each run can produce a signed audit artifact you can inspect, store, and verify later without trusting application logs alone.

{
  "execution_id": "exec_a1b2c3",
  "workflow_id": "wf_d4e5f6",
  "status": "succeeded",
  "verification": "offline-capable"
}