agent_auth grant). Issuance still always requires a
human to approve — there is no anonymous or instant credential.
This is the machine-readable counterpart to the
agent authentication guide served for agents at
visiqlabs.com/auth.md. The flow is advertised in the agent_auth block of
/.well-known/oauth-authorization-server.When to use it
- Your agent runs somewhere an operator cannot pre-provision a key, but a human can approve a one-time request.
- You want the credential bound to the approving human’s account and scoped to exactly what they agree to — never broader than their own permissions.
The flow at a glance
- Agent → VisIQ:
POST /api/agent/identityto register. - VisIQ → Agent: returns a
claim_token, a shortuser_code, and a verification URL. - Agent → Human: show the operator the
user_code/verification_uri_complete. - Human → VisIQ: the operator signs in, opens the URL, reviews the requested audience and permissions, and approves.
- Agent → VisIQ (poll):
POST /api/agent/identity/claimeveryintervalseconds —400 authorization_pendinguntil approved. - VisIQ → Agent: once approved, the
api_keyis returned exactly once.
Step 1 — Register
POST https://app.visiqlabs.com/api/agent/identity
Omitting
requested_permissions requests the default product grant below.
The default grant never includes account administration: a key minted from the
default grant cannot manage API keys, the team, or billing.
dashboard:viewallow_rules:viewallow_rules:createallow_rules:updateallow_rules:deleterecall_rules:viewrecall_rules:createrecall_rules:updaterecall_rules:deleteallow_agents:viewallow_agents:createallow_agents:updateallow_agents:deleteallow_audit_log:viewrecall_audit_log:viewrecord_records:viewrecord_audit_log:viewaudit_log:viewevents:viewallow_hitl:viewallow_hitl:respondallow_settings:viewallow_settings:update
requested_permissions list may name any permission in the
catalogue, account administration included. The approver sees the full list
before approving, and the grant is always bounded by what the approver holds:
nobody can approve a permission they do not have themselves.
Registration is rate-limited per client IP (10 per minute and 100 per hour,
counted across every VisIQ server). Over the limit you get
429 {"error": "rate_limited"} with a Retry-After header; if the limiter
itself cannot answer, you get 503 {"error": "temporarily_unavailable"} and
should retry later.
The response is a device-flow ceremony:
claim_token private — it is what you exchange for the key in Step 3.
Show the human the user_code / verification_uri.
Step 2 — Have a human approve
Show your operator theverification_uri_complete — a single clickable link
with the code already embedded (RFC 8628 one-click); the code survives the
sign-in / MFA detour and the approval page auto-loads your pending registration.
Fall back to the bare verification_uri plus the typed user_code if a
one-click link is not usable.
They sign in to VisIQ, open the URL, review the requested audience and
permissions, and approve. Approval is for signed-in people only: a request to
the approval endpoint made with an API key (management keys included) is refused
with 403, so one agent can never approve another. Approval mints a governed key bound to their account
— harness by default, management if you requested it and they agreed. They can
narrow the grant, and can never grant beyond their own permissions.
Step 3 — Poll for the credential
POST https://app.visiqlabs.com/api/agent/identity/claim, every interval
seconds, with your claim_token:
400). Keep polling at interval seconds. If you poll sooner than that,
you get slow_down instead (RFC 8628 section 3.5), also HTTP 400, carrying
the new, longer interval to use from then on:
slow_down adds 5 seconds, up to 60. Once approved, you receive the
credential exactly once, whatever your polling pace:
key_typetells you which audience was actually granted (harnessormanagement).- For a management key,
permissionsis the exact grant list your credential holds; it isnullfor a harness key.
user_code.
Then use the key as a Bearer token — see
Use a key.
Revoking
You can retire a device-flow credential yourself, at any time:-
Cancel or revoke the device-flow credential —
POST https://app.visiqlabs.com/api/agent/identity/revokewith{ "token": "vq_prod_..." }(an issued key) or{ "claim_token": "vqac_..." }(the pending ticket, which also revokes an already-issued key). An unknown or already-revoked token still gets200, so the endpoint never reveals whether a token existed. If the revoke could not be completed you get503 {"error": "temporarily_unavailable"}: treat the key as still live and retry. Revoking a live key is recorded in the approving account’s audit log asAGENT_KEY_REVOKED(a denied registration is recorded asAGENT_REGISTRATION_DENIED, an issued key asAGENT_KEY_ISSUED). -
Self-revoke any key you hold —
POST /allow/self/revoke, authenticated by the key itself, no permission required. See Revoke your own key.
Prefer MCP?
Once you hold a management key you can operate VisIQ through the Platform MCP server instead of raw REST — including retiring the key with therevoke_self tool when you are done.