Integration guideBeginner~25 min

Run OpenAI Runtime Causal Audit

SupportedPython 3.12+OpenAI RuntimeReplayTOOL_CALL + CAUSAL_AUDIT

Run one real OpenAI Responses API tool call, replay it through an approved evidence replacement, and see BHANUJ AIGP distinguish a changed decision from an unchanged one.

Last updated
Proven outcomes TWO CASES
Observed riskHIGH · 0.90
Approved replacementLOW · 0.20
Decision changesEVIDENCE_ALIGNED
Decision does not changeEVIDENCE_IGNORED

PUBLIC PLUGIN API · CONTROLLED REPLAY · CAUSAL AUDIT

First observe what happened. Then test one approved replacement in a safe replay.

What you will prove

Same path answers two different causal questions.

This lab has one governed tool, transaction_risk.score. Its observed evidence is high risk with confidence 0.90. BHANUJ AIGP authorizes one opaque-reference REPLACE intervention; the OpenAI runtime resolves the approved low-risk profile privately and refuses to replay if its digest does not match.

Aligned fixture

Evidence changes from HIGH to LOW, the model decision changes from BLOCK to ALLOW, and the audit ends as EVIDENCE_ALIGNED.

Ignored fixture

The same evidence changes, but an independent locked-account fact keeps the decision BLOCK. The audit ends as EVIDENCE_IGNORED.

Before you start

Use the simple local path first.

  • A Mac, Linux, or Windows development machine with Git, Docker Desktop, Python 3.12+, and uv.
  • An OpenAI API key and a model your project may use.
  • Ports 8000 (Core) and 8091 (the private runtime) available on your machine.
  • Two repository folders: ai-governance-oss and labs. Keep them as separate checkouts.
Why host-local Core? It lets you install the external runtime only into the replay worker's Python environment. The BHANUJ AIGP package still has no OpenAI dependency and the runtime still has no BHANUJ AIGP dependency.

If you have not started AIGP before, complete the Getting Started prerequisites first. This guide uses the host-local startup option so all replay state and the plugin-aware worker use the same local configuration.

Process Flow

Steps

  1. 1

    Start BHANUJ AIGP locally

    Start the local API, identity provider, and durable stores.

  2. 2

    Get the runtime

    Clone the OpenAI runtime lab and create its environment.

  3. 3

    Configure the runtime

    Supply your OpenAI key, model, state directory, and replay secret.

  4. 4

    Install the plugin

    Make the external adapter discoverable to the BHANUJ AIGP worker.

  5. 5

    Start the replay worker

    Run the one worker that has the OpenAI plugin installed.

  6. 6

    Start the runtime

    Expose its private, bearer-protected /replay endpoint on your machine.

  7. 7

    Get a short-lived API token

    Let the runtime submit bounded evidence and the audit request to Core.

  8. 8

    Check both services

    Confirm BHANUJ AIGP and the private runtime are reachable before spending an API call.

  9. 9

    Run the aligned fixture

    Replace high-risk evidence with approved low-risk evidence and observe a changed result.

  10. 10

    Run the ignored fixture

    Repeat with a locked-account fact that keeps the result unchanged.

1. Start BHANUJ AIGP locally — terminal 1

This command stays open while you complete the remaining steps. It starts Keycloak, Neo4j, the API, and local durable stores. It does not start a replay worker.

terminal 1 · AI Governance OSS
git clone https://github.com/Bhanuj-AI/ai-governance-oss.git
cd ai-governance-oss
uv sync
cp .env.local.example .env.local
cp keycloak-postgres/.env.keycloak.example keycloak-postgres/.env.keycloak
./servers-local.sh

2. Get the runtime — terminal 2

terminal 2 · OpenAI runtime
git clone https://github.com/Bhanuj-AI/labs.git
cd labs/agent-frameworks/openai/openai-agent-runtime
uv sync --extra dev
export OPENAI_RUNTIME_HOME="$PWD"

3. Configure the runtime

Use a local-only replay secret. The example keeps provider-side response retention off: local continuation uses store=false.

terminal 2 · configure .env
cp .env.example .env

