Architecture Overview¶
This page describes the end-to-end architecture of a web application built on Cohesity Gaia. The architecture follows a standard three-tier pattern: a frontend SPA, a backend API server, and the Gaia platform as the data and AI layer.
High-Level Architecture¶
┌─────────────────────────────────────────────────────────────────────────┐
│ Your Application │
│ │
│ ┌───────────────────┐ ┌───────────────────────────────────┐ │
│ │ │ HTTP │ │ │
│ │ Frontend (SPA) │────────▶│ Backend (API Server) │ │
│ │ React / Vite │◀────────│ FastAPI / Python │ │
│ │ │ JSON │ │ │
│ └───────────────────┘ └──────────────┬────────────────────┘ │
│ │ │
└────────────────────────────────────────────────┼────────────────────────┘
│ HTTPS + apiKey header
▼
┌──────────────────────────────┐
│ Gaia REST API │
│ helios.cohesity.com/v2/mcm │
│ /gaia/* │
└──────────────┬───────────────┘
│
┌──────────────┴───────────────┐
│ Cohesity Data Cloud │
│ │
│ ┌─────────┐ ┌───────────┐ │
│ │ Vector │ │ LLM │ │
│ │ Store │ │ Engine │ │
│ └─────────┘ └───────────┘ │
│ ┌─────────────────────────┐ │
│ │ Indexed Enterprise Data │ │
│ │ (Backups, Files, M365) │ │
│ └─────────────────────────┘ │
└───────────────────────────────┘
The Layers¶
Frontend — React SPA¶
The frontend is a single-page application (React + Vite in this guide, but any SPA framework works). It is responsible for:
- Collecting user queries and displaying AI-generated answers
- Rendering streaming responses token-by-token
- Managing UI state: selected datasets, active conversations, loading indicators
- Sending the API key once during initial connection setup
Framework Flexibility
While this guide uses React with Vite and Zustand for state management, the Gaia API is framework-agnostic. You can use Vue, Angular, Svelte, or even a CLI — anything that can make HTTP requests to your backend.
Backend — FastAPI / Python¶
The backend sits between the frontend and the Gaia API. It serves several critical purposes:
- API key protection — The Gaia API key never leaves the backend. The frontend authenticates via a session token.
- Request enrichment — Add defaults, validate inputs, inject security contexts.
- Response transformation — Shape Gaia responses for the frontend's needs.
- Session management — Track which API key belongs to which user session.
- Streaming proxy — Forward SSE streams from Gaia to the frontend.
from fastapi import FastAPI, Depends
from gaia_sdk import GaiaClient
app = FastAPI()
@app.post("/api/ask")
async def ask_question(
query: str,
datasets: list[str],
gaia: GaiaClient = Depends(get_gaia_client),
):
response = await gaia.ask(datasets, query)
return {
"answer": response.response_string,
"sources": response.documents,
"conversationId": response.conversation_id,
}
Gaia REST API¶
The Gaia API is the interface to the Cohesity Data Cloud's RAG engine. All interactions — dataset management, queries, uploads, conversations — go through this REST API.
Base URL: https://helios.cohesity.com/v2/mcm/gaia
Authentication: apiKey HTTP header on every request.
Cohesity Data Cloud¶
The underlying platform that stores, indexes, and manages enterprise data. This includes:
- Vector Store — Embeddings of document chunks for semantic retrieval
- LLM Engine — Orchestrates the language model to generate answers from retrieved context
- Data Sources — Backup snapshots, file shares, M365 data, databases, and uploaded documents
Request Flow¶
Here's what happens when a user asks a question:
User types a question
│
▼
┌───────────────┐ POST /api/ask ┌──────────────┐
│ Frontend │───────────────────▶│ Backend │
│ (React) │ │ (FastAPI) │
└───────────────┘ └──────┬───────┘
│
Resolves session → API key
│
POST /ask (with apiKey header)
│
▼
┌──────────────────┐
│ Gaia API │
└────────┬─────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌────────────┐ ┌─────────────┐ ┌────────────┐
│ Embedding │ │ Vector │ │ LLM │
│ Query │ │ Search │ │ Generate │
└────────────┘ └─────────────┘ └────────────┘
│ │ │
└────────────────┴────────────────┘
│
{ responseString, documents,
queryUid, conversationId }
│
▼
Response flows back:
Gaia → Backend → Frontend → User
Step by step:
- The user types a question in the frontend.
- The frontend sends a POST request to the backend's
/api/askendpoint with the query and selected dataset names. - The backend looks up the session to retrieve the Gaia API key, then forwards the request to the Gaia API.
- Gaia embeds the query, searches the vector store for relevant document chunks, and sends the top results along with the query to the LLM.
- The LLM generates an answer grounded in the retrieved documents.
- Gaia returns the answer (
responseString), source documents, aqueryUid, and aconversationId. - The backend transforms and returns the response to the frontend.
- The frontend displays the answer and source citations to the user.
Session-Based Authentication Pattern¶
A critical architectural decision is how to handle API keys in a web application. The pattern used in this guide:
┌───────────┐ ┌───────────┐
│ Frontend │ │ Backend │
└─────┬─────┘ └─────┬─────┘
│ │
│ POST /api/connect │
│ { apiKey: "abc123" } │
│───────────────────────────────▶│
│ │── Validate key against Gaia API
│ │── Store key in server-side session
│ { sessionId: "sess_xyz" } │
│◀───────────────────────────────│
│ │
│ All subsequent requests │
│ include sessionId (cookie │
│ or header), never the │
│ API key. │
│───────────────────────────────▶│── Resolve session → API key
│ │── Call Gaia with apiKey header
Never expose the API key in frontend code
The API key should only exist in the backend's memory. The frontend sends it once during the connection step and then uses a session token for all subsequent requests. This prevents key exposure in browser developer tools, network logs, or JavaScript bundles.
Key API Concepts¶
| Concept | Endpoint | Description |
|---|---|---|
| Datasets | GET /datasets | Named collections of indexed enterprise data. You query against one or more datasets. |
| Ask (RAG Query) | POST /ask | Send a question and get an LLM-generated answer grounded in your data. |
| Streaming | POST /ask/stream | Same as Ask, but returns the answer as an SSE stream for real-time display. |
| Exhaustive Search | PUT /ask/exhaustive | Retrieve all matching documents with pagination — no LLM generation, just search. |
| Conversations | GET /conversations | Multi-turn conversation tracking. Pass a conversationId to maintain context. |
| Refine | POST /ask/refine | Re-answer a question using only specific documents for a more focused response. |
| Document Upload | POST /upload-session | Upload files for Gaia to index alongside existing datasets. |
| Feedback | POST /query-feedback | Submit quality feedback on responses to improve the system over time. |
Technology Choices¶
This guide uses the following stack, but the Gaia API works with any technology:
| Layer | Technology | Why |
|---|---|---|
| Frontend | React 18 + Vite | Fast dev experience, huge ecosystem, component-based UI |
| State Management | Zustand | Lightweight, no boilerplate, works well with async |
| Routing | React Router v6 | Standard SPA routing |
| Backend | FastAPI (Python) | Async-native, auto-generated docs, Pydantic validation |
| Gaia SDK | gaia_sdk (this project) | Type-safe, async, handles SSE streaming |
| HTTP Client | httpx | Async HTTP with streaming support |
Next Steps¶
- Prerequisites — Install everything you need.
- Authentication — Connect to Gaia.
- Your First API Call — Make it real.