Outpost Admin API Reference
The Outpost Admin API is a separate FastAPI application that listens on port 8301 (local-only). It provides emergency override capabilities, local status inspection, and operational controls without requiring connectivity to the Arbitex platform.
Air-gap compatible. All admin API calls are local. No data is forwarded to the platform during admin operations.
Authentication
Section titled “Authentication”All endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <admin-api-key>Token resolution order:
admin_users[].api_keyfrom the loaded policy bundle (HMAC compare — constant time)OUTPOST_EMERGENCY_ADMIN_KEYenvironment variable as a fallback
Brute-force protection (OUT-017): 5 failed authentication attempts per IP within a 15-minute sliding window triggers HTTP 429. The window resets automatically.
CORS: The admin API only accepts requests from http://localhost:8301 and http://127.0.0.1:8301. All other origins are rejected.
Status and sync
Section titled “Status and sync”GET /admin/api/status
Section titled “GET /admin/api/status”Returns the current outpost operational status: policy version, active override count, uptime, and emergency kill state.
GET /admin/api/statusAuthorization: Bearer <token>Response
{ "outpost_id": "prod-outpost-01", "policy_version": "v2026.03.12-4", "uptime_seconds": 86400, "active_override_count": 2, "emergency_kill": false, "last_override_modified": "2026-03-12T08:00:00Z", "routing_override": null, "update_available": true, "latest_version": "0.19.2"}| Field | Description |
|---|---|
active_override_count | Sum of all active provider, rule, ruleset, and routing overrides + kill switch |
emergency_kill | true if the emergency kill switch is active (all requests blocked) |
routing_override | Provider name if routing is pinned; null if using policy-default routing |
update_available | true if latest_version differs from the running outpost version |
GET /admin/api/sync-status
Section titled “GET /admin/api/sync-status”Returns policy sync health: last sync timestamp, ETag, bundle version, heartbeat status, and TLS certificate expiry.
GET /admin/api/sync-statusAuthorization: Bearer <token>Response
{ "last_sync_at": "2026-03-12T08:52:00Z", "etag": "\"abc123\"", "bundle_version": "v2026.03.12-4", "latest_version": "0.19.2", "heartbeat": { "last_sent_at": "2026-03-12T08:55:00Z", "consecutive_failures": 0 }, "cert_expiry_days": 82.5}cert_expiry_days is null if no certificate path is configured. A value below 30 should trigger a certificate renewal.
GET /admin/api/airgap-config
Section titled “GET /admin/api/airgap-config”Returns the read-only air-gap configuration from OutpostSettings. Useful for verifying that air-gap mode is configured correctly.
GET /admin/api/airgap-configAuthorization: Bearer <token>Response
{ "airgap_enabled": true, "policy_path": "/etc/arbitex/policy.json", "model_path": "/etc/arbitex/models/", "siem_output": "file:///var/log/arbitex/siem.jsonl", "hmac_enabled": true, "outpost_id": "prod-outpost-01"}hmac_enabled is false only when OUTPOST_INSECURE_SKIP_HMAC=true is set (development only).
Provider management
Section titled “Provider management”GET /admin/api/providers
Section titled “GET /admin/api/providers”Lists all providers from the loaded policy bundle along with their current override state.
GET /admin/api/providersAuthorization: Bearer <token>Response
{ "providers": [ { "name": "anthropic", "base_url": "https://api.anthropic.com", "models": ["claude-sonnet-4-6", "claude-haiku-4-5-20251001"], "disabled": false, "disabled_until": null, "disable_reason": "" }, { "name": "openai", "base_url": "https://api.openai.com", "models": ["gpt-4o", "gpt-4o-mini"], "disabled": true, "disabled_until": "2026-03-12T12:00:00Z", "disable_reason": "Incident response — elevated error rate" } ]}disabled_until is null for a permanent disable (no duration specified).
POST /admin/api/providers/{provider}/disable
Section titled “POST /admin/api/providers/{provider}/disable”Disables a provider, optionally for a fixed duration. All requests routed to this provider will fail with 503 until re-enabled.
POST /admin/api/providers/{provider}/disableAuthorization: Bearer <token>Content-Type: application/json
{ "duration_hours": 4, "reason": "Incident response — elevated error rate"}| Field | Type | Required | Description |
|---|---|---|---|
duration_hours | float | No | Auto-re-enable after this many hours. Omit for permanent disable |
reason | string | No | Reason recorded in the audit log |
Returns 400 if the provider name is not in the policy bundle.
Response
{ "status": "disabled", "provider": "openai", "duration_hours": 4}POST /admin/api/providers/{provider}/enable
Section titled “POST /admin/api/providers/{provider}/enable”Re-enables a previously disabled provider. Clears the disable override immediately.
POST /admin/api/providers/{provider}/enableAuthorization: Bearer <token>No request body required.
Response
{ "status": "enabled", "provider": "openai"}DLP rule and ruleset management
Section titled “DLP rule and ruleset management”GET /admin/api/rules
Section titled “GET /admin/api/rules”Lists all DLP rules from the loaded policy bundle with their enabled/disabled state.
GET /admin/api/rulesAuthorization: Bearer <token>Response
{ "rules": [ { "id": "pii-ssn", "name": "SSN Detection", "tier": 1, "action": "block", "enabled": true }, { "id": "pii-ccn", "name": "Credit Card Number", "tier": 1, "action": "redact", "enabled": false } ]}POST /admin/api/rules/{rule_id}/toggle
Section titled “POST /admin/api/rules/{rule_id}/toggle”Enables or disables a specific DLP rule. The change takes effect immediately for all subsequent requests.
POST /admin/api/rules/{rule_id}/toggleAuthorization: Bearer <token>Content-Type: application/json
{ "enabled": false}Response
{ "rule_id": "pii-ccn", "enabled": false}GET /admin/api/rulesets
Section titled “GET /admin/api/rulesets”Lists all DLP compliance rulesets (compliance_bundles in the policy bundle) with their enabled/disabled state.
GET /admin/api/rulesetsAuthorization: Bearer <token>Response
{ "rulesets": [ { "id": "hipaa", "name": "HIPAA PHI", "enabled": true }, { "id": "pci-dss", "name": "PCI DSS", "enabled": false } ]}POST /admin/api/rulesets/{ruleset_id}/toggle
Section titled “POST /admin/api/rulesets/{ruleset_id}/toggle”Enables or disables an entire compliance ruleset. Disabling a ruleset suppresses all rules within it.
POST /admin/api/rulesets/{ruleset_id}/toggleAuthorization: Bearer <token>Content-Type: application/json
{ "enabled": false}Response
{ "ruleset_id": "pci-dss", "enabled": false}Routing and kill switch
Section titled “Routing and kill switch”POST /admin/api/routing-override
Section titled “POST /admin/api/routing-override”Pins all traffic to a specific provider, or clears an existing routing override.
POST /admin/api/routing-overrideAuthorization: Bearer <token>Content-Type: application/json
{ "provider": "anthropic"}To clear the routing override and restore policy-default routing, set provider to null:
{ "provider": null}Response
{ "routing_override": "anthropic"}Returns 400 if the provider name is not in the policy bundle.
POST /admin/api/emergency-kill
Section titled “POST /admin/api/emergency-kill”Activates or deactivates the emergency kill switch. When active, all LLM requests are rejected immediately with 503 — no DLP evaluation, no provider contact.
POST /admin/api/emergency-killAuthorization: Bearer <token>Content-Type: application/json
{ "active": true}To deactivate:
{ "active": false}Response
{ "emergency_kill": true}Prompt holds
Section titled “Prompt holds”Prompt holds are raised when the DLP pipeline flags a request for human review. Holds are in-memory only — they do not persist across outpost restarts.
GET /admin/api/prompt-holds
Section titled “GET /admin/api/prompt-holds”Lists all prompt holds (pending and resolved).
GET /admin/api/prompt-holdsAuthorization: Bearer <token>Response
{ "holds": [ { "hold_id": "hold_abc123", "status": "pending", "created_at": "2026-03-12T09:00:00Z", "prompt_length": 842, "user_id": "u-xyz", "rule_ids": ["custom-secret-leak"] } ], "pending_count": 1}POST /admin/api/prompt-holds/{hold_id}/approve
Section titled “POST /admin/api/prompt-holds/{hold_id}/approve”Approves a pending prompt hold, forwarding the held request to the LLM.
POST /admin/api/prompt-holds/{hold_id}/approveAuthorization: Bearer <token>Returns 404 if the hold is not found or already resolved.
Response
{ "hold_id": "hold_abc123", "decision": "approve"}POST /admin/api/prompt-holds/{hold_id}/deny
Section titled “POST /admin/api/prompt-holds/{hold_id}/deny”Denies a pending prompt hold, returning an error to the requesting client.
POST /admin/api/prompt-holds/{hold_id}/denyAuthorization: Bearer <token>Returns 404 if the hold is not found or already resolved.
Response
{ "hold_id": "hold_abc123", "decision": "deny"}GET /admin/api/prompt-holds/events
Section titled “GET /admin/api/prompt-holds/events”Server-Sent Events (SSE) stream. Emits prompt_hold events in real time as new holds arrive. Backlogs all current pending holds on initial connect.
GET /admin/api/prompt-holds/eventsAuthorization: Bearer <token>Accept: text/event-streamEvent format
data: {"type": "prompt_hold", "hold_id": "hold_abc123", "status": "pending", ...}The stream remains open until the client disconnects. Suitable for admin UI integrations.
GET /admin/api/usage
Section titled “GET /admin/api/usage”Returns the current-period usage summary from the outpost’s local usage tracker (when usage tracking is enabled via policy bundle).
GET /admin/api/usageAuthorization: Bearer <token>Response (tracking enabled)
{ "usage_tracking": "enabled", "totals": { "request_count": 4821, "input_tokens": 72300, "output_tokens": 18100, "cost_estimate": 0.31 }, "budget_config": { "monthly_request_limit": 50000, "alert_pct": 80 }}Response (tracking disabled)
{ "usage_tracking": "disabled", "totals": null, "budget_config": null}Policy simulation
Section titled “Policy simulation”POST /admin/api/policy/simulate
Section titled “POST /admin/api/policy/simulate”Runs a synthetic prompt through the local DLP pipeline and returns a full evaluation trace. Read-only — no request is forwarded to any LLM, no usage is recorded, and the prompt text is not written to the audit log (only its length is logged).
POST /admin/api/policy/simulateAuthorization: Bearer <token>Content-Type: application/json
{ "prompt": "My SSN is 123-45-6789, please help me...", "provider": "anthropic", "model": "claude-sonnet-4-6", "org_id": "b3e2a1c0-..."}| Field | Required | Description |
|---|---|---|
prompt | Yes | Text to evaluate |
provider | No | Provider to use for rule-provider matching |
model | No | Model ID for model-specific rules |
org_id | No | Defaults to the outpost’s configured org_id |
Returns 503 if no policy bundle is loaded.
Response — see Policy Simulator guide for full response schema.
Audit buffer
Section titled “Audit buffer”GET /admin/api/audit-buffer
Section titled “GET /admin/api/audit-buffer”Returns the last 200 events from the local JSONL audit buffer on disk. Useful for immediate review without exporting to a SIEM.
GET /admin/api/audit-bufferAuthorization: Bearer <token>Response
{ "events": [ { "timestamp": "2026-03-12T09:00:01Z", "action": "proxy_request", "user_id": "u-xyz", "provider": "anthropic", "model": "claude-sonnet-4-6", "dlp_result": "pass", "latency_ms": 210 } ], "total": 47}total reflects the number of events in the response (up to 200), not the total events in the file.
Credential Intelligence
Section titled “Credential Intelligence”GET /admin/api/credint/status
Section titled “GET /admin/api/credint/status”Returns bloom filter status: whether the filter is loaded, entry count, snapshot date, target false-positive rate, and file size.
GET /admin/api/credint/statusAuthorization: Bearer <token>Response (filter loaded)
{ "enabled": true, "loaded": true, "entry_count": 1200000, "loaded_at": 1741780000.0, "file_size_bytes": 2097152, "snapshot_date": "2026-03-01", "fpr_target": 0.1}Response (filter not configured)
{ "enabled": false, "loaded": false, "entry_count": 0, "loaded_at": null, "file_size_bytes": 0, "snapshot_date": "", "fpr_target": 0.0}loaded_at is a Unix timestamp (float). fpr_target is the false-positive rate the filter was built to achieve (e.g. 0.1 = 10%).
POST /admin/api/credint/reload
Section titled “POST /admin/api/credint/reload”Reloads the CredInt bloom filter from the path configured in CREDINT_BLOOM_PATH. Hot-swaps the in-memory filter without an outpost restart. Returns success/failure and the new entry count.
POST /admin/api/credint/reloadAuthorization: Bearer <token>No request body required.
Response (success)
{ "success": true, "message": "Bloom filter reloaded", "entry_count": 1300000}Response (scanner not configured)
{ "success": false, "message": "CredInt scanner not configured"}If reload fails (corrupt file, I/O error), the existing in-memory filter remains active (fail-open). Check outpost logs for the error details.
Error responses
Section titled “Error responses”| Status | Cause |
|---|---|
401 | Missing Authorization header, or empty token |
403 | Invalid admin API key |
404 | Resource not found (provider, rule, hold, etc.) |
429 | Brute-force rate limit exceeded — 5 failed auth attempts within 15 minutes |
500 | Unhandled server error or uninitialised component |
503 | Required component not initialised (e.g. no policy bundle loaded) |
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
| GET | /admin/api/status | Outpost operational status |
| GET | /admin/api/sync-status | Policy sync and heartbeat status |
| GET | /admin/api/airgap-config | Air-gap configuration (read-only) |
| GET | /admin/api/providers | List providers with override state |
| POST | /admin/api/providers/{provider}/disable | Disable a provider |
| POST | /admin/api/providers/{provider}/enable | Re-enable a provider |
| GET | /admin/api/rules | List DLP rules with toggle state |
| POST | /admin/api/rules/{rule_id}/toggle | Enable or disable a DLP rule |
| GET | /admin/api/rulesets | List compliance rulesets with toggle state |
| POST | /admin/api/rulesets/{ruleset_id}/toggle | Enable or disable a ruleset |
| POST | /admin/api/routing-override | Pin or clear routing override |
| POST | /admin/api/emergency-kill | Activate/deactivate emergency kill switch |
| GET | /admin/api/prompt-holds | List all prompt holds |
| POST | /admin/api/prompt-holds/{hold_id}/approve | Approve a prompt hold |
| POST | /admin/api/prompt-holds/{hold_id}/deny | Deny a prompt hold |
| GET | /admin/api/prompt-holds/events | SSE stream of prompt hold events |
| GET | /admin/api/usage | Local usage summary |
| POST | /admin/api/policy/simulate | Run policy simulation |
| GET | /admin/api/audit-buffer | Last 200 local audit events |
| GET | /admin/api/credint/status | CredInt bloom filter status |
| POST | /admin/api/credint/reload | Reload CredInt bloom filter |
See also
Section titled “See also”- Outpost architecture overview — port layout and admin network isolation
- Credential Intelligence guide — bloom filter setup and CDN refresh
- Policy Simulator guide — detailed simulate response schema
- DLP configuration reference — rule and ruleset IDs