Getting Started¶
This guide walks through creating, signing, and verifying an Agent Manifest in under 15 minutes. It covers Level 0 (software-only signing) and Level 1 (TPM-attested).
Prerequisites¶
- Python 3.11 or later
- For Level 1: a Linux host with TPM 2.0 (
tpm2-toolsinstalled), an AMD SEV-SNP VM, or an Intel TDX VM
Installation¶
# Core SDK
pip install agent-manifest
# With CLI
pip install "agent-manifest[cli]"
# With post-quantum profile
pip install "agent-manifest[pq]"
Level 0 - Software-only signing¶
Level 0 is suitable for development, staging, and non-regulated environments. No hardware required.
Step 1: Generate a signing key¶
Or in Python:
from agent_manifest import generate_ed25519
keypair = generate_ed25519()
# Store keypair.private_hex and keypair.public_hex securely
Step 2: Build the manifest¶
from agent_manifest import (
Manifest, ArtifactBindings,
SystemPromptBinding, PolicyBundleBinding,
ToolManifestBinding, ModelIdentityBinding,
CryptoProfile, DeploymentType, EnforcementMode, ModelAttestationType,
PolicyLanguage,
)
from agent_manifest._types import HashValue, ManifestId
from datetime import datetime, timedelta, timezone
import hashlib
now = datetime.now(timezone.utc)
# Hash your actual artifacts
system_prompt_text = "You are a document summarization assistant..."
prompt_hash = "sha256:" + hashlib.sha256(
system_prompt_text.encode("utf-8")
).hexdigest()
manifest = Manifest(
manifest_id=ManifestId("019236ab-cdef-7000-8000-000000000001"),
agent_id="spiffe://trust.acme.co/agent/doc-summarizer/prod",
issued_at=now,
expires_at=now + timedelta(days=90),
issuer="spiffe://trust.acme.co/signing-authority",
crypto_profile=CryptoProfile.standard,
artifacts=ArtifactBindings(
system_prompt=SystemPromptBinding(
hash=HashValue(prompt_hash),
hash_algorithm="SHA-256",
version="1.0.0",
classification="internal",
bound_at=now,
),
policy_bundle=PolicyBundleBinding(
hash=HashValue("sha256:" + "b" * 64),
policy_language=PolicyLanguage.cedar,
version="1.0.0",
enforcement_mode=EnforcementMode.enforce,
bound_at=now,
),
model_identity=ModelIdentityBinding(
provider="anthropic",
model_id="claude-haiku-4-5-20251001",
version="20251001",
deployment_type=DeploymentType.api,
model_attestation_type=ModelAttestationType.provider_asserted,
bound_at=now,
),
),
)
Step 3: Sign the manifest¶
from agent_manifest import Ed25519Signer, generate_ed25519
keypair = generate_ed25519()
signer = Ed25519Signer(keypair)
manifest_dict = manifest.model_dump(mode="json", by_alias=True)
sig_block = signer.sign(manifest_dict)
manifest_dict["signature"] = sig_block
print(sig_block["algorithm"]) # Ed25519
Or with the CLI:
manifest create my-agent-config.json -o draft.json
manifest sign draft.json --key keys/private.hex -o signed.json
Step 4: Verify¶
from agent_manifest._verify import verify_manifest, VerificationContext, RevocationStore
# Fail-closed: VALID requires the issuer's key in trusted_keys. Without
# trusted keys the result is UNVERIFIABLE - never VALID.
result = verify_manifest(
manifest_dict,
VerificationContext(
system_prompt_hash=prompt_hash,
policy_bundle_hash="sha256:" + "b" * 64,
trusted_keys={keypair.key_id: keypair.public_b64url()},
),
RevocationStore(),
)
print(result.result) # VALID
Or with the CLI:
Without --public-key, signed manifests fail closed as UNVERIFIABLE because the CLI has no trusted issuer key to authenticate the signature. The CLI --public-key option accepts the raw Ed25519 public key generated by manifest keygen.
Level 1 - TPM attestation¶
Level 1 adds hardware attestation, which binds the manifest hash to a TEE measurement that cannot be forged by the operator. Required for EU AI Act Art. 15 (cybersecurity) and enterprise production deployments.
Prerequisites¶
On Ubuntu/Debian:
On AWS: Nitro Enclaves with aws-nitro-enclaves-sdk-python installed.
Attest the signed manifest¶
from agent_manifest._auto_provider import select_provider
# Auto-selects: OPAQUE -> SEV-SNP -> TDX -> TPM -> Software
provider = select_provider(level=1)
provider.extend_manifest_hash(manifest_dict)
report = provider.get_attestation_report()
manifest_dict["attestation"] = {
"tee_type": report.platform, # "tpm" | "amd-sev-snp" | "intel-tdx" | "opaque"
"manifest_hash_in_report": True,
"report_uri": report.report_uri,
"bound_at": now.isoformat(),
}
Or with the CLI:
manifest attest signed.json --provider auto --level 1 -o attested.json
manifest verify attested.json --public-key keys/public.hex
The verification result for a Level 1 manifest includes attestation_verified: true when the TEE measurement matches the manifest hash.
Revocation¶
When an artifact changes (new model version, policy update, system prompt revision), revoke the old manifest and issue a new one:
manifest revoke <manifest-id> \
--reason "policy bundle updated to v1.1.0" \
--revoked-by [email protected]
In Python:
from agent_manifest._verify import RevocationStore
store = RevocationStore()
store.revoke(
manifest_id="019236ab-cdef-7000-8000-000000000001",
reason="policy bundle updated to v1.1.0",
revoked_by="[email protected]",
)
Next steps¶
- Read the full specification
- Browse the examples for complete manifest JSON for each conformance level
- For hardware attestation setup on Azure, AWS, or GCP, see the platform-specific notes in Section 3.3.1 of the spec
- For EU AI Act HITL compliance, see Section 9.1 and the Level 2 example in
examples/ - For post-quantum signing, install
agent-manifest[pq]and setcrypto_profile=CryptoProfile.post_quantum