# Edit .env. At minimum, set a real API key and a model available to it.
# OPENAI_API_KEY=...
# OPENAI_MODEL=...

# Keep the remaining local defaults for this tutorial:
# OPENAI_AGENT_RUNTIME_REPLAY_AUTH_TOKEN=<a-long-local-secret>
# OPENAI_AGENT_RUNTIME_PUBLIC_REPLAY_ENDPOINT=http://127.0.0.1:8091/replay
# OPENAI_AGENT_RUNTIME_RESPONSE_CONTINUATION=local

4. Install the adapter in the AIGP worker environment — terminal 3

This is the only installation step that joins the two systems. It installs the runtime as a versioned plugin into the process that will execute replay jobs; it does not add OpenAI to Core's dependency graph.

terminal 3 · plugin-aware AIGP environment
cd /path/to/ai-governance-oss
export BHANUJ_AIGP_HOME="$PWD"
export OPENAI_RUNTIME_HOME='/absolute/path/to/labs/agent-frameworks/openai/openai-agent-runtime'

# Install this external runtime into the Python environment that runs the worker.
uv pip install "$OPENAI_RUNTIME_HOME"

# Load the same local BHANUJ AIGP configuration used by servers-local.sh.
set -a
. ./.env.local
. ./.env.service-accounts.generated
. ./.env.oauth.generated
set +a

# The worker and runtime must use the same replay secret and endpoint.
export AI_GOVERNANCE_OPENAI_AGENT_RUNTIME_REPLAY_ENDPOINT='http://127.0.0.1:8091/replay'
export AI_GOVERNANCE_OPENAI_AGENT_RUNTIME_REPLAY_AUTH_TOKEN='<the-same-local-secret-set-in-runtime-.env>'

# Prove that AIGP can discover the runtime through the public entry point.
uv run --no-sync python -c "from importlib.metadata import entry_points; assert any(p.name == 'openai-agent-runtime' for p in entry_points(group='bhanuj.governance.plugins')); print('OpenAI runtime plugin discovered')"

5. Start the plugin-aware replay worker — terminal 3

terminal 3 · leave this worker running
cd "$BHANUJ_AIGP_HOME"
uv run --no-sync python -m ai_governance.workers.replay_worker_runtime

6. Start the private OpenAI runtime — terminal 2

terminal 2 · private runtime endpoint
cd "$OPENAI_RUNTIME_HOME"
set -a
. ./.env
set +a
uv run --extra dev openai-runtime serve --host 127.0.0.1 --port 8091

7. Get a short-lived AIGP API token — terminal 4

The token is held only in this shell. The runtime forwards it only to AIGP as an HTTP authorization header; it is never included in the replay envelope.

terminal 4 · submitter shell
# Keep this token in the current shell only. Do not put it in .env.
export BHANUJ_AIGP_HOME='/absolute/path/to/ai-governance-oss'
export OPENAI_RUNTIME_HOME='/absolute/path/to/labs/agent-frameworks/openai/openai-agent-runtime'

cd "$OPENAI_RUNTIME_HOME"
set -a
. ./.env
set +a
export AI_GOVERNANCE_API_BEARER_TOKEN="$(
  cd "$BHANUJ_AIGP_HOME"
  uv run python scripts/oauth/fetch-access-token.py
)"
export AI_GOVERNANCE_BASE_URL='http://127.0.0.1:8000'
export AI_GOVERNANCE_ORGANIZATION_ID='org_default'
export AI_GOVERNANCE_PROJECT_ID='project_default'

8. Check both services before using the OpenAI API

terminal 4 · both commands return success
curl --fail http://127.0.0.1:8000/ready
curl --fail http://127.0.0.1:8091/health

9. Run the evidence-aligned case

The command creates and activates the replacement policy if needed, records the observed execution, starts Causal Audit, and waits for the final result. Keep the printed policy ID and version for the next step.

terminal 4 · aligned fixture
cd "$OPENAI_RUNTIME_HOME"
uv run --extra dev openai-runtime causal-audit --scenario aligned
expected result
{
  "observed_decision": "BLOCK",
  "observed_outcome_score": 1.0,
  "audit_status": "SUCCEEDED",
  "classification": "EVIDENCE_ALIGNED"
}

