Skip to content

RFC-012: Artifact Lifecycle Protocol (ALP) — 6. Provenance Chain

AIGP SpecificationRFC-012: Artifact Lifecycle Protocol (ALP) › 6. Provenance Chain

← 5. Protocol Messages · Section index · 7. Approval Rules →

6. Provenance Chain

Every artifact MUST maintain a complete provenance chain from context sources through execution outcome. The provenance chain is the audit trail that answers: who asked for this, what informed it, who approved it, and what happened when it ran?

6.1 Provenance Record

{
"provenance_id": "prov-art-20260504-001",
"artifact_id": "art-20260504-001",
"chain": [
{
"step": 1,
"type": "CONTEXT_ASSEMBLY",
"timestamp": "2026-05-04T09:55:00Z",
"acp_context_id": "ctx-1714800000000",
"sources": [
{"provider": "analytics-service", "context_type": "conversion_state", "fields_fetched": 8},
{"provider": "governance-server", "context_type": "governance_posture", "fields_fetched": 5},
{"provider": "identity-service", "context_type": "user_entitlements", "fields_fetched": 6}
]
},
{
"step": 2,
"type": "AI_INVOCATION",
"timestamp": "2026-05-04T09:56:00Z",
"aigp_request_id": "req-1714800000000",
"model_id": "us.anthropic.claude-opus-4-7",
"use_case": "artifact_generation",
"input_tokens": 4200,
"output_tokens": 1800
},
{
"step": 3,
"type": "ARTIFACT_CREATED",
"timestamp": "2026-05-04T10:00:00Z",
"artifact_id": "art-20260504-001",
"content_hash": "sha256:a1b2c3d4e5f6...",
"agent_id": "agent-remediation-v1"
},
{
"step": 4,
"type": "APPROVAL",
"timestamp": "2026-05-04T10:30:00Z",
"approver": "owner@ai-governance-protocol.org",
"approver_type": "HUMAN",
"reviewed_hash": "sha256:a1b2c3d4e5f6..."
},
{
"step": 5,
"type": "EXECUTION",
"timestamp": "2026-05-04T11:00:00Z",
"run_id": "run-20260504-001",
"environment": "dev",
"exit_code": 0,
"duration_ms": 150000
},
{
"step": 6,
"type": "OUTCOME",
"timestamp": "2026-05-04T11:02:30Z",
"state": "COMPLETED",
"output_summary": "12 policies remediated successfully",
"final_hash": "sha256:c3d4e5f6g7h8..."
}
]
}

6.2 Provenance Integrity

The provenance chain MUST be hash-linked. Each step’s hash includes the previous step’s hash, forming an immutable chain:

import hashlib
import json
def compute_step_hash(step: dict, previous_hash: str) -> str:
"""Compute hash for a provenance step, chaining to previous."""
step_bytes = json.dumps(step, sort_keys=True).encode()
combined = f"{previous_hash}\n{step_bytes.hex()}"
return f"sha256:{hashlib.sha256(combined.encode()).hexdigest()}"

If any step in the chain is modified, all subsequent hashes become invalid, and the provenance chain fails verification.

6.3 Provenance Verification

def verify_provenance_chain(provenance: dict) -> tuple[bool, str]:
"""Verify the integrity of a provenance chain."""
previous_hash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"
for step in provenance["chain"]:
expected_hash = compute_step_hash(step, previous_hash)
if step.get("step_hash") != expected_hash:
return False, f"Chain broken at step {step['step']}: expected {expected_hash}, got {step.get('step_hash')}"
previous_hash = expected_hash
return True, "Provenance chain verified"

← 5. Protocol Messages · Section index · 7. Approval Rules →