Learning Objectives
By the end of this module, you will be able to:
- Choose between gateway, middleware, and embedded verification
- Pass an explicit verification result into local enforcement
- Compose multiple verified constitutions without bypassing trust checks
- Define degraded operation from system risk, rather than from convenience
7.1 — Integration Patterns
The reference SDK is a local library. It does not require a hosted decision service.
Pattern A: Gateway Boundary
A gateway verifies bundles and applies policy before a request reaches a model provider. This centralises trust configuration and audit controls, but the gateway becomes a security and availability dependency.
Application
→ VCP gateway: load, verify, enforce, minimise
→ model provider adapter
→ response and audit evidence Pattern B: Application Middleware
Middleware works well when one service owns the request boundary. The
example below assumes that bundle_repository and trust are application-owned dependencies:
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from vcp import (
Orchestrator,
PDPEnforcer,
RefusalBoundaryPlugin,
VerificationResult,
)
app = FastAPI()
enforcer = PDPEnforcer(fail_closed=True)
enforcer.register(RefusalBoundaryPlugin())
@app.middleware("http")
async def vcp_middleware(request: Request, call_next):
if request.method != "POST":
return await call_next(request)
bundle = bundle_repository.for_request(request)
verification = Orchestrator(trust).verify(bundle)
if verification is not VerificationResult.VALID:
return JSONResponse(
status_code=403,
content={"error": "VCP verification failed"},
)
decision = enforcer.evaluate(
bundle,
content=(await request.body()).decode("utf-8"),
verification_result=verification,
)
if not decision.allowed:
return JSONResponse(
status_code=403,
content={"error": "VCP policy blocked request"},
)
request.state.verified_vcp_bundle = bundle
return await call_next(request) Bound request bodies before decoding, avoid returning sensitive policy evidence to callers, and ensure downstream handlers cannot replace the verified bundle with fresh untrusted input.
Pattern C: Embedded Library
Call the SDK directly at the point where a model prompt or tool action is authorised. This reduces infrastructure, while requiring every call site to preserve the same verification and enforcement sequence.
7.2 — Multi-Constitution Composition
Verify each bundle independently before composition. Composition semantics never transfer trust from one bundle to another:
from vcp import (
Orchestrator,
VerificationResult,
format_multi_constitution_injection,
)
bundles = [organisation_bundle, domain_bundle]
orchestrator = Orchestrator(trust)
for bundle in bundles:
result = orchestrator.verify(bundle)
if result is not VerificationResult.VALID:
raise PermissionError("Constitution set is not fully verified")
system_context = format_multi_constitution_injection(bundles) Use the SDK's Composer when you need explicit CSM-1 semantic conflict
handling. Test ordering, precedence, strictness, and conflict behavior with
your own policy examples.
7.3 — Degraded Operation
Choose a strategy per action class and document it before an outage:
| Strategy | Use | Required evidence |
|---|---|---|
| Fail closed | Safety-critical, financial, medical, or irreversible actions | Deny when bundle, trust, revocation, scope, or verification evidence is unavailable |
| Verified cached bundle | Bounded offline operation | Previously verified bytes, valid time window, local trust state, replay controls, and an explicit maximum age |
| Restricted fallback | Low-risk availability paths | A separately reviewed capability subset with no high-impact actions |
| Audit-only mode | Observation or staged rollout | Clear user and operator indication that enforcement is not active |
A generic fail-open path is unsuitable for a control whose absence creates the very risk it is meant to limit.
7.4 — Error Handling
from vcp import VerificationError
try:
orchestrator.verify_or_raise(bundle)
except VerificationError as error:
logger.warning(
"VCP verification rejected bundle",
extra={"code": error.result.name},
)
return deny_response("Value verification unavailable") Do not log raw bundle content, context, keys, or user identifiers in the error path.
7.5 — Performance and Capacity
- Benchmark verification, revocation lookup, context encoding, and provider latency separately
- Bound bundle size and context growth before cryptographic work
- Use the SDK's bounded replay and revocation caches
- Cache only exact verified bytes with trust and freshness metadata
- Measure your candidate on representative hardware; do not rely on an undocumented universal latency claim
Exercise
Implement the middleware boundary with a deliberately invalid signature and a simulated unavailable revocation endpoint. Confirm that the chosen action class follows its documented degraded-operation policy.
See It in Action
The Ren demo illustrates context handoff between agents. It is a scenario demonstration, not a benchmark or third-party conformance result.