Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 3 GitHub source documents. All source documents are searchable here.
Last updated: September 21, 2025
This content is meant to be consumed by AI agents via MCP. Click here to get the MCP configuration.
Note: In rare cases it may contain LLM hallucinations.
For authoritative documentation, please consult the official GLEIF vLEI trainings and the ToIP Glossary.
The state of having verifiable authenticity and documented history/origin through cryptographic proof-of-authorship chains, enabling end-to-end verification of data provenance without relying on trusted intermediaries.
Provenanced refers to data or digital artifacts that possess cryptographically verifiable proof of their authenticity, origin, and transformation history through an unbroken chain of cryptographic attestations. In the KERI/ACDC ecosystem, being "provenanced" means having end-to-end verifiable authenticity that can be validated by any party without requiring trust in intermediaries or centralized authorities.
Formally, a data item D is provenanced if there exists a verifiable chain C = {c₁, c₂, ..., cₙ} where each cᵢ is a cryptographic attestation such that:
c₁ establishes the initial authorship of Dcᵢ₊₁ verifiably references cᵢ through cryptographic bindingC can be verified end-to-end by any third partyProvenanced data in KERI/ACDC systems relies on several cryptographic primitives:
Digital Signatures: All provenance attestations use Ed25519 signatures providing SUF-CMA (Strong Unforgeability under Chosen Message Attack) security properties. Each signature binds:
Self-Addressing Identifiers (SAIDs): Content-addressable identifiers computed using Blake3-256 hash function:
SAID = Base64(Blake3-256(canonical_serialization(data)))
SAIDs provide cryptographic binding between identifiers and content, ensuring that any reference to a SAID commits to the exact content that produced that digest.
Signature Verification Batching: Group multiple signature verifications and use vectorized Ed25519 implementations for 3-5x performance improvement:
# Batch verify signatures
signatures = [acdc.signature for acdc in chain]
public_keys = [get_public_key(acdc.issuer) for acdc in chain]
messages = [acdc.canonical_data for acdc in chain]
results = ed25519_batch_verify(signatures, messages, public_keys)
SAID Computation Caching: Cache SAID computations using content-addressable storage to avoid recomputation:
class SAIDCache:
def __init__(self):
self._cache = {}
def get_said(self, data: bytes) -> str:
if data not in self._cache:
self._cache[data] = base64.encode(blake3.hash(data))
return self._cache[data]
Constant-Time Comparisons: Always use constant-time comparison for SAID verification to prevent timing attacks:
import hmac
def verify_said(computed_said: str, claimed_said: str) -> bool:
return hmac.compare_digest(computed_said, claimed_said)
Key State Validation: Always verify key state is current and not revoked before signature verification:
def verify_with_key_state(acdc, timestamp):
key_state = keri_client.get_key_state_at_time(acdc.issuer, timestamp)
if key_state.revoked:
raise KeyRevokedError(f"Key revoked at {key_state.revocation_time}")
if timestamp < key_state.establishment_time:
raise InvalidTimestampError("Signature predates key establishment")
return ed25519.verify(key_state.public_key, acdc.data, acdc.signature)
Circular Reference Handling: Always maintain visited set during chain traversal to prevent infinite loops:
def traverse_chain(acdc_said, visited=None):
if visited is None:
visited = set()
if acdc_said in visited:
raise CircularReferenceError()
visited.add(acdc_said)
# Continue traversal...
Schema Evolution: Handle schema versioning carefully to maintain backward compatibility:
def validate_with_schema_version(acdc, schema_said):
schema = resolve_schema(schema_said)
# Check for schema compatibility
if not is_compatible_version(schema.version, acdc.schema_version):
raise SchemaIncompatibilityError()
return jsonschema.validate(acdc.data, schema.definition)
Hash Chaining: Provenance chains use cryptographic hash chaining where each attestation includes the SAID of the previous attestation, creating an immutable audit trail:
Attestation_n = {
"d": SAID(Attestation_n),
"i": Controller_AID,
"p": SAID(Attestation_{n-1}), // Previous attestation
"data": transformation_data,
"signature": Ed25519_sign(private_key, canonical_data)
}
Authentic Chained Data Containers implement provenance through several mechanisms:
Issuer Attribution: Every ACDC contains an i field specifying the Issuer's AID, establishing cryptographic control authority through KERI key event logs.
Schema Binding: The s field contains either a SAID reference to an immutable schema or the schema itself, ensuring type safety and structural integrity.
Attribute Provenance: The a field can contain either direct attributes or SAIDs referencing attribute blocks, enabling graduated disclosure while maintaining provenance.
Edge Relationships: The e field enables property graph relationships between ACDCs, creating verifiable provenance chains across multiple data containers.
ACDC Top-Level Structure:
{
"v": "ACDC10JSON00011c_", // Version string
"d": "EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM", // SAID
"u": "0ABghkDaG7OY1wjaDAE0qHcg", // UUID for privacy
"i": "EBkPreYpZfFk66jpf3uFv7vklXKhzBrAqjsKAn2EDIPM", // Issuer AID
"ri": "ECmRy7xMwsxUelUauaXtMxTfPAMPAI6FkekeolOjkggt", // Registry ID
"s": "ED6jrVPTzlSkUPqGGeIZ8a8FWS7a6s4reAXRZOkogZ2A", // Schema SAID
"a": "EEveY4-9XgOcLxUderzwLIr9Bf7V_NHwY1lkFrn9y2PY", // Attributes
"e": "EFH3dCdoFOLe71iheqcywJcnjtJtQIYPvAu6DZIl3MOA", // Edges
"r": "EG71iheqcywJcnjtJtQIYPvAu6DZIl3MORH3dCdoFOLB" // Rules
}
Provenance Chain Structure:
{
"sources": {
"EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM": {
"weight": 1.0,
"rules": ["EFrules_SAID_here"]
}
},
"transformation": {
"type": "aggregation",
"algorithm": "weighted_sum",
"parameters": {...}
},
"destination": "ENewDataSAID"
}
r sectionsController -> KERIA Agent: Create ACDC with provenance
KERIA Agent -> Schema Registry: Resolve schema SAID
KERIA Agent -> Provenance Store: Retrieve source ACDCs
KERIA Agent -> Crypto Module: Generate signatures
KERIA Agent -> ACDC Store: Persist new ACDC
KERIA Agent -> Registry: Update transaction log
STATES: [UNVERIFIED, VALIDATING, VERIFIED, INVALID]
UNVERIFIED --[start_validation]--> VALIDATING
VALIDATING --[all_checks_pass]--> VERIFIED
VALIDATING --[any_check_fails]--> INVALID
VERIFIED --[revocation_detected]--> INVALID
Verification Endpoint:
POST /v1/provenance/verify
Content-Type: application/json
{
"acdc": "EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM",
"depth": 10, // Maximum chain depth to verify
"include_revoked": false
}
Response:
{
"verified": true,
"chain_length": 5,
"verification_time": "2024-01-15T10:30:00Z",
"trust_score": 0.95,
"warnings": []
}
Chain Traversal Endpoint:
GET /v1/provenance/chain/{acdc_said}?depth=5&format=dag
Response:
{
"root": "EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM",
"nodes": [...],
"edges": [...],
"metadata": {
"total_nodes": 12,
"max_depth": 5,
"verification_status": "verified"
}
}
Verification Complexity: O(n × m) where n is chain length and m is average signature verification time (~0.1ms for Ed25519)
Storage Overhead: Each provenance link adds approximately 200-500 bytes depending on metadata richness
Network Overhead: Provenance verification requires fetching all referenced ACDCs, potentially causing O(n) network requests for chain length n
Caching Strategy: Implement LRU cache for verified provenance chains with TTL based on credential validity periods
Provenance verification depends critically on KERI's key event logs (KELs) to establish current key state for signature verification:
def verify_provenance_signature(acdc, signature, issuer_aid):
# Get current key state from KERI
key_state = keri_client.get_key_state(issuer_aid)
# Verify signature against current public key
return ed25519.verify(
public_key=key_state.current_public_key,
message=canonical_serialize(acdc),
signature=signature
)
All provenance data uses CESR (Composable Event Streaming Representation) for consistent encoding:
ACDC_CESR = version_string + cesr_encode(acdc_data) + cesr_encode(signatures)
Provenance chains integrate with Public Transaction Event Logs (PTEL) for revocation checking:
def check_revocation_status(acdc_said, registry_id):
tel_events = ptel_client.get_events(registry_id)
for event in tel_events:
if event.type == 'revoke' and acdc_said in event.revoked_credentials:
return True
return False
Provenance chains must detect and handle circular references:
def detect_cycles(acdc_said, visited=None):
if visited is None:
visited = set()
if acdc_said in visited:
raise ProvenanceCycleError(f"Circular reference detected: {acdc_said}")
visited.add(acdc_said)
acdc = resolve_acdc(acdc_said)
for source_said in acdc.get_source_saids():
detect_cycles(source_said, visited.copy())
When complete provenance chains are unavailable:
def verify_partial_chain(acdc_said, max_depth=10):
verified_depth = 0
current_said = acdc_said
while verified_depth < max_depth:
try:
acdc = resolve_acdc(current_said)
if not verify_acdc_signature(acdc):
break
verified_depth += 1
current_said = acdc.get_parent_said()
except ACDCNotFoundError:
break
return {
'verified_depth': verified_depth,
'complete': verified_depth == max_depth,
'trust_score': calculate_trust_score(verified_depth)
}
Provenance verification must handle historical key states:
def verify_historical_signature(acdc, timestamp):
issuer_aid = acdc.issuer
historical_keys = keri_client.get_key_state_at_time(issuer_aid, timestamp)
for key_state in historical_keys:
if ed25519.verify(key_state.public_key, acdc.canonical_data, acdc.signature):
return True
return False
Provenance implementation must comply with:
All provenance data must validate against JSON Schema Draft 2020-12:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"d": {"type": "string", "pattern": "^E[A-Za-z0-9_-]{43}$"},
"i": {"type": "string", "pattern": "^E[A-Za-z0-9_-]{43}$"},
"sources": {
"type": "object",
"patternProperties": {
"^E[A-Za-z0-9_-]{43}$": {
"type": "object",
"properties": {
"weight": {"type": "number", "minimum": 0, "maximum": 1}
}
}
}
}
},
"required": ["d", "i"]
}
Horizontal Scaling: Distribute provenance verification across multiple worker nodes using consistent hashing on ACDC SAIDs
Caching Architecture: Implement multi-tier caching:
Database Sharding: Partition provenance data by SAID prefix to distribute load
Key Metrics:
Alerting Thresholds:
DoS Protection: Implement rate limiting and maximum chain depth limits to prevent resource exhaustion attacks
Privacy Protection: Use selective disclosure mechanisms to minimize information leakage during provenance verification
Key Compromise Response: Implement automated revocation checking and key rotation detection
Audit Logging: Maintain immutable logs of all provenance verification attempts for compliance and forensics
Property-Based Testing: Use hypothesis to generate test cases for provenance chains:
from hypothesis import given, strategies as st
@given(st.lists(st.text(), min_size=1, max_size=10))
def test_provenance_chain_verification(chain_data):
# Generate valid provenance chain
chain = create_test_chain(chain_data)
# Verify chain
result = verify_provenance_chain(chain[0].said)
assert result.verified
assert len(result.chain) == len(chain_data)
Fuzzing: Test with malformed provenance data to ensure robust error handling:
def test_malformed_provenance_handling():
malformed_cases = [
{"d": "invalid_said"}, # Invalid SAID format
{"i": ""}, # Empty issuer
{"sources": {"circular": "self"}}, # Circular reference
]
for case in malformed_cases:
with pytest.raises(ProvenanceValidationError):
verify_provenance_data(case)