Getting Started¶
This guide walks you through installing OAG, writing your first policy, and verifying enforcement end-to-end.
Prerequisites¶
- A terminal with
bashor PowerShell curl(for testing)
JDK 21+ only needed if building from source.
Install¶
Download the binary for your platform from Releases and place it on your PATH:
# Linux / macOS
chmod +x oag
sudo mv oag /usr/local/bin/
# Windows — add the directory containing oag.exe to your PATH
Verify:
A fat JAR (oag-app-1.0-SNAPSHOT-all.jar) is also available on the Releases page for platforms without a native binary. Run with java -jar oag-app-1.0-SNAPSHOT-all.jar help (requires JDK 21+).
Build from Source¶
For development, run directly without building a JAR:
Write a Policy¶
Create policy.yaml:
version: 1
defaults:
action: deny
max_body_bytes: 1048576
allow:
- id: openai_api
host: api.openai.com
methods: [CONNECT, POST, GET]
paths: [/v1/*]
secrets: [OPENAI_KEY]
- id: anthropic_api
host: api.anthropic.com
methods: [CONNECT, POST]
paths: [/v1/*]
secrets: [ANTHROPIC_KEY]
deny:
- id: cloud_metadata
host: 169.254.169.254
This policy allows POST/GET requests to OpenAI and POST requests to Anthropic, blocks cloud metadata access, and denies everything else by default.
HTTPS traffic: Agents use HTTP CONNECT tunneling for HTTPS destinations. Include CONNECT in the methods list for any host the agent will access over HTTPS. Omit paths when allowing CONNECT, since tunnel requests have no path.
See configuration.md for the full policy schema.
Provide Secrets¶
OAG materializes secrets at request time so agents never see raw credentials.
Environment variables (default provider):
export OAG_SECRET_OPENAI_KEY="sk-your-key-here"
export OAG_SECRET_ANTHROPIC_KEY="sk-ant-your-key-here"
File provider (alternative):
mkdir secrets
echo -n "sk-your-key-here" > secrets/OPENAI_KEY.secret
echo -n "sk-ant-your-key-here" > secrets/ANTHROPIC_KEY.secret
Agents use placeholders in headers — OAG swaps them for real secrets on allowed requests:
Start OAG¶
With verbose logging to stderr:
File provider variant:
oag run --policy policy.yaml --port 8080 --log audit.jsonl --secret-provider file --secret-dir ./secrets
During development via Gradle:
Verify with oag explain¶
Before running an agent, verify your policy evaluates as expected:
Expected output:
Try a denied request:
Expected output:
Use --json for machine-readable output:
Validate Configuration¶
Run the doctor command to check your policy and runtime config:
Point Your Agent at OAG¶
Configure any HTTP-proxy-capable agent:
The agent sends requests through OAG. Denied requests return 403 Forbidden. Allowed requests are forwarded upstream with secrets injected.
Quick Test with curl¶
# Allowed HTTP request (expect upstream response)
curl -x http://127.0.0.1:8080 http://api.openai.com/v1/models
# Denied request (expect 403)
curl -x http://127.0.0.1:8080 http://evil.com/
# Allowed HTTPS via CONNECT tunnel
curl -x http://127.0.0.1:8080 https://api.openai.com/v1/models
# Denied HTTPS tunnel (expect 403)
curl -x http://127.0.0.1:8080 https://www.google.com/
Check the Audit Log¶
Every request produces a JSONL audit event in audit.jsonl:
{
"timestamp": "2026-02-23T12:00:00Z",
"decision": {"action": "allow", "reason_code": "allowed_by_rule", "rule_id": "openai_api"},
"request": {"host": "api.openai.com", "port": 443, "scheme": "https", "method": "POST", "path": "/v1/chat/completions", "bytes_out": 512},
"secrets": {"injection_attempted": true, "injected": true, "secret_ids": ["OPENAI_KEY"], "secret_versions": {}},
"phase_timings": {"policy_evaluation_ms": 0.08, "total_ms": 19.72}
}
Example abbreviated. Actual audit events include additional fields: schema_version, event_type, oag_version, policy_hash, agent_id, session_id, redirect_chain, errors, and others. Fields with null values are included in the output. See Observability for the full schema.
Filter for denies:
See observability.md for the full event schema and metrics.
Performance¶
Measured on real network traffic (not benchmarks):
| Scenario | Total Time | OAG Overhead |
|---|---|---|
| Denied request | 0.34-0.44 ms | 100% (no network I/O) |
| Allowed HTTP request | 19-79 ms | 1.2-1.5 ms (rest is upstream) |
| CONNECT tunnel | varies | < 0.5 ms setup |
| Policy evaluation | — | 0.08 ms |
| Secret materialization | — | 0.10-0.12 ms |
OAG adds 1-2 ms of overhead to allowed requests. Denied requests complete in under 0.5 ms. On allowed requests, 94-98% of total time is upstream network I/O.
Common Flags¶
| Flag | Description | Default |
|---|---|---|
--policy <path> |
Policy file path | required |
--port <n> |
Listen port | 8080 |
--log <path> |
Audit log file path | stdout |
--verbose |
Debug output to stderr | off |
--dry-run |
Log violations without blocking | off |
--watch |
Hot-reload policy on file change | off |
--read-timeout-ms <ms> |
Upstream read timeout | 30000 |
--connect-timeout-ms <ms> |
Upstream connect timeout | 5000 |
--secret-provider <type> |
Secret backend (env, file, or oauth2) |
env |
--admin-port <n> |
Admin server port | disabled |
See cli.md for the full flag reference.
Next Steps¶
- Concepts — how OAG works, architecture, threat model
- Configuration Reference — full policy schema, rule fields, bundles, linting
- CLI Reference — all commands, flags, JSON output schemas
- Security — content inspection, injection detection, exfiltration guards
- Observability — audit events, Prometheus metrics, OpenTelemetry
- Operations — deployment, packaging, resilience, testing
- Policy Examples — ready-to-use policy recipes