Truefoundry

Arthur + TrueFoundry

How do you run Arthur AI as a custom guardrail on TrueFoundry AI Gateway? Deploy the integrations/arthur-ai FastAPI wrapper on any public HTTPS host, register it as a Custom Guardrail in TrueFoundry, and attach the guardrail group to your models or requests. TrueFoundry calls the wrapper at llm_input / llm_output; the wrapper forwards traffic to Arthur GenAI Engine and returns verdict JSON on HTTP 200 β€” validating prompts on the way in and completions on the way out without redacting or rewriting text.


Overview

TrueFoundry AI Gateway is the proxy layer that sits between your applications and the LLM providers and MCP Servers. It is an enterprise-grade platform that enables users to access 1000+ LLMs using a unified interface while taking care of observability and governance.

Arthur AI integrates with TrueFoundry as a Custom Guardrail. When LLM traffic flows through the gateway, Arthur validates prompts on the way in and completions on the way out β€” reporting pass/block verdicts without redacting or rewriting text. TrueFoundry calls the wrapper via the Custom Guardrail contract at llm_input / llm_output, and the wrapper forwards traffic to Arthur GenAI Engine and returns verdict JSON on HTTP 200.

Once configured, you get:

  • Input validation β€” prompts checked before they reach the model
  • Output validation β€” completions checked before they return to your application
  • Pass/block verdicts β€” policy outcomes reported without redacting or rewriting text
  • Configurable checks β€” default PromptInjectionRule + ToxicityRule on input and ToxicityRule on output when config is {}
sequenceDiagram
    participant App as Your Application
    participant Gateway as TrueFoundry AI Gateway
    participant Wrapper as Arthur AI Wrapper
    participant Engine as Arthur GenAI Engine

    App->>Gateway: LLM request
    Gateway->>Wrapper: POST /validate-input (llm_input)
    Wrapper->>Engine: POST /api/v2/validate
    Engine-->>Wrapper: Rule results
    Wrapper-->>Gateway: HTTP 200 {"verdict": true|false}
    alt verdict true
        Gateway->>App: Request proceeds to model
    else verdict false
        Gateway->>App: Request blocked (policy)
    end
    Note over Gateway,Wrapper: Output rail repeats at llm_output via /validate-output

How it works:

  1. TrueFoundry AI Gateway POSTs an OpenAI-shaped requestBody (input) or requestBody + responseBody (output) to your wrapper URL.
  2. The wrapper extracts user/assistant text and calls Arthur with your ARTHUR_API_KEY.
  3. The wrapper returns HTTP 200 with a policy outcome in the body. Infrastructure failures return HTTP 5xx.
Your app ─► TrueFoundry gateway ─► Arthur AI wrapper ─► engine.platform.arthur.ai/api/v2/validate

Prerequisites:

  • Arthur API key from the Arthur platform.
  • Public HTTPS URL for the deployed wrapper.
  • WRAPPER_API_KEY β€” shared secret TrueFoundry sends as Authorization: Bearer ….

Arthur AI guardrail behavior

Arthur GenAI Engine validates LLM prompts and completions. The wrapper calls POST /api/v2/validate and maps rule results to pass/block β€” it does not embed policy logic beyond the checks you configure in Arthur.

Arthur is validate-only. On TrueFoundry, use Operation: Validate for both input and output rails.

Default checks when config is {}:

  • Input: PromptInjectionRule + ToxicityRule
  • Output: ToxicityRule
πŸ“˜

Arthur is validate-only. Use Operation: Validate for both input and output rails. Arthur reports failures but does not redact or rewrite text.


Response contract

HTTPBodyMeaning
200{"verdict": true}Allow
200{"verdict": false, "message": "..."}Block (policy)
5xxerror JSONWrapper or Arthur failure

Policy blocks use 2xx + verdict: false, not HTTP 4xx. See Custom guardrail response contract.


Wrapper endpoints

PathTarget
/validate-inputRequest (input)
/validate-outputResponse (output)

GET /health β€” health check. GET /debug/loaded-config β€” bearer-gated diagnostics.

All POST routes expect Authorization: Bearer <WRAPPER_API_KEY>.


Setup

Clone and configure

