Skip to content
Docs

Getting Started

Getting Started — Agent Identity & Policy Gateway (15-minute quickstart)

This guide gets you from zero → first trace logged.

What you’ll do

  1. Sign up / sign in
  2. Create an agent + tool
  3. Create an API key
  4. Call POST /api/decision
  5. If needed: complete an approval (needs_approval) and capture the session token
  6. Confirm the trace appears in /decision-logs
  7. Generate an Autopilot recommendation
  8. Replay a draft policy and understand the output

Security reminders (always)


1) Sign up / Sign in

  1. Open the app in your browser:
    • Production: <PROD_URL>
  2. Sign up or sign in.

What success looks like:

  • You land on /dashboard.

2) Create an Agent

  1. Open: /agents
  2. Click Create
  3. Fill in:
    • Key:
      customer_support_agent
    • Name:
      Customer Support Agent
    • Active: enabled/true
  4. Save

What success looks like:

  • The agent appears in the list and shows as active.

3) Create a Tool

  1. Open: /tools
  2. Click Create
  3. Fill in:
    • Key:
      reset_password_api
    • Name:
      Reset Password API
    • Category:
      account
    • Sensitivity: choose a reasonable value (keep default if unsure)
    • Active: enabled/true
  4. Save

What success looks like:

  • The tool appears in the list and shows as active.

4) Create an API key

  1. Open: /api-keys
  2. Click Create
  3. Give it a name like:
    Local testing
  4. 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:

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_id
  • traceId
  • requestId
  • policy_version_id
    (when matched)

Additional fields by outcome:

  • If
    outcome: "allow"
    :
    • a session is created immediately and a
      session_token
      is returned
  • If
    outcome: "needs_approval"
    :
    • approval_request_id
    • approval_expires_at
    • approval_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"
:

  1. Copy and store:
    • approval_request_id
    • approval_expires_at
  2. Poll the status endpoint until it becomes terminal:
    • approved
      (session exists)
    • denied
      (terminal)
    • expired
      (terminal)

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:

  • pending
    — not yet approved
  • approved
    — session exists; token may be issued
  • denied
    — terminal
  • expired
    — terminal

One-time token issuance (important)

When the approval becomes

approved
, the status endpoint issues
session_token
exactly once:

  • The first poll after approval may include
    session_token
    (plaintext).
  • 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

  1. Open: /decision-logs
  2. 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

  1. Open: /policies
  2. 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

  1. In /policies, select a draft policy
  2. 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.params
is present. Limitation: traces that do not include params cannot be validated against param constraints.


Troubleshooting 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