---
title: "EvalGate agent credential handoff"
description: "Start a non-browser agent setup request, obtain human OAuth approval, and retrieve a scoped EvalGate API key once."
canonical: "https://www.evalgate.com/agent/setup"
last-updated: "2026-09-18"
---

# EvalGate agent credential handoff

Use this flow when an agent can make HTTPS requests but cannot complete an interactive GitHub or Google sign-in. The person still authenticates through an existing social OAuth provider and approves the exact organization and requested scopes. EvalGate supports both an RFC 8628 device grant and a JSON compatibility adapter.

## 1. Start

Standards-based clients discover `/.well-known/oauth-authorization-server` and POST form-encoded `client_id=evalgate-agent` plus a space-separated `scope` to `/oauth/device/authorization`. JSON-only clients may use:

```bash
curl -X POST https://www.evalgate.com/api/agent-setup/start \
  -H 'Content-Type: application/json' \
  --data '{"client_name":"repository assistant","requested_scopes":["eval:read","runs:read","traces:write"]}'
```

The response contains `device_code`, `user_code`, `verification_uri`, `verification_uri_complete`, `expires_in`, and `interval`. Codes expire after ten minutes.

## 2. Ask a person to approve

Show the person both `verification_uri` and `user_code`. They open the URI, sign in with GitHub or Google, choose or create the accountable workspace, confirm that the displayed code matches, review every scope, and approve or deny the request.

## 3. Poll

RFC 8628 clients poll `/oauth/token` with the device grant, device code, and `client_id=evalgate-agent`. JSON clients wait at least `interval` seconds between calls:

```bash
curl -X POST https://www.evalgate.com/api/agent-setup/poll \
  -H 'Content-Type: application/json' \
  --data '{"device_code":"<device_code>"}'
```

Approval returns the same opaque, organization-scoped bearer API key exactly once. Denied, expired, and already-consumed handoffs never return a credential. Store the key in a secret manager and send it as `Authorization: Bearer <key>`.

## Safe test mode

After pickup, call public MCP `server/discover`, authenticated `tools/list`, and read-only `project.plan`. Those MCP operations invoke no model provider and no billable hosted evaluation. `evalgate gate --offline` separately blocks built-in/configured provider-backed checks, but custom project code can still use the network and hard command isolation depends on Linux `unshare`. Neither path is a production-like sandbox.

## Security boundary

Start and poll are rate-limited and do not create identities or keys anonymously. Device and human lookup codes are stored as hashes. The one-time key is encrypted while awaiting pickup, bound to the approving organization, limited to the reviewed non-administrative scopes, expires after 90 days, and is deleted from the handoff after delivery.

- [Account requirements](https://www.evalgate.com/signup.md)
- [Full authentication walkthrough](https://www.evalgate.com/auth.md)
- [OpenAPI](https://www.evalgate.com/openapi.json)
