Authentication¶
Every request to the Gaia API must be authenticated. Gaia uses a simple API key mechanism — you include your key as an HTTP header on every request. This page covers how authentication works, how to implement it securely in a web application, and best practices for production.
API Key Authentication¶
Gaia authenticates requests using the apiKey HTTP header. Every API call must include this header:
Not Bearer tokens
Gaia does not use the Authorization: Bearer scheme. The header name is literally apiKey (case-sensitive).
Obtaining an API Key¶
- Log in to the Cohesity UI (cluster or Helios at
helios.cohesity.com). - Navigate to Settings → Access Management → API Keys.
- Click Generate API Key.
- Provide a descriptive name (e.g.,
gaia-dev-app). - Copy the key immediately — it is shown only once.
- Store it in a secure location (password manager, environment variable, or secrets vault).
Quick Examples¶
cURL¶
If you have a .env file, load it into your shell first so $GAIA_API_KEY is available:
Then call the API:
curl -s \
-H "apiKey: $GAIA_API_KEY" \
https://helios.cohesity.com/v2/mcm/gaia/datasets | python3 -m json.tool
Python with httpx¶
import httpx
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://helios.cohesity.com/v2/mcm/gaia"
async def list_datasets():
async with httpx.AsyncClient(
base_url=BASE_URL,
headers={"apiKey": API_KEY},
) as client:
response = await client.get("/datasets")
response.raise_for_status()
return response.json()
Python with the Gaia SDK¶
The SDK handles header management for you:
Session-Based Authentication for Web Apps¶
In a web application, you must not expose the API key to the frontend. Instead, use a session-based pattern where the key is sent once and stored server-side.
The Flow¶
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Frontend │ │ Backend │ │ Gaia API │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ 1. POST /api/connect │ │
│ { apiKey: "abc123..." } │ │
│───────────────────────────────────▶│ │
│ │ 2. Validate: GET /datasets │
│ │ apiKey: abc123... │
│ │──────────────────────────────▶│
│ │ │
│ │ 3. 200 OK (key is valid) │
│ │◀──────────────────────────────│
│ │ │
│ │ 4. Store key in session │
│ 5. Set-Cookie: session=sess_xyz │ │
│◀───────────────────────────────────│ │
│ │ │
│ 6. POST /api/ask │ │
│ Cookie: session=sess_xyz │ │
│ { query: "...", datasets: [] } │ │
│───────────────────────────────────▶│ │
│ │ 7. Resolve session → key │
│ │ POST /ask │
│ │ apiKey: abc123... │
│ │──────────────────────────────▶│
│ │ │
Backend Implementation¶
from fastapi import FastAPI, Response, Cookie, HTTPException
from pydantic import BaseModel
from gaia_sdk import GaiaClient
import secrets
app = FastAPI()
# In-memory session store — simple for demos, not production-safe.
# Sessions are lost on server restart. See Session Management chapter for a
# persistent implementation using SQLite or Redis.
sessions: dict[str, str] = {}
class ConnectRequest(BaseModel):
api_key: str
@app.post("/api/connect")
async def connect(req: ConnectRequest, response: Response):
"""Validate the API key and create a session."""
# Verify the key works by making a test call
try:
async with GaiaClient(api_key=req.api_key) as gaia:
await gaia.list_datasets()
except Exception:
raise HTTPException(status_code=401, detail="Invalid API key")
# Create a session
session_id = secrets.token_urlsafe(32)
sessions[session_id] = req.api_key
response.set_cookie(
key="gaia_session",
value=session_id,
httponly=True,
secure=True,
samesite="strict",
)
return {"status": "connected", "sessionId": session_id}
async def get_gaia_client(
gaia_session: str = Cookie(None),
) -> GaiaClient:
"""FastAPI dependency that resolves a session to a GaiaClient."""
if not gaia_session or gaia_session not in sessions:
raise HTTPException(status_code=401, detail="Not authenticated")
api_key = sessions[gaia_session]
return GaiaClient(api_key=api_key)
Security Context Header¶
For multi-tenant deployments or operations that require elevated privileges, Gaia supports an optional X-GAIA-SECURITY-CTX header.
curl -s \
-H "apiKey: YOUR_API_KEY" \
-H "X-GAIA-SECURITY-CTX: tenant-abc-ctx-token" \
https://helios.cohesity.com/v2/mcm/gaia/datasets
With the SDK:
async with GaiaClient(
api_key="YOUR_API_KEY",
security_context="tenant-abc-ctx-token",
) as gaia:
datasets = await gaia.list_datasets()
When to use the security context
Most single-tenant applications don't need this header. It's used when your Cohesity cluster serves multiple tenants and you need to scope API access to a specific tenant's data. Check with your Cohesity administrator for details.
Environment Variables¶
The recommended way to manage credentials is through environment variables. Here's a complete .env.example file:
# ── Gaia API Configuration ──────────────────────────────────
# Required: Your Gaia API key
GAIA_API_KEY=your-api-key-here
# Gaia API base URL (default: Helios)
GAIA_BASE_URL=https://helios.cohesity.com/v2/mcm/gaia
# SSL verification (set to false only for dev clusters with self-signed certs)
GAIA_VERIFY_SSL=true
# Optional: Security context for multi-tenant setups
# GAIA_SECURITY_CTX=
# ── Application Configuration ───────────────────────────────
# Backend server
APP_HOST=0.0.0.0
APP_PORT=8000
# Session secret (generate with: python3 -c "import secrets; print(secrets.token_urlsafe(32))")
SESSION_SECRET=change-me-to-a-random-string
# CORS origins (comma-separated)
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
# Log level
LOG_LEVEL=INFO
Load these in your application:
Security Best Practices¶
Critical Security Rules
- Never expose the API key in frontend code. Not in JavaScript bundles, not in HTML, not in browser-accessible config files.
- Never commit
.envfiles to version control. Add.envto.gitignorebefore your first commit. - Use HTTPS everywhere. The API key is sent as a header — without TLS, it's visible to network observers.
Additional Recommendations¶
| Practice | Description |
|---|---|
| Use environment variables | Load keys from os.environ, never hardcode them |
| Rotate keys regularly | Generate new keys periodically and revoke old ones |
| Use HttpOnly cookies | For session tokens in web apps, preventing XSS access |
| Set Secure and SameSite flags | Prevent CSRF and ensure cookies are only sent over HTTPS |
| Implement session expiry | Don't keep sessions alive forever; add a TTL |
| Use a secrets manager | In production, use Vault, AWS Secrets Manager, or similar |
| Audit key usage | Monitor the Cohesity audit log for unexpected API key activity |
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
401 Unauthorized | Missing or invalid apiKey header | Verify the key is correct and the header name is apiKey (case-sensitive) |
403 Forbidden | Key doesn't have Gaia permissions | Check RBAC settings in the Cohesity UI; ensure the key's role includes Gaia access |
SSL certificate error | Self-signed cert on dev cluster | Set GAIA_VERIFY_SSL=false (dev only!) or install the cluster's CA cert |
Connection refused | Wrong base URL | Verify GAIA_BASE_URL points to the correct cluster/Helios endpoint |
Never disable SSL verification in production
GAIA_VERIFY_SSL=false is only acceptable on isolated development clusters with self-signed certificates. In production, keep SSL verification enabled. If you have a private CA, install its certificate into your system trust store or pass it via httpx's verify= parameter instead of disabling verification entirely.
Next Steps¶
- Your First API Call — Put your key to work.
- Understanding Datasets — Learn about the data you'll be querying.