Getting Started
Getting Started — Agent Identity & Policy Gateway (15-minute quickstart)
This guide gets you from zero → first trace logged.
What you’ll do
- Sign up / sign in
- Create an agent + tool
- Create an API key
- Call POST /api/decision
- If needed: complete an approval (needs_approval) and capture the session token
- Confirm the trace appears in /decision-logs
- Generate an Autopilot recommendation
- Replay a draft policy and understand the output
Security reminders (always)
- Never paste real secrets or production data into chat.
- Use environment variables for secrets (never hardcode).
- Never commit secrets to GitHub.
- API keys must never be stored plaintext in the database (hash only).
- Do not log (treat it like a bearer credential).
session_token- OWASP session guidance: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
1) Sign up / Sign in
- Open the app in your browser:
- Production: <PROD_URL>
- Sign up or sign in.
What success looks like:
- You land on /dashboard.
2) Create an Agent
- Open: /agents
- Click Create
- Fill in:
- Key:
customer_support_agent - Name:
Customer Support Agent - Active: enabled/true
- Key:
- Save
What success looks like:
- The agent appears in the list and shows as active.
3) Create a Tool
- Open: /tools
- Click Create
- Fill in:
- Key:
reset_password_api - Name:
Reset Password API - Category:
account - Sensitivity: choose a reasonable value (keep default if unsure)
- Active: enabled/true
- Key:
- Save
What success looks like:
- The tool appears in the list and shows as active.
4) Create an API key
- Open: /api-keys
- Click Create
- Give it a name like:
Local testing - Create and copy the key shown (this is the ONLY time you’ll see the full key)
What success looks like:
- You have an API key value saved somewhere secure.
5) Call POST /api/decision (copy/paste)
You’ll need:
- <CONSOLE_URL> (example: https://console.agenttrust.io)
- <GATEWAY_URL> (example: https://gateway.agenttrust.io)
- <API_KEY> (the API key you created above)
IMPORTANT:
- This API requires the header x-api-key
- The tenant is derived from the hash of x-api-key (never from request body)
Option A — curl (works in most terminals)
GATEWAY_URL="<GATEWAY_URL>"
API_KEY="<API_KEY>"
curl -s -X POST "$GATEWAY_URL/api/decision" \
-H "content-type: application/json" \
-H "x-api-key: $API_KEY" \
-d '{
"agentId": "customer_support_agent",
"toolId": "reset_password_api",
"environment": "dev",
"userId": "alice@example.com",
"params": { "ticketId": "T-1001" }
}'
Option B — PowerShell (Windows)
$GATEWAY_URL = "<GATEWAY_URL>" $API_KEY = "<API_KEY>" $body = @{ agentId = "customer_support_agent" toolId = "reset_password_api" environment = "dev" userId = "alice@example.com" params = @{ ticketId = "T-1001" } } | ConvertTo-Json -Depth 5 Invoke-RestMethod -Method Post ` -Uri "$GATEWAY_URL/api/decision" ` -Headers @{ "x-api-key" = $API_KEY } ` -ContentType "application/json" ` -Body $body
What success looks like
You get a 200 response with JSON containing:
- :
outcome|"allow"|"deny""needs_approval" decision_idtraceIdrequestId- (when matched)
policy_version_id
Additional fields by outcome:
- If :
outcome: "allow"- a session is created immediately and a is returned
session_token
- a session is created immediately and a
- If :
outcome: "needs_approval"approval_request_idapproval_expires_atapproval_status: "pending"
Note: If no policies match yet, you will typically see a deny outcome by default. Even for deny, you should still get traceId / requestId and a trace row logged.
5A) If outcome is allow
When
outcome: "allow"- The response includes a .
session_token - Treat this token like a bearer credential.
- Store it immediately (secrets manager / encrypted storage).
- Do not log it.
5B) If outcome is needs_approval (approval flow)
When
outcome: "needs_approval"- Copy and store:
approval_request_idapproval_expires_at
- Poll the status endpoint until it becomes terminal:
- (session exists)
approved - (terminal)
denied - (terminal)
expired
Poll approval status (agent caller)
GATEWAY_URL="<GATEWAY_URL>"
API_KEY="<API_KEY>"
APPROVAL_ID="<APPROVAL_ID>"
curl -sS "$GATEWAY_URL/api/approvals/$APPROVAL_ID/status" \
-H "x-api-key: $API_KEY"
Status values:
- — not yet approved
pending - — session exists; token may be issued
approved - — terminal
denied - — terminal
expired
One-time token issuance (important)
When the approval becomes
approvedsession_token- The first poll after approval may include (plaintext).
session_token - Subsequent polls return .
session_token: null - The gateway stores only a token hash/prefix and does not store the plaintext token.
Client requirement: the caller must persist the token immediately on first receipt.
If you miss it, you cannot recover it from the gateway — create a new approval request.
(Reference: PostgREST RPC model used by Supabase: https://docs.postgrest.org/en/stable/references/api/functions.html)
Approve/deny from the Console (admin/owner)
Resolution is performed from the Console domain using Supabase user auth.
Pre-reqs:
- You are logged into <CONSOLE_URL>
- Your user is an admin/owner for the active tenant
Temporary dev method (until an approvals UI is present):
Open browser DevTools Console on <CONSOLE_URL> and run:
const approvalId = "<APPROVAL_ID>";
fetch(`/api/approvals/${approvalId}/resolve`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ resolution: "approve", note: "ok" }),
})
.then(async (r) => ({ status: r.status, body: await r.text() }))
.then(console.log);
Supabase server-side auth patterns (cookie-based SSR): https://supabase.com/docs/guides/auth/server-side
6) Confirm the trace in /decision-logs
- Open: /decision-logs
- Use filters to find your request:
- Paste your traceId or requestId into the filter/search (if available)
- Or filter by agent/tool/environment
What success looks like: You can see a log row for the request you just made.
7) Generate Autopilot recommendation
- Open: /policies
- In the Autopilot panel, generate a recommendation
- Use the default time window (last 7 days) unless you have a reason to change it
- Optionally set environment to dev
What success looks like: You see a recommended policy (typically an allowlist) based on historically allowed traces. If “save as draft” is enabled, saving works and produces a draft policy (inactive).
Important: v1 recommend scans historically ALLOWED traces in the selected window.
8) Replay a draft policy and understand the output
- In /policies, select a draft policy
- Run Replay for a recent window
What success looks like:
- You see counts like:
- wouldAllow / wouldDeny
- wouldDenyButWasAllowed (breakage)
- wouldAllowButWasDenied (new access)
- You see sample rows for breakage/new access (when applicable)
Replay limitation (important): Replay evaluates param constraints when
decision_traces.trace.paramsTroubleshooting quick tips
- 401 (decision/status): missing/blank x-api-key header (error.code = MISSING_API_KEY)
- 401 (status): invalid/inactive x-api-key (error.code = INVALID_API_KEY)
- 400: unknown/inactive agent/tool (check you used the Key values and they’re active)
- 400: invalid approval ID format (error.code = INVALID_APPROVAL_ID)
- 409 (resolve): approval already terminal (approved/denied/expired)
- 410 (resolve): approval expired (status becomes terminal)
- 500: fail-closed — treat as a safety stop and investigate logs/DB connectivity
Prefer the in-app version? Open:
- /getting-started
Prefer GitHub docs? You are here:
- docs/getting-started.md