Skip to content

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:

Text Only
apiKey: YOUR_API_KEY_HERE

Not Bearer tokens

Gaia does not use the Authorization: Bearer scheme. The header name is literally apiKey (case-sensitive).

Obtaining an API Key

  1. Log in to the Cohesity UI (cluster or Helios at helios.cohesity.com).
  2. Navigate to Settings → Access Management → API Keys.
  3. Click Generate API Key.
  4. Provide a descriptive name (e.g., gaia-dev-app).
  5. Copy the key immediately — it is shown only once.
  6. 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:

Bash
# Load .env into the current shell (bash/zsh)
export $(grep -v '^#' .env | xargs)

Then call the API:

Bash
curl -s \
  -H "apiKey: $GAIA_API_KEY" \
  https://helios.cohesity.com/v2/mcm/gaia/datasets | python3 -m json.tool

Python with httpx

Python
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:

Python
from gaia_sdk import GaiaClient

async with GaiaClient(api_key="YOUR_API_KEY") as gaia:
    datasets = await gaia.list_datasets()
    for ds in datasets:
        print(f"  {ds.name}{ds.status}")
Python
from gaia_sdk import GaiaClient

# Reads GAIA_API_KEY, GAIA_BASE_URL, GAIA_VERIFY_SSL from env
async with GaiaClient.from_env() as gaia:
    datasets = await gaia.list_datasets()
    for ds in datasets:
        print(f"  {ds.name}{ds.status}")

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

Text Only
┌──────────┐                         ┌──────────┐                    ┌──────────┐
│ 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

Python
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.

Bash
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:

Python
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:

Bash
# ── 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:

Python
from dotenv import load_dotenv

load_dotenv()  # Reads .env into os.environ

Security Best Practices

Critical Security Rules

  1. Never expose the API key in frontend code. Not in JavaScript bundles, not in HTML, not in browser-accessible config files.
  2. Never commit .env files to version control. Add .env to .gitignore before your first commit.
  3. 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