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.
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
Start BHANUJ AIGP locally
Start the local API, identity provider, and durable stores.
- 2
Get the runtime
Clone the OpenAI runtime lab and create its environment.
- 3
Configure the runtime
Supply your OpenAI key, model, state directory, and replay secret.
- 4
Install the plugin
Make the external adapter discoverable to the BHANUJ AIGP worker.
- 5
Start the replay worker
Run the one worker that has the OpenAI plugin installed.
- 6
Start the runtime
Expose its private, bearer-protected /replay endpoint on your machine.
- 7
Get a short-lived API token
Let the runtime submit bounded evidence and the audit request to Core.
- 8
Check both services
Confirm BHANUJ AIGP and the private runtime are reachable before spending an API call.
- 9
Run the aligned fixture
Replace high-risk evidence with approved low-risk evidence and observe a changed result.
- 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.
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.sh2. Get the runtime — terminal 2
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.
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=local4. 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.
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
cd "$BHANUJ_AIGP_HOME"
uv run --no-sync python -m ai_governance.workers.replay_worker_runtime6. Start the private OpenAI runtime — terminal 2
cd "$OPENAI_RUNTIME_HOME"
set -a
. ./.env
set +a
uv run --extra dev openai-runtime serve --host 127.0.0.1 --port 80917. 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.
# 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
curl --fail http://127.0.0.1:8000/ready
curl --fail http://127.0.0.1:8091/health9. 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.
cd "$OPENAI_RUNTIME_HOME"
uv run --extra dev openai-runtime causal-audit --scenario aligned{
"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. Your terminal starts the CLI
You run the aligned command in terminal 4. The CLI is the approved caller for this tutorial.
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. 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. 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. 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. 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. 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. 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. 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.
# 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>{
"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.
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: trueThe 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.scorewithreference-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.scoreand its evidence schema isreference-openai-fraud-risk / v1. - 2. Allow one change
- The policy allows
opaque-reference / v1with theREPLACEstrategy. 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.
- 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. - 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_ALIGNEDandEVIDENCE_IGNORED. - 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.
- 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.
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_TOKENwithOPENAI_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 usehost.docker.internal:8091instead. - AIGP returns 401 or 403
- Generate a new short-lived token in step 7. Check that the organization and project IDs are
org_defaultandproject_defaultfor 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.
