Authentication Guide
This guide covers authentication in Eve, including login, token management, and best practices for securing your API access.
Authentication Overview
Eden uses JWT (JSON Web Token) based authentication:
- Login with credentials to receive a JWT token
- Use the token in API requests via the Authorization header
- Refresh the token before it expires to maintain your session
Eden can also accept externally issued OIDC tokens when [auth.external] is configured. External identity providers authenticate the caller; Eden still resolves the organization, maps claims or groups, and enforces Eden RBAC before requests reach endpoints, templates, or gateways.
External Identity Providers
External auth can run in hybrid mode during migration or authoritative mode when the external issuer is the bearer-token authority.
| Provider preset | What it covers |
|---|---|
generic_oidc | Standards-based OIDC issuers with explicit Eden org mapping. |
okta | Okta OIDC tokens and group claim mappings. |
microsoft_entra | Microsoft Entra ID tenant and user claim defaults. |
google_workspace | Google OIDC tokens with configured Eden org mapping. |
auth0 | Auth0 OIDC tokens with static org mapping or custom claims. |
aws_cognito | AWS Cognito OIDC tokens and Cognito group defaults. |
keycloak | Keycloak OIDC tokens with realm-specific Eden mapping. |
one_login | OneLogin OIDC tokens with configured Eden org mapping. |
ping_one | PingOne OIDC tokens with configured Eden org mapping. |
These providers are identity sources. They authenticate the caller and provide claims or groups that Eden maps into its existing authorization model; they do not bypass Eden RBAC.
Logging In
Basic Authentication
Use HTTP Basic Auth to login and receive a JWT token. The X-Org-Id header is required to scope the login to your organization:
curl http://{host}:8000/api/v1/auth/login \
-H "X-Org-Id: your_org_id" \
-u username:password \
-X POSTOr with an explicit Authorization header:
# Encode credentials
echo -n "username:password" | base64
# Result: dXNlcm5hbWU6cGFzc3dvcmQ=
curl http://{host}:8000/api/v1/auth/login \
-H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
-H "X-Org-Id: your_org_id" \
-X POSTResponse
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWRtaW4iLCJvcmdfaWQiOiJteV9jb21wYW55IiwiZXhwIjoxNzA1NDkyODAwfQ.signature"
}Using Your Token
Include the JWT token in the Authorization header for all API requests:
curl http://{host}:8000/api/v1/endpoints \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json"Environment Variable
For convenience, store your token in an environment variable:
export TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl http://{host}:8000/api/v1/endpoints \
-H "Authorization: Bearer $TOKEN"Token Refresh
Refresh your token before it expires to maintain uninterrupted access:
curl http://{host}:8000/api/v1/auth/refresh \
-H "Authorization: Bearer $TOKEN" \
-X POSTResponse:
{
"status": "success",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...new_token..."
}
}The refresh endpoint also supports GET requests:
curl http://{host}:8000/api/v1/auth/refresh \
-H "Authorization: Bearer $TOKEN"JWT Token Structure
Eden JWT tokens contain these claims:
| Claim | Description |
|---|---|
user_id | String identifier for the user |
user_uuid | UUID identifier for the user |
org_id | String identifier for the organization |
org_uuid | UUID identifier for the organization |
exp | Token expiration timestamp (Unix epoch) |
iat | Token issued at timestamp (Unix epoch) |
Decoding a Token
You can decode the payload (middle part) of a JWT to see its contents:
echo "eyJ1c2VyX2lkIjoiYWRtaW4iLCJvcmdfaWQiOiJteV9jb21wYW55IiwiZXhwIjoxNzA1NDkyODAwfQ" | base64 -dUser Identification
Eden supports two methods for user identification during login:
By Username (String)
Use email addresses or custom identifiers:
Username: john.doe@company.com
Password: mypassword123By User UUID
Use UUID format:
Username: 550e8400-e29b-41d4-a716-446655440000
Password: mypassword123The system automatically detects the format and handles accordingly.
Client-Side Token Validation
Validate tokens client-side before making API calls:
JavaScript
function isTokenExpired(token) {
try {
const payload = JSON.parse(atob(token.split(".")[1]));
const now = Math.floor(Date.now() / 1000);
return payload.exp <= now;
} catch {
return true;
}
}
function getTokenExpiry(token) {
try {
const payload = JSON.parse(atob(token.split(".")[1]));
return new Date(payload.exp * 1000);
} catch {
return null;
}
}Python
import base64
import json
from datetime import datetime
def is_token_expired(token):
try:
payload = token.split('.')[1]
# Add padding if needed
payload += '=' * (4 - len(payload) % 4)
decoded = json.loads(base64.b64decode(payload))
return decoded['exp'] <= datetime.now().timestamp()
except:
return True
def get_token_expiry(token):
try:
payload = token.split('.')[1]
payload += '=' * (4 - len(payload) % 4)
decoded = json.loads(base64.b64decode(payload))
return datetime.fromtimestamp(decoded['exp'])
except:
return NoneAutomatic Token Refresh
Implement automatic token refresh to maintain sessions:
JavaScript Example
class EdenClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.token = null;
this.refreshTimer = null;
}
async login(orgId, username, password) {
const credentials = btoa(`${username}:${password}`);
const response = await fetch(`${this.baseUrl}/api/v1/auth/login`, {
method: "POST",
headers: { Authorization: `Basic ${credentials}`, "X-Org-Id": orgId },
});
const data = await response.json();
this.token = data.token;
this.scheduleRefresh();
return this.token;
}
scheduleRefresh() {
if (this.refreshTimer) clearTimeout(this.refreshTimer);
const expiry = this.getTokenExpiry();
if (!expiry) return;
// Refresh 5 minutes before expiry
const refreshTime = expiry.getTime() - Date.now() - 5 * 60 * 1000;
if (refreshTime > 0) {
this.refreshTimer = setTimeout(() => this.refresh(), refreshTime);
}
}
async refresh() {
const response = await fetch(`${this.baseUrl}/api/v1/auth/refresh`, {
method: "POST",
headers: { Authorization: `Bearer ${this.token}` },
});
const data = await response.json();
this.token = data.data.token;
this.scheduleRefresh();
return this.token;
}
getTokenExpiry() {
try {
const payload = JSON.parse(atob(this.token.split(".")[1]));
return new Date(payload.exp * 1000);
} catch {
return null;
}
}
async request(endpoint, options = {}) {
if (this.isTokenExpired()) {
await this.refresh();
}
return fetch(`${this.baseUrl}${endpoint}`, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${this.token}`,
},
});
}
isTokenExpired() {
const expiry = this.getTokenExpiry();
return !expiry || expiry <= new Date();
}
}Error Handling
Missing or Invalid Credentials
{
"error": "Unauthorized",
"message": "Invalid credentials"
}Expired Token
{
"error": "Unauthorized",
"message": "Token has expired"
}Invalid Token Format
{
"error": "Unauthorized",
"message": "Invalid token format"
}User Not Found
{
"error": "Not Found",
"message": "User not found in organization"
}Best Practices
Token Storage
| Environment | Recommended Storage |
|---|---|
| Browser apps | sessionStorage or httpOnly cookies |
| Server apps | Memory or secure environment variables |
| Mobile apps | Secure keychain/keystore |
Never store tokens in localStorage for sensitive applications.
Security Recommendations
- Always use HTTPS in production
- Set appropriate token expiration times
- Implement token refresh before expiration
- Handle 401 errors gracefully by refreshing or re-authenticating
- Clear tokens on logout
Error Recovery
async function apiCall(endpoint) {
const response = await fetch(endpoint, {
headers: { Authorization: `Bearer ${token}` },
});
if (response.status === 401) {
// Try to refresh token
try {
await refreshToken();
return apiCall(endpoint); // Retry
} catch {
// Refresh failed, redirect to login
logout();
}
}
return response;
}Related
- API Overview - Full API reference
- External Identity And Third-Party Auth - Third-party identity feature overview
- Users - User management
- Agents - Service identities, runtime agents, and client integrations
- RBAC - Access control