> ## Documentation Index
> Fetch the complete documentation index at: https://evalgate.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Use a revocable human CLI session or create an explicit API key for SDK and automation access.

# Authenticate with the EvalGate API

Human CLI requests use the revocable session created by `evalgate login`.
SDK, REST, MCP, A2A, and CI automation use an explicitly created API key. SDK
clients also need an organization ID when they create org-scoped resources such
as traces and evaluations.

## Create an account

Production account creation uses an interactive browser redirect with GitHub
or Google at [evalgate.com/signup](https://evalgate.com/signup). Choose one
provider and approve its identity request.

* EvalGate does not ask for a separate email/password pair.
* The social sign-in flow does not send a separate EvalGate verification email.
* No payment card is required for Developer's 1,000-result monthly allowance.
* Paid tiers and Developer overage continue at \$1 per 1,000 additional results
  without a default usage or dollar cap.
* Social sign-in requires JavaScript and an interactive browser for the person
  proving identity. An agent can initiate a credential handoff over HTTP, but a
  signed-in organization admin must still approve the organization and scopes.

After sign-in, create or join an organization. Then create a scoped API key
under **Developer → API Keys**. Connect a repository in Setup only when the
workflow needs repository intelligence or CI, and add a separate model-provider
key only for model-backed execution.

## Organization single sign-on and two-factor authentication

> [!NOTE]
>
> Enterprise SSO and MFA are a source candidate awaiting live enterprise-IdP
> and deployment acceptance. See [feature status](https://evalgate.com/docs/platform/feature-status.md).
> Identity changes require an organization owner signed in through an interactive
> browser session. Authorized owner credentials can read the configuration;
> API keys, CLI sessions and OAuth credentials cannot change it. SCIM and SAML
> single logout are not supported.

Organization owners configure sign-in security under **Settings → Security and
sign-in**:

* **Verified domains.** Claim an email domain, publish the TXT record EvalGate
  shows at `_evalgate-domain-verification.<domain>`, then verify. Only verified
  domains route sign-in to your identity provider.
* **SSO providers.** Connect a SAML 2.0 identity provider (IdP metadata XML, or
  entity ID, SSO URL, and signing certificate) or an OpenID Connect provider
  (issuer, client ID, client secret). The client secret is stored encrypted and
  is not shown again. Members sign in from the login page by entering their
  work email under single sign-on. A first SSO sign-in adds the person to the
  organization with the role you choose for new SSO members (Viewer by
  default).
  Use **Generate callback URLs** before registering the application in Okta or
  Entra, copy the exact URLs into the IdP, and keep the page open until you have
  saved the client credentials. The planned ID is not saved until registration
  succeeds; reloading requires restarting setup or reusing that ID through the API.
* **Require SSO.** Members whose email domain you verified must sign in through
  your identity provider; GitHub and Google sign-in is refused for those
  addresses, and existing non-SSO sessions lose access to the organization. You
  can designate one owner as a recovery admin who may still sign in without
  SSO, but only with a verified two-factor code.
* **Require two-factor authentication.** Every member must enroll an
  authenticator app (TOTP) and verify it in each session before reaching the
  organization. Backup codes are issued once at enrollment. You can choose to
  accept your identity provider's MFA for SSO sign-ins instead.

These policies apply to browser sign-in sessions, which are also what approve
new CLI sessions and API keys. When SSO or two-factor enforcement is first
enabled, EvalGate immediately revokes existing organization API keys, CLI
sessions, automation grants and OAuth credentials. Plan replacement credentials
for your integrations before enabling enforcement. Disabling the policy does
not restore revoked credentials. Policy changes, domain and provider changes,
MFA enrollment and resets, and SSO sign-in outcomes are recorded in the
organization's activity history.

## EvalGate keys and provider keys are different

| Credential | What it authorizes | Where to configure it |
| - | - | - |
| **Human CLI session** | Interactive CLI identity and organization membership | `evalgate login`; stored outside the repository |
| **EvalGate API key** | SDK, REST, MCP, A2A, and CI/service automation | Developer Dashboard and `EVALGATE_API_KEY` |
| **Provider or gateway key** | Model inference for LLM judges, synthesis, and other model-backed workflows | **Settings → AI providers** |

EvalGate uses a **bring your own provider key (BYOK)** model and does not bundle
model inference credits. Your provider bills model usage directly. A provider
key is never a substitute for the EvalGate bearer token, and you should not put
it in `EVALGATE_API_KEY`. See [Model providers and BYOK](https://evalgate.com/docs/platform/model-providers-byok.md).

## Create an API key

API keys are created from the Developer Dashboard. You need an EvalGate account before you begin.

**1. Open the Developer Dashboard**

Sign in to your EvalGate account and navigate to the [Developer Dashboard](https://evalgate.com/developer). Scroll down to the **API Keys** section.

**2. Create the key**

Click **Create API Key**. Enter a descriptive name such as `Development Key` or `CI Pipeline`, select the scopes you need, then click **Create Key**.

**3. Copy the key and find your organization ID**

Your API key is displayed only once. Copy it before closing the dialog.

> [!WARNING]
>
> If you close the dialog without copying the key, you cannot retrieve it. Create a new key instead.

To find your organization UUID, run `evalgate whoami --format json` or call `GET /api/organizations/current` with the new key.

## Agent and CLI setup

The TypeScript and Python CLIs handle their session directly. Login opens the
browser-approved device flow, and link establishes the durable organization,
GitHub repository, and repository-relative root association without asking the
user to copy a key:

```bash theme={null} theme={null}
evalgate login
evalgate whoami
evalgate link
evalgate status
```

The CLI session is stored in the operating-system user configuration directory,
outside the repository. Use `evalgate logout` to revoke the remote session and
then remove its local handle.
Agents should start with the non-mutating status contract:

```bash theme={null} theme={null}
evalgate status --json
```

`.evalgate/project.json` is a non-secret version 2 link record. It stores the
durable organization/repository/root identity separately from the last cloud
activation snapshot. The snapshot records its exact target commit and immutable
manifest identity. Moving a branch or checking out another commit does not
unlink the repository: `status` reports link, checkout relation, cloud-snapshot
currency, local-gate readiness, and cloud-target readiness independently.

A checkout two commits behind `main` can remain linked, locally gate-ready, and
eligible for cloud intake at its exact older SHA. An unpushed or diverged
checkout remains linked and locally usable, but cloud-backed work requires a
push or an explicit appropriate branch. EvalGate never substitutes the remote
branch head for the local target commit.

The CLI uses
`%APPDATA%\evalgate\config.json` on Windows,
`~/Library/Application Support/evalgate/config.json` on macOS, and
`${XDG_CONFIG_HOME:-~/.config}/evalgate/config.json` on Linux. An absolute
`EVALGATE_CONFIG_HOME` may override that directory in managed environments.
Repository configuration cannot provide a bearer key or redirect a saved session
to another origin. Alternate trusted origins must use HTTPS, except localhost
and loopback development.

For CI and direct API clients, create a least-privilege API key in the dashboard
and inject it as `EVALGATE_API_KEY` through the platform's secret store. Never
commit it or pass it on the command line.

If the agent does not already have an admin key, it can initiate a human-approved
handoff without automating the browser:

```bash theme={null} theme={null}
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"]}'
```

Show the returned `verification_uri` and `user_code` to an organization admin.
After the admin signs in with GitHub or Google and approves the exact scopes,
poll `POST /api/agent-setup/poll` at the advertised interval. The resulting
90-day API key is returned once. Starting or polling a request never creates an
anonymous account or key. See the [agent authentication guide](https://evalgate.com/docs/api/agent-authentication.md).

Standards-based CLI clients may use the RFC 8628 adapter instead: discover
`/.well-known/oauth-authorization-server`, start at
`/oauth/device/authorization` with public client `evalgate-agent`, and poll the
advertised `/oauth/token` endpoint. Approval returns a `cli_session` credential
whose effective role follows the approving user's current organization
membership. It is not an automation API key and `link` never replaces it.

MCP hosts that support OAuth authorization code can instead dynamically
register a public client at `/oauth/register`, then follow the advertised
`/oauth/authorize` endpoint with an exact registered redirect URI and PKCE S256.
The signed-in person selects the accountable organization and approves the
requested scopes. Codes are single-use and expire after five minutes; access
tokens expire after 90 days and can be submitted to `/oauth/revoke`. EvalGate
does not issue a client secret or refresh token.

### Agentic registration with a human approver

Agents that implement the `auth.md` profile can discover `agent_auth` in
`/.well-known/oauth-authorization-server` and register at `/oauth/identity`
with `type: "service_auth"` and `login_hint` set to their intended approver's
email. Optional `client_name` and `requested_scopes` identify the request.
The returned `claim` provides a verification URI and user code. The person
must sign in with that verified email, select the organization, and approve the
scopes; knowing an email cannot create an account or credential.

Poll `/oauth/token` using
`grant_type=urn:workos:agent-auth:grant-type:claim` and the returned
`claim_token`. Approval delivers one revocable organization-scoped token and
an EvalGate-signed identity assertion. That assertion works with the RFC 7523
JWT-bearer grant for at most thirty minutes, returning the same credential
after checking its revocation, expiry, verified owner, current membership and
scope ceiling. It cannot extend the original credential's ninety-day expiry.
Pending code renewal at `/oauth/claim` requires the original claim token and
email, invalidates the old code, and retains the ten-minute registration expiry.

Only `service_auth` is advertised. Anonymous registrations, third-party ID-JAG
assertions, and provider security-event endpoints are unsupported. See the
[complete registration and claim walkthrough](https://www.evalgate.com/auth.md).

For a safe post-approval test, call MCP `server/discover`, public schema-only
`tools/list`, then authenticate and call read-only `project_plan`. Those MCP operations invoke no
model provider and no billable hosted evaluation. See the
[MCP request example](https://evalgate.com/docs/platform/mcp-integration.md#public-bootstrap-request).

`evalgate gate --offline` separately blocks EvalGate's built-in/configured
provider-backed checks. Custom project code can still use the network, and
hard network denial for wrapped commands depends on Linux `unshare`. Neither
path is a production-like sandbox.

## Use the API key in HTTP requests

Include your API key as a Bearer token in the `Authorization` header:

```http theme={null} theme={null}
Authorization: Bearer YOUR_API_KEY
```

The base URL for all API endpoints is `https://evalgate.com`.

```bash theme={null} theme={null}
curl https://evalgate.com/api/traces \
  -H "Authorization: Bearer sk_test_your_api_key_here" \
  -H "Content-Type: application/json"
```

## Configure environment variables

Store credentials as environment variables so neither the SDK nor your code needs to hardcode them.

```bash .env theme={null} theme={null}
EVALGATE_API_KEY=sk_test_your_api_key_here
EVALGATE_ORGANIZATION_ID=00000000-0000-4000-8000-000000000001
```

Both variables are required for SDK workflows that create org-scoped platform resources. Direct REST API routes derive the organization from the API key unless an endpoint explicitly documents an `organizationId` field.

## SDK auto-loading

Both the TypeScript and Python SDKs read `EVALGATE_API_KEY` and `EVALGATE_ORGANIZATION_ID` automatically when you call `.init()` with no arguments.

```typescript TypeScript theme={null} theme={null}
import { AIEvalClient } from '@evalgate/sdk';

const client = AIEvalClient.init();
```

```python Python theme={null} theme={null}
from evalgate_sdk import AIEvalClient

client = AIEvalClient.init()
```

If you need to pass credentials explicitly, pass them directly to the constructor:

```typescript TypeScript theme={null} theme={null}
const client = new AIEvalClient({
  apiKey: process.env.EVALGATE_API_KEY,
  organizationId: process.env.EVALGATE_ORGANIZATION_ID,
});
```

```python Python theme={null} theme={null}
import os
from evalgate_sdk import AIEvalClient

client = AIEvalClient(
    api_key=os.environ["EVALGATE_API_KEY"],
    organization_id=os.environ["EVALGATE_ORGANIZATION_ID"],
)
```

## Authentication errors

If a request fails with `401 Unauthorized`, check that:

* The `Authorization` header is present and formatted as `Bearer YOUR_API_KEY`.
* The key was copied in full.
* The key has not been deleted from the Developer Dashboard.
* The key scopes include the operation you're attempting.

## Security best practices

> [!NOTE]
>
> Treat your API key like a password. Anyone who has it can make requests on behalf of your organization.

**Never commit keys to version control.** Add `.env` to your `.gitignore` file before creating it:

```bash theme={null} theme={null}
echo ".env" >> .gitignore
```

**Use CI secret stores for CI pipelines.** In GitHub Actions, store credentials as repository secrets:

```yaml theme={null} theme={null}
env:
  EVALGATE_API_KEY: ${{ secrets.EVALGATE_API_KEY }}
  EVALGATE_ORGANIZATION_ID: ${{ secrets.EVALGATE_ORGANIZATION_ID }}
```

**Create separate keys per environment.** Use one key for local development, a separate key for staging, and another for production.

**Rotate keys when team members leave.** Revoke keys for former team members immediately from the Developer Dashboard and issue new keys to active users.

Provider credentials have a separate lifecycle. Store, rotate, and revoke them
from provider settings, and also revoke them at the upstream provider. EvalGate
stores organization provider credentials encrypted before use and does not
return the plaintext credential after creation.

## Rate limits

All API keys are subject to rate limits. If your integration receives `429 Too Many Requests`, see the [rate limits reference](https://evalgate.com/docs/platform/rate-limits.md) for per-plan limits and backoff guidance.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.