git clone https://github.com/truefoundry/integrations-custom-guardrails
cd integrations-custom-guardrails/integrations/arthur-ai
cp .env.example .env
ARTHUR_API_KEY=<from https://engine.platform.arthur.ai>
WRAPPER_API_KEY=<generate: python -c "import secrets; print(secrets.token_urlsafe(32))">
⚠️

Use environment variables or secrets for API keys. Set ARTHUR_API_KEY and WRAPPER_API_KEY in .env or TrueFoundry Platform β†’ Secrets rather than committing them to source control.

Deploy the wrapper

TrueFoundry:

pip install -U truefoundry
tfy login
python deploy.py --wait

Set TFY_WORKSPACE_FQN, TFY_PUBLIC_HOST, TFY_PUBLIC_PATH, and secret FQNs in .env. Create secrets arthur-api-key and wrapper-api-key under group arthur-guardrails-tfy in Platform β†’ Secrets.

Local:

python3 -m venv .venv
.venv/bin/pip install -r requirements-dev.txt
.venv/bin/uvicorn main:app --reload --port 8000

Register Arthur AI guardrail configs in TrueFoundry

AI Gateway β†’ Guardrails β†’ + Add New Guardrails Group β†’ type Custom.

  • Group name: arthur-ai
  • Add two configs β€” input and output.

Input validate example:

FieldValue
Namearthur-input-validate
OperationValidate
TargetRequest
Enforcing StrategyEnforce But Ignore On Error
URLhttps://<host>/validate-input
HeadersAuthorization β†’ Bearer <WRAPPER_API_KEY>; Content-Type β†’ application/json
Config{}

Arthur AI guardrail configuration in TrueFoundry (input validate)


Output validate:

FieldValue
Namearthur-output-validate
OperationValidate
TargetResponse
URLhttps://<host>/validate-output

Auth Data β†’ Custom Bearer Auth works the same as Headers if you prefer not to set headers manually.

Attach Arthur AI guardrails to traffic

Model pin: AI Gateway β†’ Models β†’ <model> β†’ Guardrails β†’ attach group arthur-ai.

Per request β€” X-TFY-GUARDRAILS header, selector format <group>/<config-name>:

{
  "llm_input_guardrails": ["arthur-ai/arthur-input-validate"],
  "llm_output_guardrails": ["arthur-ai/arthur-output-validate"]
}

Custom config (optional)

Override default Arthur checks by setting config.checks in the TrueFoundry dashboard:

{
  "checks": [
    {"name": "prompt-injection-check", "type": "PromptInjectionRule", "apply_to_prompt": true, "apply_to_response": false},
    {"name": "toxicity-check", "type": "ToxicityRule", "apply_to_prompt": true, "apply_to_response": false, "config": {"threshold": 0.5}}
  ],
  "fail_closed_on_unavailable": false
}
KeyPurpose
credentials.apiKeyOverride ARTHUR_API_KEY env var
api_baseOverride Arthur API host (default https://engine.platform.arthur.ai)
timeoutRequest timeout in seconds (default 30)
context / grounding_contextGrounding text for hallucination checks
fail_closed_on_unavailableBlock when Arthur returns Skipped/Unavailable (default false)

Troubleshooting

SymptomLikely cause
401 from wrapperWRAPPER_API_KEY on the service does not match the dashboard Bearer token
Gateway allows despite verdict: falseTenant gateway not honoring verdict-on-200; set Enforce or upgrade gateway
Arthur Skipped/Unavailable but traffic allowedDefault behavior; set fail_closed_on_unavailable: true in config
Wrong checks runningCurl /debug/loaded-config with Bearer auth to inspect loaded config

Reference

ItemValue
Source repotruefoundry/integrations-custom-guardrails/integrations/arthur-ai
Arthur Engineengine.platform.arthur.ai
Arthur APIPOST https://engine.platform.arthur.ai/api/v2/validate
Selectorarthur-ai/<config-name>
TrueFoundry docsCustom Guardrails
Documentation indextruefoundry.com/llms.txt

Next Steps

Now that Arthur AI is running as a guardrail on TrueFoundry AI Gateway, explore these resources:

flowchart LR
    A[Deploy wrapper] --> B[Register guardrails]
    B --> C[Attach to traffic]
    C --> D[Validate input]
    D --> E[Validate output]
    E --> F[Monitor verdicts]