Version: 2.0.0
Protocol ID: fides-v2.0.0
Status: Draft
- Overview
- Identity
- AgentCard
- Capabilities
- Trust Graph
- Delegation
- Policy Engine
- Evidence Ledger
- Runtime Attestation
- Guard Decision Engine
- Discovery
- Kill Switch
- Registry Service
- Relay Service
- Error Taxonomy
FIDES v2 is a decentralized trust fabric for AI agents. It provides:
- Identity: Cryptographic DIDs with AgentCard v2 descriptors
- Trust Graph: Weighted, capability-specific reputation with transitive trust
- Policy Engine: Deterministic rule evaluation with pre-execution guards
- Evidence Ledger: Hash-chained, Merkle-rooted event log with privacy levels
- Runtime Attestation: TEE-based execution environment verification
- Delegation: Capability delegation with constraints and session grants
- Discovery: Multi-provider agent discovery (well-known, registry, DHT, relay)
- Kill Switch: Emergency capability/agent/global shutdown
All protocol objects are JSON-serializable and signed using canonical JSON encoding (recursive key sorting, no whitespace).
PROTOCOL_VERSION = "fides-v2.0.0"
did:fides:<identifier>
Where <identifier> is a unique string (typically a public key fingerprint or UUID).
interface Identity {
did: string
type: 'agent' | 'publisher' | 'principal' | 'trust-anchor'
publicKey: Uint8Array // Ed25519 public key
metadata: Record<string, unknown>
createdAt: string // ISO 8601
}All signed objects use canonical JSON encoding:
interface SignedObject<T> {
payload: T
signature: string // hex-encoded Ed25519 signature
signerDid: string
algorithm: 'ed25519'
}Canonical JSON rules:
- Object keys sorted recursively (lexicographic)
- No whitespace
- Unicode characters escaped as
\uXXXX - Numbers in canonical form (no trailing zeros)
interface AgentCard {
id: string
did: string
name: string
description: string
version: string
publisher?: string
homepage?: string
capabilities: CapabilityDescriptor[]
protocols: string[] // e.g., ["mcp", "a2a", "x402"]
endpoints: AgentEndpoint[]
security: SecurityProfile
metadata: Record<string, unknown>
}
interface AgentEndpoint {
url: string
protocol: string
capabilities: string[] // capability IDs served at this endpoint
}
interface SecurityProfile {
authentication: ('api-key' | 'oauth2' | 'mtls' | 'did-auth')[]
encryption: ('tls1.3' | 'age')[]
attestation?: 'tee-required' | 'tee-optional' | 'none'
}AgentCards are published at:
https://<agent-domain>/.well-known/fides-agent-card.json
interface CapabilityDescriptor {
id: string // e.g., "email:send", "web:search", "payment:charge"
name: string
description: string
riskLevel: 'critical' | 'high' | 'medium' | 'low'
parameters: CapabilityParameter[]
output: CapabilityOutput
constraints: CapabilityConstraint[]
metadata: Record<string, unknown>
}
interface CapabilityParameter {
name: string
type: 'string' | 'number' | 'boolean' | 'object' | 'array'
required: boolean
description: string
}
interface CapabilityOutput {
type: string
description: string
}
interface CapabilityConstraint {
type: 'rate-limit' | 'spend-limit' | 'scope-limit' | 'time-limit'
value: unknown
}function classifyCapabilityRisk(capability: CapabilityDescriptor): {
level: 'critical' | 'high' | 'medium' | 'low'
factors: string[]
}Risk factors:
- Critical: Financial operations, data deletion, system access
- High: Data modification, external communication, PII access
- Medium: Data read, computation, internal operations
- Low: Status queries, health checks, metadata access
interface TrustEdge {
sourceDid: string
targetDid: string
trustLevel: number // 0-100
capabilityId?: string // null = general trust
context?: string
attestation: Record<string, unknown>
signature: string
createdAt: string
expiresAt?: string
revokedAt?: string
}Algorithm (spec-compliant):
- Direct trust (depth 1): weight 1.0
- Transitive depth 2: weight 0.5
- Transitive depth 3+: weight 0.25
- Final score = weighted sum / total paths, capped at 1.0
interface CapabilityScore {
did: string
capabilityId: string
score: number // 0-1
invocationCount: number
incidentCount: number
lastComputed: string
}Score formula:
score = base_trust × (1 - incident_penalty) × success_rate_factor
| Method | Path | Description |
|---|---|---|
| POST | /v1/trust |
Create trust edge |
| GET | /v1/trust/:did/score |
Get reputation score |
| GET | /v1/trust/:from/:to |
Get trust path |
| GET | /v1/trust/:did/capability/:capId |
Get capability score |
| POST | /v1/trust/:did/capability/:capId/invoke |
Record invocation |
| POST | /v1/incidents |
Record incident |
| GET | /v1/incidents/:did |
Get incidents |
interface DelegationToken {
id: string
delegator: string // DID
delegatee: string // DID
capabilities: string[]
constraints: DelegationConstraint
issuedAt: string
expiresAt: string
nonce: string
audience?: string[]
signature: string
}
interface DelegationConstraint {
maxActions?: number
maxSpend?: string
allowedContexts?: string[]
forbiddenContexts?: string[]
}interface SessionGrant {
id: string
token: DelegationToken
sessionKey: string // Ed25519 key pair for session
expiresAt: string
boundTo?: string // target DID
}A DelegationToken is valid if:
- All required fields present
- Not expired
- Signature verified against delegator's public key
- Delegatee DID matches the requesting agent
interface PolicyBundle {
id: string
version: string
rules: PolicyRule[]
defaultAction: 'allow' | 'deny' | 'approve-required'
}
interface PolicyRule {
id: string
condition: PolicyExpression
action: 'allow' | 'deny' | 'approve-required' | 'dry-run'
explanation: string
}| Operator | Description |
|---|---|
eq |
Field equals value |
neq |
Field not equals value |
lt |
Field less than value |
lte |
Field less than or equal |
gt |
Field greater than value |
gte |
Field greater than or equal |
in |
Field in array value |
all |
All values in array field |
any |
Any value in array field |
Guards run before policy evaluation:
- allow: Continue
- warn: Continue but flag for dry-run
- block: Immediate deny
interface EvidenceEvent {
id: string
type: string
timestamp: string
actor: string
action: string
target?: string
payload: unknown
privacy: EvidencePrivacy
prevHash: string
hash: string
signature: string
}
interface EvidencePrivacy {
level: 'public' | 'private' | 'redacted' | 'hash_only'
redactionKey?: string
}Each event's hash is computed over the canonical JSON of the event (excluding the hash field itself), with prevHash pointing to the previous event's hash.
The Merkle root is computed over all event hashes in the chain using SHA-256:
- Leaf nodes: event hashes
- Internal nodes: SHA-256(left + right)
- Odd nodes at any level: promoted to next level
| Level | Payload Visibility |
|---|---|
public |
Full payload visible |
private |
Payload nullified on export |
redacted |
Payload replaced with [REDACTED] |
hash_only |
Only hash verifiable, payload nullified |
interface RuntimeAttestation {
id: string
agentDid: string
provider: string // e.g., "aws-nitro", "intel-sgx", "amd-sev"
measurement: string // TEE measurement hash
timestamp: string
expiresAt: string
evidence: unknown // Provider-specific evidence
signature: string
}interface TEEAdapter {
readonly provider: string
attest(agentDid: string): Promise<RuntimeAttestation>
verify(attestation: RuntimeAttestation): Promise<boolean>
}- Kill switch check → immediate deny if engaged
- Attestation check → deny if invalid/expired and required
- Evidence chain → deny if hash chain broken
- Incident rate → deny if ≥5 incidents in 24h
- Trust score → factor into decision (low score = warn)
- Pre-execution pipeline → block/warn/allow
- Policy evaluation → final decision
interface GuardRequest {
agentDid: string
capabilityId: string
policy: PolicyBundle
context: Record<string, unknown>
trust: TrustContext
}
interface TrustContext {
reputationScore: number
capabilityScore?: number
attestationValid: boolean
attestation?: RuntimeAttestation
evidenceChain?: EvidenceChain
killSwitchEngaged: boolean
recentIncidents: number
}interface GuardDecision {
decision: 'allow' | 'deny' | 'approve-required' | 'dry-run'
explanation: string
factors: Array<{
source: string
factor: string
weight: number
description: string
}>
policyResult?: PolicyResult
}interface DiscoveryProvider {
readonly name: string
readonly priority: number
discover(did: string): Promise<AgentCard | null>
search(query: DiscoveryQuery): Promise<AgentCard[]>
}| Provider | Priority | Description |
|---|---|---|
well-known |
100 | .well-known/fides-agent-card.json |
local |
90 | mDNS/local network discovery |
registry |
80 | Central registry service |
relay |
70 | Relay network discovery |
dht |
60 | Distributed hash table (libp2p) |
The DiscoveryOrchestrator queries providers in priority order, returning the first successful result. Multiple providers can be queried in parallel for search operations.
interface KillSwitchTarget {
type: 'global' | 'agent' | 'capability' | 'principal'
did?: string
id?: string
}- Global kill overrides all
- Agent kill overrides capability kills for that agent
- Capability kill affects all agents for that capability
Central registry for agent registration and capability publishing.
- Public: Anyone can register
- Private: Requires approval
| Method | Path | Description |
|---|---|---|
| POST | /v1/register |
Register agent |
| GET | /v1/agents/:did |
Get agent info |
| GET | /v1/search |
Search agents |
| POST | /v1/capabilities |
Publish capability |
Message relay for agents behind NAT/firewalls or with dynamic addresses. Relay deployments can use process-local memory for lightweight development or a schema-versioned file snapshot for durable production restarts.
| Method | Path | Description |
|---|---|---|
| POST | /v1/relay |
Relay message |
| GET | /v1/relay/:id |
Get message status |
All FIDES errors use the TrustError class with category classification:
| Category | Code Prefix | Description |
|---|---|---|
identity |
IDENTITY_* |
DID resolution, key management |
trust |
TRUST_* |
Trust edge, scoring |
policy |
POLICY_* |
Policy evaluation |
delegation |
DELEGATION_* |
Token validation |
evidence |
EVIDENCE_* |
Chain integrity |
discovery |
DISCOVERY_* |
Provider failures |
attestation |
ATTESTATION_* |
TEE verification |
network |
NETWORK_* |
Connectivity |
protocol |
PROTOCOL_* |
Version mismatch |
authorization |
AUTHZ_* |
Permission denied |
runtime |
RUNTIME_* |
Kill switch, execution |
internal |
INTERNAL_* |
System errors |
All FIDES v2 implementations MUST include the protocol version in:
- HTTP headers:
X-Fides-Protocol: fides-v2.0.0 - AgentCard:
protocolsarray - Signed objects: implicit via canonical JSON format
Implementations SHOULD reject requests with incompatible protocol versions.
v1 → v2 migration notes:
- Trust decay formula changed:
direct*0.7 + transitive*0.3→direct*1.0 + depth2*0.5 + depth3+*0.25 - AgentCard v2 adds
capabilities,security,endpoints - Policy engine adds pre-execution pipeline
- Evidence ledger adds Merkle root computation
- New packages:
@fides/guard,@fides/discovery,@fides/runtime