Learning objectives
By the end of this module, you will be able to:
- Run the maintained Python verification API and handle all 18 outcomes
- Distinguish signature integrity, configured trust, and attestation claim quality
- Configure online or revocation-list (CRL) checking and handle its failure safely
- Describe the additional evidence required for audit or compliance claims
6.1 — Verification in practice
Verification takes the bundle and a description of where you intend to use it: which model, for what purpose, in which environment, for which audience and region. The orchestrator checks the bundle's declared scope against that description, along with its signatures, trust anchors, time window and revocation status, and returns one outcome.
from vcp import Orchestrator, VerificationContext, VerificationResult
verification_context = VerificationContext(
trust_config=trust,
model_family="example-model-*",
purpose="customer-support",
environment="production",
audience="adult",
region="GB",
)
result = Orchestrator(trust).verify(
bundle,
context=verification_context,
)
if result is not VerificationResult.VALID:
raise PermissionError("VCP verification failed: " + result.name) The SDK does not promise that verification finishes within any fixed time, and no outcome means "timed out". Fetching bundles and checking revocation both go over the network, so put your own timeout around that work at the application boundary, and decide and document what your application does when it fires.
6.2 — The 18 verification outcomes
| Outcome | SDK category | Meaning |
|---|---|---|
VALID | Success | All configured verification checks passed |
SIZE_EXCEEDED | Security | Manifest or content exceeded the accepted byte bound |
INVALID_SCHEMA | Configuration | Bundle shape or types were malformed |
UNTRUSTED_ISSUER | Configuration | No valid issuer trust anchor matched |
INVALID_SIGNATURE | Security | Issuer signature did not verify |
UNTRUSTED_AUDITOR | Configuration | No valid auditor trust anchor matched |
INVALID_ATTESTATION | Security | Attestation signature or claim structure was invalid, or the
claim type was not INJECTION_SAFE or FULL_AUDIT |
HASH_MISMATCH | Security | Canonical content did not match the manifest hash |
NOT_YET_VALID | Temporal | Current time is earlier than the bundle's not-before time
(nbf) |
EXPIRED | Temporal | Current time is past the bundle's expiry time (exp) |
FUTURE_TIMESTAMP | Security | The issued-at time (iat) is later than now by more
than the allowed clock skew |
REPLAY_DETECTED | Security | This bundle's unique ID (jti) was already in the
bounded replay cache, so this exact bundle has been seen before |
TOKEN_MISMATCH | Security | Declared token information did not match |
BUDGET_EXCEEDED | Configuration | Bundle budget exceeded the configured context allowance |
SCOPE_MISMATCH | Configuration | Model, purpose, environment, audience, or region did not match scope |
REVOKED | Security | Configured revocation evidence marks the bundle revoked |
FETCH_FAILED | Transient | A required bounded network retrieval failed. Reserved; SDK 4.2.0 does not return it |
REVOCATION_UNAVAILABLE | Transient | No configured revocation source could establish a status, so the bundle was rejected (fail closed) |
Only VALID lets the application continue to local
enforcement. The category tells you what a failure means. A transient
failure, such as an unreachable revocation service, may pass on a later
attempt. A temporal failure means the bundle is outside its valid time
window. A configuration failure means the bundle's shape, issuer,
auditor, scope or budget does not match what your deployment accepts. A
security failure, such as a bad signature, altered content, a replayed
bundle or a revocation, will not fix itself, so never retry it as if it
were transient.
6.3 — Safety attestation
The issuer signature binds bundle bytes to an issuer key. Every bundle
must also carry a safety-attestation claim signed by a separately trusted
auditor. VCP-SDK 4.2.0 recognizes the four claim types below, but only INJECTION_SAFE and FULL_AUDIT pass
verification, because only they cover the risk of placing the bundle in
a model's prompt. A bundle attested as CONTENT_SAFE or COMPETENCE_CALIBRATION fails with INVALID_ATTESTATION:
| Type | Claim |
|---|---|
INJECTION_SAFE | The auditor asserts the defined injection-safety review was completed |
CONTENT_SAFE | The auditor asserts the defined content-safety review was completed |
FULL_AUDIT | The auditor asserts the organization's defined full-audit evidence exists |
COMPETENCE_CALIBRATION | The auditor asserts the defined competence-calibration review was completed |
A valid signature shows that the bytes have not changed since signing (integrity) and that a key you configured as trusted signed them (provenance). On its own, it does not establish that the review method was adequate, lawful, complete, or correctly described. Your governance process must define the evidence required for each claim.
6.4 — Revocation
A manifest may name an HTTPS endpoint (check_uri) that
answers in real time whether this one bundle has been withdrawn, and a
certificate revocation list, or CRL (crl_uri), a published
list of every withdrawn bundle ID. The SDK tries the endpoint first and
falls back to the list. It validates schemes, ports, credentials,
fragments, DNS results, resolved addresses, response size, JSON shape,
issuer binding, and freshness before accepting network evidence. Those
checks keep a hostile manifest from steering the checker toward
addresses inside your own network or feeding it a stale answer.
"revocation": {
"check_uri": "https://status.example.org/vcp/revocation",
"crl_uri": "https://status.example.org/vcp/crl.json"
} If a manifest declares no revocation URI, both SDKs treat the bundle as not revoked; the Python SDK also logs a warning. High-assurance deployments that require revocation must add that rule themselves, in application policy or a custom enforcement plugin, and reject any bundle that names no approved revocation mechanism.
If no configured endpoint can establish a status, the orchestrator
returns REVOCATION_UNAVAILABLE and rejects the bundle. A
confirmed revocation returns REVOKED. An unavailable status
may clear on a retry within your deadline. Decide in advance, for each
kind of action your application takes, whether to block or to continue
in a constrained mode that does not use this bundle.
6.5 — What verification proves
- The accepted bytes matched their declared canonical hash
- The signatures verified under the configured algorithms and keys
- The issuer and auditor matched current trust anchors
- Configured temporal, replay, budget, scope, and revocation checks passed
Verification does not prove that a model followed the content, a tool action was safe, a reviewer exercised sound judgment, the system complied with law, or downstream logs are complete. Those need separate runtime, human, legal, and operational evidence.
Exercise
Run examples/python/02_verify_bundle.py. Then test hash
mismatch, missing audience, future timestamp, revoked jti,
and unreachable CRL behavior. Confirm that no failure path formats or
injects the bundle.
See it in action
The Marta demo shows how declared personal state changes a pre-scripted reply. It verifies no bundles, so treat it as an explanatory scenario, not cryptographic verification evidence.