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

# Authentication

> Three auth methods: session cookies for the dashboard, API keys for programmatic access, and OAuth via GitHub or Google.

# Authentication

Igris supports several authentication methods depending on the context.

## Session Cookies (Dashboard)

When you log in through the dashboard, Better Auth sets a session cookie. The cookie name depends on the environment:

* **Production:** `__Secure-igris.session_token` (Secure flag set, HTTPS only)
* **Development:** `igris.session_token`

This cookie is automatically sent with all dashboard requests.

For API calls from a browser context, include credentials:

```javascript theme={null}
fetch("https://api.igrisecurity.com/api/v1/policies", {
  credentials: "include" // sends session cookie
});
```

Or pass the cookie explicitly:

```bash theme={null}
curl https://api.igrisecurity.com/api/v1/policies \
  -H "Cookie: __Secure-igris.session_token=eyJhbGciOi..."
```

## OAuth (GitHub / Google)

GitHub and Google OAuth are conditionally enabled based on server configuration. When the relevant environment variables are set (`GITHUB_CLIENT_ID`/`GITHUB_CLIENT_SECRET` or `GOOGLE_CLIENT_ID`/`GOOGLE_CLIENT_SECRET`), the corresponding social login buttons appear on the sign-in page. OAuth sessions are issued as session cookies identical to email/password login — no additional API changes are needed.

## API Keys (Programmatic Access)

For MCP proxy connections and CI/CD integrations, use API keys.

### Creating an API Key

1. Go to **Settings → API Keys** in the dashboard
2. Click **Create Key**
3. Give it a label (e.g., "Proxy - Production", "CI Pipeline")
4. Copy the key — it's only shown once

API keys follow the format `ig_` followed by 48 lowercase hex characters (24 random bytes), for a total of 51 characters:

```
ig_a3f82c1d9e4b7f0612a5c8e3d1f29b047e6a8c2d5f1b4e7a
```

### Using an API Key

Pass the key in the `Authorization` header:

```bash theme={null}
curl https://api.igrisecurity.com/api/v1/policies \
  -H "Authorization: Bearer ig_a3f82c1d9e4b7f06..."
```

### Key Scoping and Permissions

API keys are **read-only by default**. `GET` and `HEAD` requests succeed with a valid key. Write operations (`POST`, `PUT`, `PATCH`, `DELETE`) on management API routes require a session cookie — requests made with an API key alone will receive `403 Forbidden` on those routes.

Keys are scoped to the organization they were created in.

### Revoking Keys

Revoke a key in **Settings → API Keys** by clicking **Revoke**. Revoked keys immediately stop working — any proxy connections using that key will receive `401 Unauthorized`.

## Ingest API Authentication

The Ingest API (`/api/v1/ingest/*`) uses a **separate** BetterAuth API-key system. These keys are issued for log ingestion from external proxies (Portkey, Helicone, Cloudflare integrations) and are distinct from the management API keys described above. Pass them the same way — `Authorization: Bearer <key>` — but generate them from the Ingest settings, not the main API Keys page.

## MCP Gateway and LLM Gateway Authentication

The MCP gateway (`/v1/mcp/:slug`) and LLM gateway (`/llm/:slug/*`) use **Bearer API key only**. Session cookies are not accepted on these routes.

* **CORS:** Both routes allow wildcard origins (`*`) — designed for programmatic clients and browser-based SDKs calling from any origin.
* **No session cookie fallback:** There is no session-cookie auth path on gateway routes; the Bearer key is the only accepted credential.

```bash theme={null}
# MCP gateway
curl https://api.igrisecurity.com/v1/mcp/my-server \
  -H "Authorization: Bearer ig_a3f82c1d9e4b7f06..."

# LLM gateway
curl https://api.igrisecurity.com/llm/openai/v1/chat/completions \
  -H "Authorization: Bearer ig_a3f82c1d9e4b7f06..."
```

## Organization Context

All API requests are scoped to an organization. The organization is determined by:

1. **Session cookies** — the user's active organization in their session
2. **API keys** — the organization the key was created in

## Error Responses

| Status                 | Meaning                                             |
| ---------------------- | --------------------------------------------------- |
| `401 Unauthorized`     | Missing, invalid, or revoked credentials            |
| `403 Forbidden`        | Valid credentials but insufficient role permissions |
| `403 Forbidden` (plan) | Feature requires a higher plan tier                 |

A `401` response body contains only an `error` field:

```json theme={null}
{
  "error": "Invalid or expired API key"
}
```

A plan-gated `403` response includes additional context:

```json theme={null}
{
  "error": "Feature not available on your plan",
  "feature": "hipaa",
  "currentPlan": "starter",
  "requiredPlan": "scale"
}
```

## RBAC Roles

Permissions are enforced based on the user's role in the organization:

| Role          | Policies   | Sessions   | Servers    | API Keys   | Compliance | Billing | Members |
| ------------- | ---------- | ---------- | ---------- | ---------- | ---------- | ------- | ------- |
| **Owner**     | Full       | Full       | Full       | Full       | Full       | Full    | Full    |
| **Admin**     | Full       | Full       | Full       | Full       | Full       | —       | Manage  |
| **Developer** | Read/Write | Read/Write | Read/Write | Read/Write | —          | —       | —       |
| **CISO**      | Read/Write | Read/Write | Read       | —          | Read/Write | —       | —       |
| **Auditor**   | Read       | Read       | Read       | —          | Read       | —       | —       |
