Web app
Tour of the web app
The web app is the shared screen for the people who review what your agents did: findings to triage, calls waiting for a human, policies to promote, evidence to hand an auditor.
When to use the web app, and when the CLI
The web app is a client of the gateway's public HTTP API. It has no database access of its own: every page is a set of /api/… calls, and every button posts to one. Anything you can see in it, a script can fetch with a token.
The CLI mostly works on the database directly: the one in your state directory, or the one AGENTFOX_DATABASE_URL names. On a self-hosted deployment, run CLI commands where they can reach the gateway's database and both show the same data. An agent registered in the web app appears in agentfox agents list straight away, and the reverse. On a hosted workspace, the CLI commands on these pages apply to your own local install; the HTTP routes are what reach the workspace.
- Use the web app for queues a person works through (findings, approvals, hand-offs), for editing a policy with a simulation in front of you, and for anything a non-engineer has to read: compliance status, the board snapshot, evidence packages.
- Use the CLI in CI, in scripts, and for the things the web app has no screen for: capability grants (agentfox permit grant), tool declarations, and change proposals.
Run it on your own machine
The web app lives in dashboard/ in the repository. It needs a running gateway and a signed-in session. This is the shortest path to looking at it with data in it, and it is what these pages were checked against.
Load demo data and record some traffic
--demoloads three agents, their tools and grants, an eval suite and five users. It records no traffic: until something runs, Overview says nothing is connected.agentfox demoruns the offline walkthrough, which records traces, decisions, findings and approvals.bash agentfox init --demo agentfox demoOutput Setting up AgentFox ✓ database ready … ✓ 43 controls across 7 frameworks v0.1.0-draft (draft) ✓ 3 policy pack(s) loaded baseline observe recorded, nothing blocked eu-ai-act-high-risk observe recorded, nothing blocked tool-containment enforce violations are blocked now … ✓ wrote agentfox.toml ✓ demo fixtures loaded agents, policies and an eval suite; no traffic yet. `agentfox demo` sends sample requests through them. … ╭───────────────────────────────────────────────╮ │ Walkthrough complete. │ │ agentfox serve control plane on :8080 │ │ agentfox report verify re-check the chain │ │ agentfox report evidence --agent payments-ops │ ╰───────────────────────────────────────────────╯ baseline policy restored to observe — the demo's promotion was temporary.Start the gateway
bash agentfox serveOutput AgentFox 0.3.1 → http://127.0.0.1:8080 inline: POST http://127.0.0.1:8080/v1/chat/completions api: http://127.0.0.1:8080/api/agents docs: http://127.0.0.1:8080/docsMint a token for a user that exists
The demo seed creates
admin@example.comas the workspace owner. A token is only ever shown once.bash agentfox admin auth issue admin@example.com --name dashboardOutput ╭─ Token issued — copy it now ───────────────────────────────────╮ … │ dashboard · admin@example.com · owner · org org_default │ │ expires 2027-10-05T15:16:22.155630+00:00 │ ╰─────────────────────────────────────────────────────────────────╯ Only a hash is stored. There is no way to show this value again — issue a new token if it is lost.Start the web app
bash cd dashboard npm install AGENTFOX_API_URL=http://127.0.0.1:8080 npm run devIt serves on
http://localhost:3000. Without a session every/apppage redirects to/login.Sign in
Sign-in is GitHub only (next section). On a laptop with no GitHub OAuth app, the button answers with a 503:
bash curl -s http://localhost:3000/api/auth/github/loginOutput {"error":"GitHub sign-in is not configured (GITHUB_CLIENT_ID is unset)."}For a local evaluation only, the session is the token itself, held in a cookie named
agentfox_session. Openhttp://localhost:3000/login, then in the browser console:browser console document.cookie = "agentfox_session=<the token from step 3>; path=/"; location.href = "/app";
Signing in, workspaces and roles
Continue with GitHub on /login is the only way in. There is no password and no separate sign-up. The same grant lets the app list and scan your repositories, so it asks GitHub for repo read:user user:email.
- GitHub sends you back to
/api/auth/github/callback. The web app reads your profile and email. - It calls the gateway's
POST /api/auth/github/provision, signed with a shared service secret. The gateway looks you up by GitHub user id. A GitHub identity it has never seen gets a brand-new workspace (an org), with you as itsowner, and the control catalog and obligation calendar are loaded into it so Compliance is not empty. - The gateway mints an API token named
github-login(365 days). The web app stores it in an httpOnly cookie, and every page you load calls the gateway with it, so the workspace scoping is the gateway's, not the browser's. - The GitHub access token is stored encrypted against your workspace for repository scans, and you land on Start here → Connect.
- One GitHub identity is one workspace. There is no invite flow. Two colleagues who sign in separately get two workspaces that cannot see each other's data.
- The account menu (top right) shows who you are signed in as, the workspace (your GitHub login once GitHub is connected, otherwise the org id) and your role.
- Roles decide what a button may do. The gateway enforces them on every request, whatever the page shows:
ownerandadmincan do everything;securitycan also kill or resume agents, decide approvals, create suppressions and change judgment posture;developercan register agents, quarantine them and edit policies;compliancecan review framework mappings and record risk assessments;auditorcan build evidence. A refused action comes back as an error banner on the page you were on. - Sign out deletes the cookie. It does not revoke the
github-logintoken, and every sign-in mints another one. Revoke old ones on API tokens. - When the gateway rejects your session, a page shows "Your session has expired" with a Sign in again link that clears the cookie.
Hosted or self-hosted
Whether a hosted workspace is open to you right now, and on what terms, is stated on the pricing page. Self-hosting the web app is always available: it is the dashboard service in deploy/docker-compose.yml (port 3000), the Render blueprint, or npm run build && npm start in dashboard/. See Self-hosting for the stack. These are the settings the web app itself reads:
| Setting | Where | What it does |
|---|---|---|
AGENTFOX_API_URL (or AGENTFOX_API_URL) | web app | The gateway, as the web app's server reaches it. Default http://127.0.0.1:8080. |
AGENTFOX_PLAYGROUND_API_URL | web app | The gateway as a visitor's browser reaches it, for /playground only. Falls back to the API URL. |
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET | web app | Your GitHub OAuth app. Its callback must be https://<host>/api/auth/github/callback, exactly. |
AGENTFOX_SERVICE_AUTH_SECRET | both, identical | Signs the provisioning call. If it is still the built-in development value, anyone can mint accounts on your gateway. |
AGENTFOX_TOKEN_ENCRYPTION_KEY | gateway | Encrypts stored GitHub tokens. Unset, connecting GitHub fails closed with a 503. |
AGENTFOX_PLAYGROUND_CORS_ORIGIN | gateway | Comma-separated origins allowed to call the playground routes from a browser. |
AGENTFOX_SELF_HOSTED | web app | Shows the "start the gateway" hint when the API is unreachable. On by default when the API URL is localhost. |
The sidebar
Every item, what you go there for, and the closest command. Where a cell says HTTP, there is no CLI command; the route is in the HTTP API reference.
| Item | Go there to | Closest command |
|---|---|---|
Overview /app | See what needs a person, most severe first. | agentfox findings |
Start here /app/start | Work through setup, connect a repo or API, mint tokens. | agentfox init, agentfox admin auth issue |
| Discover | ||
Agents /app/agents | The register: owners, risk, boundary, kill switch. | agentfox agents list |
Verified sources /app/sources | Tier the data agents answer from; connect and validate it. | agentfox declare source |
| Monitor | ||
Threat coverage /app/coverage | Each OWASP LLM Top 10, OWASP Agentic and MITRE ATLAS threat, and whether a rule enforces against it, only watches, or nothing does. A threat counts as covered only when a rule enforces it. ?window= sets the day window (30 by default). | HTTP: GET /api/coverage/threats |
Findings /app/findings | Triage, resolve or suppress what was detected. | agentfox findings |
Traces /app/traces | One request taken apart, and why it was blocked. | HTTP: GET /api/traces |
| Test | ||
Evaluation /app/evals | Suites, runs, SLOs, drift, red-team campaigns. | agentfox test run, agentfox test redteam |
| Govern | ||
Policies /app/policies | Rules and modes, simulation, canary, detector tuning, judgment posture. | agentfox policy list |
Access control /app/entitlement | Who a shared agent is answering for, and what they may see. | agentfox declare principal, agentfox permit user |
Approvals /app/approvals | Decide held tool calls; work the hand-off queue. | HTTP for approvals; agentfox report escalations |
Compliance /app/compliance | Controls, frameworks, risk register, evidence, legal hold, board snapshot. | agentfox report status |
The theme control sits at the foot of the sidebar: Light, Match system, Dark. It is the same control as on the public site and is remembered in this browser only. /app/glossary defines every term the app uses; it is not in the sidebar, but search finds it.
Overview
In the web app Overview
Overview answers one question: is anything wrong right now. It has two states.
- Nothing is sending traffic yet. Shown until the gateway has recorded a single trace. It shows the one line that starts recording (
import agentfox; agentfox.auto()), a link to Start here, and the coverage strip below. - Connected. If nothing needs attention you see "Nothing needs attention" with the number of governed traces and enforced decisions. Otherwise:
| Panel | What it shows | Source |
|---|---|---|
| Four stat cards | Critical and high-priority items needing attention; decisions with a block verdict in the last 24 hours ("stopped automatically"); decisions made in observe mode in the same window ("flagged but allowed"). They count what detectors found in text; tool containment is on Policies. | GET /api/attention |
| Needs attention | The six most severe items: open findings, hand-offs past their SLA, and agents sending traffic that were never registered. Identical findings fold into one row marked ×N. Each row links to the finding, the escalation tab or the agent. | GET /api/attention |
| What is switched on | Policy rules enforcing out of all rules, detectors running, attack simulations available, and controls effective out of those assessed. Each number links to the page that lists them. | /api/policies, /api/detectors, /api/redteam/probes, /api/compliance/status |
| Inventory | Agents, unregistered, without an owner, knowledge boundaries, control effectiveness. | /api/agents, /api/onboarding |
| Next | The first unfinished step of the Start here checklist. | GET /api/onboarding |
The attention queue does not cover the Compliance risk register or agents without a risk assessment; the board snapshot does.
Top bar: counts, search, notifications, account
- Critical / high counts are the same numbers as the first two Overview cards, visible on every page.
- Search opens with
⌘Kon macOS orCtrl+Kelsewhere, and the same key closes it; so doesEsc. Arrow keys move, Enter opens. It matches page names and their group, including entries that are tabs rather than sidebar items: Connect GitHub, Connect a hosted API, API tokens, Guardrail tuning, Judgment posture, Egress, Escalation, Board view, OWASP LLM Top 10, OWASP Agentic, MITRE ATLAS and Glossary. Paste a trace id (trc_…) or a finding id (fnd_…) and the first result jumps straight to it. It does not search the contents of records. - Notifications (the bell) is the attention queue from Overview: the badge is the total, the list shows the six most severe. When it is empty it says so, and points at the board snapshot for what it does not cover.
- Account menu: signed-in email, workspace, role, and links to Connect, API tokens, the public site, and Sign out.
Telling demo data apart
Records made by the demo seed carry a grey sample data tag: agents (on the list and the agent page), verified sources, and hand-offs whose conversation id starts with seed-. The board snapshot says how many of the agents it counts are sample data.
Traffic recorded by agentfox demo is not tagged. Its findings, traces, decisions and approvals belong to the demo agents (support-triage, payments-ops, hr-screening) and to an unregistered marketing-copy-bot, and its red-team findings name tools starting redteam.sim.. To start clean, point the gateway at a new state directory or database and run agentfox init without --demo.
Common tasks
| You want to | Run |
|---|---|
| Get a local web app with data in it | agentfox init --demo |
| Record demo traffic so Overview fills in | agentfox demo |
| Start the gateway the web app talks to | agentfox serve |
| Mint a token for a seeded user | agentfox admin auth issue admin@example.com --name dashboard |
| See the same queue as Overview in a terminal | agentfox findings |
| Jump to a trace or finding by id | ⌘K, paste the id |
What can go wrong
- Every
/apppage sends you to/login. There is no session cookie. Sign in, or on a local instance set the cookie as above. - "Control-plane API unreachable." The web app cannot reach
AGENTFOX_API_URL. Check the gateway is up withcurl http://127.0.0.1:8080/api/health. - "Your session has expired." The token in the cookie was revoked, expired, or belongs to another gateway. Sign in again.
- Sign-in fails at "could not provision an account". The service secret differs between the web app and the gateway.
- Overview stays on "Nothing is sending traffic yet" after
--demo. The seed records no traces. Runagentfox demo, or govern a real agent.
Limits
- No invite flow and no shared workspaces; one GitHub identity, one workspace.
- No sign-in other than GitHub.
- Some areas have no screen: capability grants, tool declarations and change proposals are CLI and HTTP only. The pages that mention them say so.
- A few in-app hints still show command names from before the CLI was consolidated. They run as hidden aliases; these docs give the current names.