What happens after you run step 9

One command starts a durable, multi-step process.

You start the command and the plugin-aware worker. From there, the CLI, AIGP, worker, and private runtime each do a specific job. No agent tool call creates the policy, and the worker never guesses which policy to use.

  1. 1. Your terminal starts the CLI

    You run the aligned command in terminal 4. The CLI is the approved caller for this tutorial.

  2. 2. The runtime runs the source case

    The OpenAI runtime performs the real observed agent run, including transaction_risk.score, and records its bounded outcome.

  3. 3. The CLI ingests the completed run

    It sends AIGP the execution record, safe tool evidence reference and digest, outcome score, and replay capability. It then marks the execution complete.

  4. 4. The CLI creates or reuses the policy

    For the aligned case, it creates and activates the exact REPLACE policy if you did not supply one. The policy is now active before any audit is submitted.

  5. 5. The CLI queues the Causal Audit

    AIGP saves a QUEUED audit and a durable Causal Audit job. The command waits by polling the saved audit record; it does not run the replay itself.

  6. 6. The worker validates and plans the replay

    The worker in terminal 3 claims the Causal Audit job. It checks the completed source, active policy, tool and schema match, and replay capability before creating a controlled Replay job.

  7. 7. The worker invokes the private runtime

    The same worker claims the Replay job, selects openai-agent-runtime/v1, and calls its private /replay endpoint with the governed intervention envelope.

  8. 8. The runtime resolves the replacement

    The runtime resolves the approved low-risk reference locally, verifies its digest, and fails closed if either check fails. Only then does it run the isolated replay.

  9. 9. AIGP finalizes the audit

    When the controlled replay reaches a terminal state, the worker schedules finalization. AIGP compares the saved source outcome with the replay outcome and records the causal classification.

In step 10, the CLI runs a new source execution but reuses the same active policy ID and version. That is why the two audit results test the same approved replacement.

10. Run the evidence-ignored case

AIGP permits one active policy for this exact tool and schema. Reuse the policy ID and version from step 9. This case should also finish successfully, but its final classification is different. You will inspect both completed audits together in Studio next.

terminal 4 · ignored fixture
# Reuse the policy_id and policy_version printed by step 9.
uv run --extra dev openai-runtime causal-audit \
  --scenario ignored \
  --policy-id <policy-id-from-step-9> \
  --policy-version <policy-version-from-step-9>
expected result
{
  "observed_decision": "BLOCK",
  "audit_status": "SUCCEEDED",
  "classification": "EVIDENCE_IGNORED"
}

Review the policy values

The policy was active before the audit started.

Lifecycle step 4 creates and activates this policy automatically when an exact match does not already exist. This section lets you review the permission it used. It never changes live traffic; it authorizes one isolated replay to replace one tool result with one approved reference.

Causal Audit intervention policy
Policy target
Tool name: transaction_risk.score
Evidence schema: reference-openai-fraud-risk
Schema version: v1

Counterfactual controls
Provider: opaque-reference
Provider version: v1
Allowed strategy: REPLACE
Counterfactual reference: openai-agent-runtime://counterfactual/fraud-low-v1
Counterfactual digest: sha256:<approved-low-risk-profile>
Runtime attests validation: true

The policy authorizes a reference. The runtime resolves its private value and verifies its digest before replaying.

Why these policy values?

Exact tool and schema
The policy matches only transaction_risk.score with reference-openai-fraud-risk / v1. It cannot be used for another tool or an unrecognised evidence shape.
REPLACE, not PERTURB or NULLIFY
This test asks what happens when the runtime uses a known, approved low-risk profile instead of the observed high-risk result. The policy does not edit a confidence field and it does not remove evidence.
Opaque reference
The reference identifies the low-risk profile inside the OpenAI runtime. AIGP can authorize that reference without receiving the profile's raw tool evidence.
Digest and runtime attestation
The policy records the approved counterfactual digest. The runtime must resolve the reference and prove the digest matches before it runs the replay. A missing reference or mismatch stops the audit safely.
One active policy
The ignored fixture reuses the exact policy ID and version from the aligned fixture. That keeps both audits tied to the same approved replacement.

