Authentication & Security
Bearer tokens at the request boundary, OAuth at the user boundary, TOTP at the account boundary. Keys are project-scoped, rotatable on demand with a 24-hour grace, revocable from any session, optionally IP-locked and endpoint-locked.
Response Semantics
Five status codes carry all auth-layer signal. Use the matrix to triage; each row links to the section that produces that response.
| Status | Meaning | Caused by |
|---|---|---|
200 |
Authenticated, scoped, in budget. | Valid key, granted scope, allowed IP, endpoint match. |
401 |
Key invalid, expired, or revoked. | Missing/typo key, expired key, key revoked. |
403 |
Key valid; access denied. | Scope missing (type authentication_error), IP not allowed, endpoint mismatch. |
429 |
Rate quota exhausted. | Per-key or service-tier quota; read Retry-After. |
5xx |
Router or upstream failure. | Not an auth condition; see Error Handling. |
API Keys
API keys authenticate requests to Xerotier inference endpoints. Each key is
a 256-bit cryptographically random value prefixed with xero_
followed by your project slug.
Key Format
xero_<project_slug>_<random_token>
Using API Keys
Include the key in the Authorization header:
curl -X POST https://api.xerotier.ai/proj_ABC123/my-endpoint/v1/chat/completions \
-H "Authorization: Bearer xero_my-project_abc123" \
-H "Content-Type: application/json" \
-d '{"model": "llama-3.1-8b", "messages": [{"role": "user", "content": "Hello"}]}'
Key Management
| Operation | Description |
|---|---|
| Create | Generate a new API key from the project settings page. The full key is shown only once at creation time. |
| Rotate | Generate a new key value in-place from the project settings page. The old key remains valid for a 24-hour grace period so you can update your applications before the old value stops working. |
| Revoke | Permanently disable a key. Revoked keys cannot be re-enabled. Any requests using a revoked key receive a 401 Unauthorized response. |
Key Security
- Store keys in environment variables or a secrets manager, never in source code.
- Use separate keys for development, staging, and production environments.
- Rotate keys regularly and immediately if you suspect a key has been compromised.
- Monitor key usage in the dashboard to detect unauthorized access.
Scopes
Each API key carries one or more permission scopes. Requests to APIs outside
the key's granted scopes receive 403 Forbidden.
| Scope | Default | Description |
|---|---|---|
inference |
Yes | Chat completions, embeddings, reranking, and model listing. Required for all inference endpoint calls. |
management |
No | Programmatic project management: key CRUD, agent CRUD, join-key management. Used by the xeroctl CLI and automation tooling. |
execution |
No | Gates the /v1/exec/* code-execution surface and the MCP exec.* tool family. |
research |
No | Gates the deep-think and research feature surface (research.* and deep_think.* tooling). |
Scopes are set at key creation time and cannot be changed afterwards. To change scopes, rotate the key and specify the new scope list.
Note on Models mutations: POST, PATCH, and DELETE against the Models API are authorized under the inference scope, not management. Read-only GET /v1/models also requires inference.
When an MCP request presents a key that lacks the required scope, the router
returns 403 Forbidden with an error of type: authentication_error
(not 401). Treat a 403 with that type as "key valid, scope missing".
IP Filtering
Each API key supports an optional IP allowlist and blocklist. When configured, the router enforces IP restrictions on every request authenticated with that key.
| Field | Description |
|---|---|
allowedIps |
Array of IPv4 or IPv6 addresses that are permitted to use this key.
When non-empty, requests from any address not in this list are rejected
with 403 Forbidden.
|
blockedIps |
Array of IPv4 or IPv6 addresses that are explicitly denied. Checked after the allowlist. When an address appears in both lists, the blocklist wins. |
IP filters are configured from the API Keys page in the dashboard. Leaving both fields empty allows requests from any IP address.
Key Rotation
Key rotation generates a new key value in-place. The old key value remains valid for a 24-hour grace period so you can update your applications without downtime.
How rotation works:
- Click "Rotate" on the key in the dashboard (or call the management API).
- The new key value is returned once, store it immediately.
- Both old and new values authenticate requests during the grace period.
- After 24 hours the old value is permanently invalidated.
Note: Rotating a key resets its key prefix. Any application that stores the prefix for display purposes must be updated after rotation.
Expiration & Quota
Key Expiration
API keys support an optional expiration date (expiresAt).
After the expiration timestamp the key is treated as revoked and all
requests receive 401 Unauthorized.
Keys without an expiration date never expire automatically.
Per-Key Rate Quota
Each key has a configurable rate quota independent of the service-tier limits:
| Field | Default | Description |
|---|---|---|
quotaRequests |
60 | Maximum number of requests allowed per quota window. |
quotaWindow |
60 s | Duration of the rolling quota window in seconds. |
When the key quota is tighter than the service-tier quota, the key quota takes precedence. Adjust quotas from the API Keys page in the dashboard.
Endpoint Restriction
A key can optionally be restricted to a single endpoint by setting
endpointId at creation time. Restricted keys are rejected
with 403 Forbidden when used against any other endpoint in
the same project.
Rate Limit Headers
Every inference response includes rate limit headers so clients can
adapt their request cadence without waiting for a 429.
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the current window. |
X-RateLimit-Remaining |
Remaining requests in the current window. |
X-RateLimit-Reset |
Seconds until the current window resets. |
When the rate limit is exceeded the server returns 429 Too Many Requests
with a Retry-After header containing the number of seconds
to wait before retrying. See Error Handling
for the broader retry contract on 4xx and 5xx responses.
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 42
Retry-After: 42
Client Examples
The following examples show how to authenticate with Xerotier using popular SDKs and HTTP clients. All examples use the OpenAI-compatible API format.
OpenAI SDK
Xerotier endpoints are OpenAI-compatible, so you can use the official OpenAI SDKs by pointing them at your Xerotier base URL.
from openai import OpenAI
client = OpenAI(
base_url="https://api.xerotier.ai/proj_ABC123/my-endpoint/v1",
api_key="xero_my-project_abc123"
)
# All requests are automatically authenticated
response = client.chat.completions.create(
model="my-model",
messages=[{"role": "user", "content": "Hello"}]
)
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.xerotier.ai/proj_ABC123/my-endpoint/v1",
apiKey: "xero_my-project_abc123"
});
// All requests are automatically authenticated
const response = await client.chat.completions.create({
model: "my-model",
messages: [{ role: "user", content: "Hello" }]
});
Raw HTTP Requests
If you are not using an OpenAI SDK, include the API key in the
Authorization header as a Bearer token.
import requests
headers = {
"Authorization": "Bearer xero_my-project_abc123",
"Content-Type": "application/json"
}
response = requests.get(
"https://api.xerotier.ai/proj_ABC123/v1/models",
headers=headers
)
const response = await fetch(
"https://api.xerotier.ai/proj_ABC123/v1/models",
{
headers: {
"Authorization": "Bearer xero_my-project_abc123"
}
}
);
const data = await response.json();
OAuth & SSO
Xerotier supports GitHub OAuth for dashboard login. This is for user authentication to the web dashboard, not for API access (which always uses API keys).
GitHub OAuth
GitHub OAuth allows users to sign in to the Xerotier dashboard using their GitHub account. When configured, a "Sign in with GitHub" button appears on the login page.
| Step | Description |
|---|---|
| 1. Initiate | User clicks "Sign in with GitHub" which redirects to /auth/github. |
| 2. Authorize | GitHub prompts the user to authorize the Xerotier application. |
| 3. Callback | GitHub redirects to /auth/github/callback with an authorization code. |
| 4. Session | Xerotier exchanges the code for user information, creates or links the account, and establishes a session. |
If a Xerotier account already exists with the same email address, the GitHub identity is linked to that existing account. Users can unlink their GitHub account from the account settings page.
Two-Factor Authentication (2FA)
Xerotier supports TOTP-based two-factor authentication for an additional layer of account security. When enabled, login requires both your password and a time-based code from an authenticator app.
Supported Authenticator Apps
Any TOTP-compatible authenticator app works, including Google Authenticator, Authy, 1Password, Bitwarden, and Microsoft Authenticator.
Setup Process
- Navigate to Account Settings and select Security.
- Click "Enable Two-Factor Authentication".
- Scan the QR code with your authenticator app (or enter the secret manually).
- Enter the 6-digit code from your authenticator to verify setup.
- Save your backup codes in a secure location (see Backup Codes).
Login with 2FA
After entering your password, you are prompted for a 6-digit TOTP code. You have 5 minutes to enter the code before the verification window expires and you must start the login process again.
Disabling 2FA
You can disable 2FA from Account Settings. You must provide a valid TOTP code to confirm the change. Disabling 2FA removes the TOTP secret and invalidates all backup codes.
Security Details
- TOTP secrets are encrypted at rest.
- Rate limiting is applied to 2FA verification attempts to prevent brute-force attacks.
Backup Codes
When you enable 2FA, Xerotier generates a set of one-time backup codes. These codes allow you to regain access to your account if you lose your authenticator device.
Using Backup Codes
- Each backup code can only be used once.
- Enter a backup code in place of the TOTP code during login.
- After using a backup code, it is permanently consumed.
Storage Guidance
- Save backup codes immediately after generation, they are shown only once.
- Store them in a secure location separate from your authenticator device (e.g., a password manager, printed copy in a safe).
- Do not store backup codes alongside your regular password.
Regenerating Backup Codes
You can regenerate backup codes from Account Settings. Regenerating creates a new set and invalidates all previous codes. You must provide a valid TOTP code to regenerate.
Account Recovery
If you have lost both your authenticator device and all backup codes, you can request account recovery. The recovery process requires email verification and may take additional time for security review. Re-enroll TOTP immediately after the next successful sign-in to restore the second factor.
Sessions & Cookies
The Xerotier dashboard uses cookie-based session management. Sessions are created at login and extended on activity.
| Behavior | Details |
|---|---|
| Session extension | Each activity extends the session by 480 minutes (8 hours) of idle timeout. |
| Maximum lifetime | Sessions expire after 1440 minutes (24 hours) regardless of activity. |
| Password change | Changing your password invalidates all active sessions. |
Session cookies are marked Secure and HttpOnly,
requiring HTTPS. Changing your password or an admin resetting your password
invalidates all active sessions.
Proxy Auth JWT (Frontend to Router)
Browser sessions never present their session cookie directly to the router.
Instead, after the Frontend validates a session cookie it mints a short-lived
proxy-auth JWT and forwards it to the router on the user's
behalf. The router accepts this JWT via ProxyJWTAuthMiddleware
and resolves the originating user, project, and scopes from its claims.
- Minted server-side by the Frontend after it has validated the dashboard session cookie.
- Signed with a shared secret known to both the Frontend and router.
- Short TTL: minted per request flow, not stored client-side.
- Accepted only on the Frontend-to-Router internal path; not used for direct API client access.
API clients (SDKs, curl, xeroctl) authenticate
with xero_* API keys as documented above, they never see or
use the proxy-auth JWT.
CSRF Protection
All state-changing requests to the Xerotier dashboard require a CSRF token.
The token is embedded in a <meta> tag on each page and
must be sent as the X-CSRF-Token header on POST, PUT, PATCH,
and DELETE requests.
For Custom Frontend Integrations
If you build custom JavaScript that calls Xerotier dashboard APIs (not the inference API), extract the CSRF token from the meta tag:
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch('/api/some-action', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token
},
body: JSON.stringify({...})
});
CSRF protection applies only to the web dashboard. The inference API uses API key authentication and does not require CSRF tokens.
Security Best Practices
API Key Security
- Never commit API keys to version control.
- Use environment variables or a secrets manager (HashiCorp Vault, AWS Secrets Manager, etc.).
- Create separate keys per application or environment.
- Rotate keys on a regular schedule (monthly or quarterly).
- Revoke keys immediately if compromised.
Account Security
- Enable two-factor authentication for all user accounts.
- Use strong, unique passwords (minimum 12 characters).
- Store backup codes in a secure, offline location.
- Review active sessions periodically in Account Settings.
Network Security
- Always use HTTPS for API calls. HTTP requests are rejected in production.
- The dashboard sets
Strict-Transport-Security(HSTS) headers in production mode. - Session cookies are marked
SecureandHttpOnlyby default.
If a Key Is Compromised
- Revoke the compromised key immediately from the dashboard.
- Create a new replacement key.
- Update all applications using the old key.
- Review recent usage logs for unauthorized access.
- If your account may be compromised, change your password (this invalidates all sessions) and regenerate backup codes.