integrations/verra FastAPI wrapper on any public HTTPS host — TrueFoundry, Docker, Render, ECS, Cloud Run, or on-prem. The gateway calls it at llm_input / llm_output via the Custom Guardrail contract; the wrapper forwards traffic to Verra and returns verdict JSON on HTTP 200.
Source repository:
truefoundry/integrations-custom-guardrails/integrations/verra/. It contains the Dockerfile, deploy script, and tests referenced below.What is Verra?
Verra is a managed AI governance product for regulated industries (healthcare, finance, insurance). Every request gets scanned by Verra’s detection pipeline — prompt injection, jailbreak, PII, secrets, exfiltration, policy violations — and recorded in a SOC 2 / HIPAA / EU AI Act compliant audit trail. This integration is a FastAPI proxy. It forwards every TF guardrail request toapi.helloverra.com/v1/truefoundry/* authenticated with your Verra API key. Detection runs in Verra’s backend; the wrapper translates the TF contract so you can deploy it inside your own infrastructure.
If you don’t want to deploy a wrapper at all, you can point the gateway directly at
https://api.helloverra.com/v1/truefoundry/* with your Verra bearer in Custom Bearer Auth.Key features on TrueFoundry
- Input validation — blocks prompt injection, jailbreak, exfiltration attempts, and policy violations before the model runs.
- Input mutation — masks PII and secrets in the prompt before it reaches the model.
- Output validation — blocks secrets and policy violations in the model response.
- Output mutation — masks PII and secrets in the model response.
- Audit trail — every guardrail decision is recorded in your Verra dashboard with TF user and metadata mapped to Verra receipts.
scan-input, secrets and PII in prompts will pass through unmasked.
Architecture
event_type='truefoundry_guardrail', with the TF user mapped to end_user_id and TF metadata namespaced under findings.truefoundry.*.
The wrapper always returns HTTP 200 and signals the policy decision in the JSON body. Infrastructure failures return HTTP 5xx. See Custom guardrail response contract.
Response contract
| HTTP | Body | Meaning |
|---|---|---|
200 | {"verdict": true} | Allow |
200 | {"verdict": false, "message": "..."} | Block (policy deny) |
200 | {"verdict": true, "transformed": <bool>, "result": <full body>} | Mutate result (redacted or unchanged) |
5xx | error JSON | Wrapper or Verra failure |
verdict: false. Verra’s backend honors this; the wrapper passes it through unchanged.
Wrapper endpoints
| Path | Operation | Target | What it does |
|---|---|---|---|
/scan-input | Validate | Request | Blocks prompt injection, jailbreak, exfiltration, policy violations |
/redact-input | Mutate | Request | Masks PII and secrets in the prompt |
/scan-output | Validate | Response | Blocks secrets and policy violations in the model response |
/redact-output | Mutate | Response | Masks PII and secrets in the model response |
GET / and GET /health — open health checks. GET /debug/loaded-config — bearer-gated diagnostics.
All POST routes expect Authorization: Bearer <WRAPPER_API_KEY>.
Prerequisites
VERRA_KEY— your Verra TrueFoundry integration token. Email support@helloverra.com to request one.WRAPPER_API_KEY— a random string you generate; the gateway sends it asAuthorization: Bearer …when calling the wrapper. Independent fromVERRA_KEY.- Public HTTPS URL for the deployed wrapper (any host the gateway can reach).
Setup
Deploy the wrapper
Local:Smoke test:Docker or any cloud host:Build and run the container on ECS, Cloud Run, Kubernetes, Render, or any platform with a public HTTPS URL. Put TLS in front of the service; the gateway must reach paths such as
https://<host>/scan-input.Deploy on TrueFoundry (optional)
Deploy on TrueFoundry (optional)
Set
TFY_WORKSPACE_FQN, TFY_PUBLIC_HOST, TFY_PUBLIC_PATH, and secret FQNs in .env. Create secrets verra-key and wrapper-api-key under group verra-guardrails-tfy in Platform → Secrets, then:Register Custom Guardrail configs
AI Gateway → Guardrails → + Add New Guardrails Group → type Custom.

Register the remaining configs:
Auth Data → Custom Bearer Auth works the same as Headers if you prefer not to set headers manually.
- Group name:
verra - Add four configs — one per wrapper path (or start with input validate only).
| Field | Value |
|---|---|
| Name | verra-input-validate |
| Description (optional) | Custom guardrail server for validate or mutate via HTTP endpoint |
| Operation | Validate |
| Target | Request |
| Enforcing Strategy | Enforce But Ignore On Error |
| URL | https://<host>/scan-input |
| Headers | Authorization → Bearer <WRAPPER_API_KEY>; Content-Type → application/json |
| Config | {} |

| Name (example) | Operation | Target | Path |
|---|---|---|---|
verra-input-redact | Mutate | Request | /redact-input |
verra-output-validate | Validate | Response | /scan-output |
verra-output-redact | Mutate | Response | /redact-output |
Attach to traffic
Model pin: AI Gateway → Models → <model> → Guardrails → attach group For hard blocks only (no PII masking), omit the
verra.Per request — X-TFY-GUARDRAILS header, selector format <group>/<config-name>:redact-* configs. For full coverage including PII/secrets masking, wire all four.Custom config (optional)
Theconfig field the gateway passes to the wrapper is forwarded to Verra unchanged. Recognized keys (all optional; redact rails default both to true):
| Key | Purpose |
|---|---|
redact_pii | Enable PII masking on /redact-input and /redact-output (default true) |
redact_secrets | Enable secrets masking on redact rails (default true) |
traceparent_metadata_key | Which context.metadata key carries an inbound traceparent for distributed tracing |
observe / govern / enforce) is the source of truth and cannot be overridden by config.
Troubleshooting
401 Unauthorized from the wrapper
401 Unauthorized from the wrapper
Gateway allows despite verdict: false
Gateway allows despite verdict: false
The wrapper signals rail decisions via
{"verdict": false} on HTTP 200. If the gateway returns a normal completion when the wrapper reported a block, your tenant gateway may not be honoring the verdict field. Confirm by curling the wrapper directly — if you get 200 + {"verdict": false} but the gateway still returns a completion, the gateway is the issue.Workaround: switch the Custom Guardrail Configs’ Enforcing Strategy to Enforce. See Enforcing Strategy.PII or secrets pass through unmasked
PII or secrets pass through unmasked
You likely registered only validate rails. Add
/redact-input and /redact-output as Mutate configs and attach them to your model or per-request selectors.Verra backend unreachable (5xx)
Verra backend unreachable (5xx)
Check wrapper logs for upstream errors to
api.helloverra.com. Verify VERRA_KEY is valid and not expired. With Enforce But Ignore On Error, transient outages pass through; use Enforce for fail-closed behavior.Reference
| Item | Value |
|---|---|
| Source repo | truefoundry/integrations-custom-guardrails/integrations/verra |
| Verra platform | helloverra.com |
| Verra docs | helloverra.com/docs |
| Verra API (direct) | https://api.helloverra.com/v1/truefoundry/* |
| Audit trail | app.helloverra.com/admin/receipts |
| Token requests | support@helloverra.com |
| Selector | verra/<config-name> |