AIGP freezes the source details and policy version, then queues a replay job. The plugin-aware worker sends the runtime a governed envelope containing only the approved reference, digests, and policy metadata. The runtime resolves the replacement privately, verifies it, and returns a bounded result for Causal Audit to compare.

Inspect in Studio

Now follow the completed runs in the order they appear.

Do this only after both commands in steps 9 and 10 finish successfully. Open Studio at http://localhost:3000, then select Agents Runtime. You will first see the executions, then the two Causal Audits created from them.

How the policy is used

1. Match the source
AIGP finds the active policy only when the source tool is transaction_risk.score and its evidence schema is reference-openai-fraud-risk / v1.
2. Allow one change
The policy allows opaque-reference / v1 with the REPLACE strategy. Use the approved low-risk reference instead of the observed risk result.
3. Keep data private
AIGP sends the policy identity, the approved reference, and digests in the replay envelope. It does not send raw tool evidence, prompts, responses, or reasoning.
4. Fail closed
The OpenAI runtime resolves the approved reference privately. If it cannot resolve it, or the resolved value has the wrong digest, it refuses to run the replay.
  1. 1Stay on the Executions tab first. Open an OpenAI Transaction Fraud Agent execution to see its ordered timeline. Find the tool call for transaction_risk.score; this is the source fact that the audit later tests.
  2. 2Select the Causal Audit tab in Agents Runtime. The overview lists both audits created by this guide. Look for the completed rows with the classifications EVIDENCE_ALIGNED and EVIDENCE_IGNORED.
  3. 3Return to the audit overview and open EVIDENCE_ALIGNED first. It shows that changing the approved risk evidence changed the decision from BLOCK to ALLOW.
  4. 4Return to the Causal Audit overview and open EVIDENCE_IGNORED. The same risk evidence changed, but the separate locked-account fact kept the decision at BLOCK.

Concept illustration only. The Studio screens above are the evidence: Causal Audit records whether the approved replacement changed the actual outcome.

Why one worker

A replay job must be claimed by the worker that knows this adapter.

The runtime adapter is discovered through the public bhanuj.governance.plugins entry-point group. In this tutorial, only terminal 3 has that package installed. Running a second, stock replay worker at the same time lets it claim the job first; it cannot load openai-agent-runtime/v1, so the job fails instead of reaching your runtime.

Causal Audit submits a jobplugin-aware worker claims itprivate runtime /replay

The host-local path avoids this problem because it starts no default worker. If you use the Docker stack instead, stop its ai-governance-replay-worker before starting a host worker, or build the plugin into that container image. Do not run both against the same job store.

What stays private

BHANUJ AIGP governs the request; the runtime owns the sensitive material.

AIGP receives

  • Tool and schema identity
  • Evidence references and digests
  • Policy and counterfactual reference identity
  • Bounded outcome scores and replay lineage

The runtime retains

  • OpenAI API key and request content
  • Function arguments and raw tool evidence
  • Model output and reasoning
  • The locally resolved replacement profile

The replay request contains a governed ReplayInterventionEnvelope, not raw evidence. The runtime fails closed if it cannot resolve the approved counterfactual reference or if the digest differs.

Troubleshooting

Solve most first-run issues.

POST /replay returns 401
The worker and runtime have different replay secrets. Compare AI_GOVERNANCE_OPENAI_AGENT_RUNTIME_REPLAY_AUTH_TOKEN with OPENAI_AGENT_RUNTIME_REPLAY_AUTH_TOKEN; they must match exactly.
Audit remains queued or replay fails
Confirm terminal 3 is running and printed OpenAI runtime plugin discovered. Stop any stock worker that shares the same job store.
Worker cannot reach the runtime
Host-local BHANUJ AIGP uses 127.0.0.1:8091. A Docker worker must use host.docker.internal:8091 instead.
AIGP returns 401 or 403
Generate a new short-lived token in step 7. Check that the organization and project IDs are org_default and project_default for the local stack.

Continue with the source.

The lab README has the runtime contract, privacy boundary, release verification, and opt-in real OpenAI integration tests.