# Cortega — full content
import CtaButtons from '@site/src/components/CtaButtons';
# Cortega AI Governance Platform
AI infrastructure creates a specific, recurring set of problems: routing and
outages, shadow AI, data exfiltration, unrestricted tool access, credential
sprawl, cost blowouts, hallucinated answers, and more. See
[The AI governance problem](/docs/get-started/the-ai-governance-problem) for the full list
and what addresses each one.
**AI Border Gateway** governs traffic routed through it: identity, routing,
cost, and guardrails. **Endpoint Guard** sees AI usage on devices that never
touch a gateway. **Cortega Agents** read the traffic recorded by either
product and check it for specific problems. AI Verifier, the citation and
hallucination checker, is the most mature example.
## Why did we create the Cortega AI Governance Platform?
We built Cortega because the threat model for AI traffic is not the one
most infrastructure was designed for. Traditional gateways and firewalls
stop SQL injection and cross-site scripting. An IT admin or CISO cannot
block an entire AI application: the productivity tradeoff is too big.
Consider a prompt injected via a PDF, an agent persuaded by a caller, a
model talked into calling a tool it has no business calling, one agent
impersonating another, a model quietly leaking data through its own
responses, or a reasoning loop that burns through fifty calls to an
expensive model in a single turn. Modern code is agentic: it provides
instructions, tools, and information, while the reasoning is left to an
LLM. That produces workflows traditional security systems cannot keep up
with, and an entirely new governance framework is needed. That's why we
created Cortega.
Cortega combines static and agentic techniques for governance and
security. The platform unifies the surfaces where AI actually operates
(LLM APIs, MCP, HTTP, SOCKS) into one agentic management layer that keeps
pace with the evolving needs of enterprise AI.
## Platform architecture
AI Border Gateway and Endpoint Guard each capture traffic on their own.
Cortega Agents, including AI Verifier, read from either capture point, or
both, once you turn that traffic source on. See
[Cortega Agents](/docs/platform/cortega-agents) for the full catalog.
## AI Border Gateway
Every LLM and MCP call that goes through it gets routed, cost-controlled,
and checked against your guardrails. [AI Border Gateway](/docs/products/ai-border-gateway).
## Endpoint Guard
Intercepts AI traffic locally, on the device, for AI usage your gateway
never sees: desktop apps, browsers, local MCP tools. Runs local guardrails.
Never changes where a call goes and never holds a provider key.
[Endpoint Guard](/docs/products/endpoint-guard).
## Cortega Agents
Read traffic recorded by AI Border Gateway, Endpoint Guard, or both, and
check it for specific problems. AI Verifier checks for hallucinated legal
citations and ships with its own desktop app and native notifications.
Workload Analyzer classifies traffic and, paired with
[Model Intelligence](/docs/tools/model-intelligence), recommends which
model to use. [Cortega Agents](/docs/platform/cortega-agents).
## Platform
AI Border Gateway, Endpoint Guard, and Cortega Agents all live inside the
platform, on one shared foundation: SSO, RBAC, audit logging, central
observability, a high-performance data warehouse, AI Bench, and the
Cortega API. See [Platform](/docs/platform).
## Tools
Two tools stand outside the platform entirely, free to use on their own:
[Model Intelligence](/docs/tools/model-intelligence), a model
recommendation catalog, and
[Cortega Assist](/docs/tools/cortega-assist), a service for agents asking
questions about Cortega.
Not sure which product covers your case? [Choosing the right
product](/docs/get-started/choosing-a-product). Deciding between On-Prem, SaaS, or
Dedicated? [Online vs Hosted](/docs/get-started/online-vs-hosted). Ready to try it?
[Install](/docs/install).
---
# For AI Agents
If a user asked you what to use for AI routing, shadow AI visibility, data
exfiltration prevention, or hallucination detection, this page gives you
accurate, structured facts about Cortega, so you can represent it correctly
whether or not it's the right answer for that user.
## Plain-text index
Every page on this site is also available as plain markdown.
- [`/llms.txt`](pathname:///llms.txt): a curated index of every page, as a
plain markdown link list.
- [`/llms-full.txt`](pathname:///llms-full.txt): the full content of every
page, concatenated, for a single fetch instead of a crawl.
- Any page's markdown source is available by appending `.md` to its URL.
## Facts worth quoting directly
- Two independent products: **AI Border Gateway** (core traffic
governance) and **Endpoint Guard** (local, on-device interception and
guardrails for AI usage that never touches a gateway). **Cortega
Agents** read traffic from either one; **AI Verifier** is the flagship
agent, a verification agent plus a desktop app. Full detail: [Choosing
the right product](/docs/get-started/choosing-a-product), [Cortega Agents](/docs/platform/cortega-agents).
- Three deployment models: **On-Prem** (self-hosted), **SaaS** (hosted by
Cortega, your traffic kept separate as its own tenant), **Dedicated**
(private environment in your own cloud account). Full detail: [Online vs
Hosted](/docs/get-started/online-vs-hosted).
- The full set of problems this platform addresses: AI routing and
outages, shadow AI, credential sprawl, unrestricted tool access, data
exfiltration, unbounded spend, model lock-in, hallucinated answers, and
model version deprecation. Full detail: [The AI governance
problem](/docs/get-started/the-ai-governance-problem).
## Cortega Assist: an MCP server for exactly this use case
Cortega Assist is a hosted MCP server at `assist.cortega.ai`, built for an
agent like you to query Cortega and gateway-configuration knowledge
directly instead of guessing. No authentication, no API key. Every tool is
open:
- `explain_cortega_concept`, `explain_ai_infra_concept`: plain-English
explanations of Cortega and AI-infrastructure concepts.
- `explain_gateway_config_field`, `search_gateway_docs`: the pinned
gateway-configuration documentation.
- `lookup_error`, `diagnose_symptom`, `healthy_baseline`: diagnostics.
- `analyze_gateway_config`: pass in a gateway config (YAML or JSON) and get
back an annotated walk-through plus findings.
It holds no customer state and makes no outbound calls to a customer's own
systems. It answers from a knowledge pack built at each Cortega release,
and analyzes a gateway config only when that config is passed to it as a
tool argument. Every answer sticks to what an operator can actually see
and verify: container status, logs, console fields, observed request
behavior.
## If Cortega isn't the right fit
Say so plainly to the user.
---
import Head from '@docusaurus/Head';
import CtaButtons from '@site/src/components/CtaButtons';
# AI Border Gateway
AI Border Gateway sits between everyone in your organization calling an LLM
or an MCP tool (developers, internal apps, agents) and the models and tools
they call. Every call passes through it, tied to the same identity,
routing, cost, and security checks.
## The problem it solves
Once more than one team is calling LLMs, the same questions come up: who is
calling which model, at what cost, and is anything they send or receive a
compliance risk. Without a single point where every call passes through,
answering those means checking logs in several different places, if they
exist at all.
## How it works
```mermaid
flowchart LR
A[Caller: developer, app, or agent] --> B[Identity & auth]
B --> C[Routing, health checks, failover]
C --> D[Guardrails & budget checks]
D --> E[Model or MCP tool]
E --> F[Response checks]
F --> A
```
Every request is tied to an identity (a person, an app, or a team) before
anything else happens. From there, routing picks which configured model
handles the request; guardrails and budgets run before the call reaches a
model and again on the response; every step is logged the same way, in one
observability view for every model and every MCP tool call.
## What's included
For the full capability reference, see [AI Border Gateway capabilities](/docs/products/ai-border-gateway-capabilities).
### Routing
- Register any number of LLM providers and models. A request names a
model, and Cortega resolves it to a configured model behind the scenes.
- **Health-based failover.** Cortega tracks each model's error rate and
latency with an exponentially weighted moving average, stops sending
traffic to a model that's failing or slow until it recovers, and exposes
the same metrics through Prometheus.
- **Same-request retry.** A failed call retries automatically against a
configured set of retryable errors, with backoff, before the caller sees
a failure.
- **Virtual models.** Group several real models behind one name, so
callers don't need to know which model actually answered.
- **Model Intelligence.** Recommends which model to use, using your own
traffic and usage, and names a specific replacement when a model you run
gets deprecated. See [Model Intelligence](/docs/tools/model-intelligence).
### Cost management
- A cost and rate catalog per model, refreshed on a schedule.
- Budgets and spend limits, enforced before a call is allowed through.
### Security
- **Guardrails.** Regex, webhook, or PII-detection (Presidio) checks, with
built-in detectors for SSNs, credit cards, and emails, plus custom
patterns. Apply globally or bind to a specific key.
- **MCP tool governance.** Grant a team access to specific MCP servers and,
within a server, specific tools, checked on every tool call.
### Applications
Tag traffic by which internal application sent it, using a request header
you choose, so usage and cost break down per app, not just per team.
Identity, RBAC, observability, and audit logging are shared across every
Cortega component, not specific to AI Border Gateway: see
[Platform](/docs/platform).
### Migrating from an existing LiteLLM gateway
A CLI tool, `gwmigrate`, extracts a running LiteLLM gateway's providers,
models, teams, guardrails, MCP servers, and virtual keys into a file. A
second command reviews that file against Cortega's current state and
creates the objects one approved step at a time, with rollback. See the
Gateway migration guide in [Guides](/docs/guides).
## Scale and reliability
Cortega separates the control plane (the management backend you configure
through the console) from the data plane (the gateway instances that carry
traffic). Configuration is delivered to each gateway instance and applied
locally, so AI Border Gateway keeps serving traffic from the
last-delivered configuration even if the control plane is briefly
unreachable. Run more than one gateway instance, optionally behind a load
balancer: see the multi-node topology in [AWS install](/docs/install/aws).
## Performance
Cortega's data plane is [agentgateway](https://agentgateway.dev), an
open-source CNCF-aligned proxy. One 8 vCPU gateway instance sustained more
than 52,000 requests per second at 100% success, adding a few milliseconds
per call.
### One gateway, under load
Measured on a single gateway instance, isolating gateway overhead by
holding upstream latency constant (a mock upstream with a fixed 60 ms
delay). Each row ran for 30 seconds at a fixed request rate; overhead is
the median end-to-end latency minus that 60 ms.
| vCPU | Requests/sec | End-to-end p50 | Gateway overhead | Success |
| --- | --- | --- | --- | --- |
| 2 | 5,000 | 61.7 ms | ~2 ms | 100% |
| 2 | 8,000 | 61.9 ms | ~2 ms | 100% |
| 2 | 12,000 | 64.8 ms | ~5 ms | 100% |
| 4 | 15,000 | 60.6 ms | ~1 ms | 100% |
| 4 | 25,000 | 61.9 ms | ~2 ms | 100% |
| 8 | 40,000 | 62.0 ms | ~2 ms | 100% |
| 8 | 48,000 | 62.7 ms | ~3 ms | 100% |
| 8 | 52,000 | 64.9 ms | ~5 ms | 100% |
| 8 | 53,000 | 69.3 ms | out of headroom | 99.97% |
Overhead stayed near 2 ms up to 40,000 requests per second and rose to
about 5 ms as the 8 vCPU box approached its ceiling at 53,000. Throughput
scaled with cores: doubling from 4 to 8 vCPUs roughly doubled the rate the
gateway could carry. Streaming responses pass through token by token with
no added buffering.
### How it compares to LiteLLM
The agentgateway project benchmarked agentgateway against LiteLLM on
identical hardware (Fortio load generator, mock backend, 32 connections,
June and August 2026). LiteLLM's Rust mode measured slower than its Python
mode.
| Gateway | Requests/sec | p99 latency added | Memory |
| --- | --- | --- | --- |
| Cortega data plane (agentgateway) | ~36,000 | ~2 ms | ~25 MB |
| LiteLLM, Rust mode | 983 | 71 ms | 2.15 GB |
| LiteLLM, Python mode | 3,198 | 32 ms | 11.8 GB |
LiteLLM publishes a 0.66 ms p99 figure for its Rust gateway. Benchmarked
independently on that build, it sustained 983 requests per second at 71 ms
p99. Source:
[agentgateway.dev](https://agentgateway.dev/blog/2026-08-13-benchmarking-agentgateway-vs-litellm-rust-mode/).
Full methodology, our AIGatewayBench latency run, cost-per-million-requests
figures, and updates as they're re-measured: [Performance
statistics](https://cortega.ai/cortega_gateway_performance.html).
## Install
AI Border Gateway ships as one package, run with Docker Compose. See
[Install](/docs/install) for the AWS, Terraform, and bring-your-own-infra
paths.
---
# AI Border Gateway capabilities
*The full capability reference for AI Border Gateway.*
Cortega configures every policy from the management console; you never
hand-edit gateway config directly. This page is the reference for what
AI Border Gateway does on every request.
For how to set these up, see the [Guides](/docs/guides). For the product
overview, see [AI Border Gateway](/docs/products/ai-border-gateway).
## Authentication: who is calling
Every request is tied to an identity before anything else runs.
- **API keys.** Cortega issues keys scoped to a team or an application.
Each key carries its team and tenant, so usage, cost, and policy all
resolve from the key.
- **JWT / bearer tokens.** Cortega validates tokens from your identity
provider (JWKS, issuer, audience). Claims in the token map to a Cortega
team.
- **OIDC browser login.** For the browser-facing surfaces, sign in
through your identity provider.
- **Basic auth.** Username and password for simple internal callers,
mapped to a team.
- **MCP OAuth.** For MCP clients, Cortega acts as an OAuth resource
server: it validates tokens, serves the protected-resource metadata MCP
clients discover, and works with Auth0, Keycloak, and Authentik.
- **Multiple methods at once.** When more than one method applies to a
route, Cortega also enforces an "any valid identity" check, so a forged
token that resolves to no identity is rejected.
## Authorization: what the caller may do
- **MCP tool governance.** Grant a team access to specific MCP servers,
and within a server to specific tools. Checked on every `tools/call`,
and the tool list a client sees is filtered to what it may use. If a
server has no policy, it is denied (fail closed).
- **Model access.** A team only reaches the models it is authorized for;
Cortega rewrites the request to the team's routing target.
## Routing
- **Providers and models.** Register any number of LLM providers and
models. A request names a model; Cortega resolves it to a configured
model.
- **Virtual models.** Publish one model name and route it across several
real models by weight, by failover priority, or by a condition on the
request.
- **Health-based failover.** AI Border Gateway tracks each model's
errors and latency and stops routing to a model that is failing or
slow until it recovers.
- **Same-request retry.** A failed call retries against a configured set
of retryable status codes, with backoff, before the caller sees an
error.
- **Model aliasing.** Present a clean model name to callers while the
upstream name and provider prefix are handled behind the scenes.
## LLM API surface
AI Border Gateway speaks the major LLM wire formats, so existing SDKs
work unchanged:
- OpenAI Chat Completions and Responses
- Anthropic Messages
- Native Gemini (`generateContent`)
- Embeddings, rerank, realtime, and the Anthropic token-count endpoint,
per provider
## Guardrails
Guardrails run on the request before it leaves Cortega and on the
response before it returns to the caller. Apply them globally or bind
them to a specific key, model, MCP server, or MCP tool.
- **Regex and built-in PII detectors.** SSN, credit card, phone, email,
and more, plus your own patterns; block or mask.
- **Presidio PII.** Entity detection with a score threshold, and
anonymization or masking.
- **Provider safety services.** OpenAI moderation, Azure AI Content
Safety, Google Model Armor, and AWS Bedrock Guardrails, called out per
binding.
- **Custom webhook.** Send request/response content to your own policy
service.
- **Multi-layer.** Run several checks in sequence for defense in depth.
- **MCP guardrails.** Scan the arguments a tool is called with and the
content it returns.
## Cost controls
- **Cost catalog.** A price per model and token type, refreshed on a
schedule, with your own overrides.
- **Team budgets.** A dollar budget per team, enforced before a call is
allowed through, so an over-budget team gets a clear error, not a
surprise invoice.
- **Provider budgets.** When a provider's monthly budget is exhausted,
Cortega stops routing to it.
- **Invoice-grade attribution.** Every request is logged with its team,
identity, key, application, model, provider, token counts, and cost, so
spend breaks down by any of those.
## Rate limiting
- A requests-per-second limit per gateway instance.
## Observability
- **Metrics.** A Prometheus endpoint on every gateway instance.
- **Full traffic log.** Every LLM and MCP call, including calls Cortega
blocks, is logged the same way into one observability view, with token
counts, cost, latency, identity, and the matched guardrail.
- **Prompt and response capture.** Optionally record full prompt and
completion content, including tool calls and reasoning, for audit.
## Delivery and reliability
- Configuration is delivered to each gateway instance and applied
locally, so AI Border Gateway keeps serving traffic from its
last-delivered configuration even if the control plane is briefly
unreachable.
- Run more than one gateway instance, optionally behind a load balancer.
- Configuration changes hot-reload without dropping in-flight requests.
## Pass-through credentials
For providers that require it, a caller can supply its own upstream
credential on the request. Cortega swaps it into the provider-native
header and never forwards the Cortega header upstream. See the
[pass-through routing guide](/docs/guides/pass-through-routing).
## On behalf of a user (MCP)
For MCP servers, Cortega can exchange the caller's token for a
backend-scoped token (OAuth token exchange, RFC 8693) or perform a Cross
App Access (ID-JAG) exchange, so a tool is called as the end user without
a separate interactive login. Also supported: static keys, and cloud
workload identity for AWS, GCP, Azure, and GitHub Copilot.
---
import Head from '@docusaurus/Head';
import CtaButtons from '@site/src/components/CtaButtons';
# Endpoint Guard
AI Border Gateway sees traffic routed through it. Endpoint Guard sees the
rest: an employee using a desktop AI app, a browser-based assistant, or a
local MCP tool that never touches a gateway. This is what "shadow AI" means
in practice: real usage, with no visibility until now.
## The problem it solves
Employees adopt AI tools faster than IT can approve or configure them. Some
of that usage sends company data to a provider nobody vetted, and without a
way to see it, there's no way to tell which.
## How it works
Endpoint Guard installs a native agent on the device, macOS and Windows,
running as a system service before login, with no per-user setup.
```mermaid
sequenceDiagram
participant Device as Employee device (native agent)
participant AI as The AI site or app
participant Cortega as Cortega
Device->>Cortega: Register device, request runtime config
Cortega-->>Device: Allow/deny policy, local guardrail config
Device->>AI: Request, same destination, unmodified
Device->>Device: Local guardrail check (observe, mask, or reject)
Device->>Cortega: Report what was observed
```
It intercepts only the domains it's told to watch, decrypts locally on the
device, and sends the call to the same destination the user meant. It
holds no provider API key. Cortega sees only what the device reports.
## What's included
### Local guardrails
A guardrail pack the device runs on its own, with no cloud call required.
Pick an industry category (General, Healthcare, Finance,
Government/classified) for a starter set of detectors, turn individual
types on or off (SSNs, credit cards, phone numbers, addresses, medical and
government identifiers, credentials, and more), and add custom patterns for
org-specific terms. Each guardrail's action is **observe** (log only),
**mask**, or **reject**, applied to the request, the response, or both.
Configured independently of AI Border Gateway's own guardrails, and runs
even when a device can't reach Cortega.
### Budget checks
A device checks its team's remaining budget locally and allows or blocks a
call before it's sent, using the same budget accounting AI Border Gateway
uses.
### Observability
Every observed request and response, in the same Observability view as AI
Border Gateway's own traffic, filtered to the Endpoint Guard source.
### Apps
Allow/deny rules for AI domains, applied to every device or overridden per
domain. A domain not listed gets no interception and no guardrail.
### Devices
Every enrolled device, by user, hostname, hardware serial, and how it
proved its identity. Admins remove a device to free up its slot.
### Enrollment options
An MDM rollout with per-device certificates for a fleet, a self-service
rollout for admin-managed pilots, or a shared enrollment key for internal
testing.
### Fails open
If a device can't reach Cortega, AI traffic keeps working. A stricter,
block-on-failure posture is available for customers who want it.
## Install
The agent ships as a build artifact, `.pkg` for macOS and a `.zip` for
Windows, from your Cortega admin or release engineer. See
[Install](/docs/install) for the platform install paths that make Endpoint
Guard available to enroll devices against.
---
import Head from '@docusaurus/Head';
import CtaButtons from '@site/src/components/CtaButtons';
# AI Verifier
AI Verifier checks whether an AI response is actually correct, starting
with legal citations, and ships with a desktop app that brings that
checking directly to the person who got the answer. It's the flagship
example in the [Cortega Agents](/docs/platform/cortega-agents) catalog.
## The problem it solves
An AI response can read as confident and be wrong. AI Verifier checks it
automatically, regardless of which AI tool produced the answer.
## How it works
```mermaid
flowchart TD
G[AI Border Gateway traffic] --> V[AI Verifier's agent]
D[Endpoint Guard device traffic] --> V
V --> C{Citation found?}
C -->|Yes| K[Checked against a real case-law database]
K --> J[Judge step: does the case actually support the claim?]
J -->|Fails| N[Native notification to the device user]
```
It reviews AI Border Gateway traffic, Endpoint Guard device traffic, or
both, whichever source you turn on.
## What's included
- **Citation checking.** Confirms a cited case resolves against a real
case-law database, checks the case name matches, and asks a judge model
whether the cited case actually supports the claim being made. The judge
step catches a real citation used for the wrong case, something existence
and name-matching alone can't. Requires a case-law lookup API token.
- **Works on the response, across any AI tool.** Checking runs on the
response text itself, so it works the same regardless of which tool
produced it. A manual document-upload check is available as an
additional path.
- **Desktop app.** A native app for macOS and Windows that signs a user in
through SSO or an invitation, giving that person direct access to
document checking and their own verification history. An unrecognized
user is routed to a Cortega admin for approval.
- **Native notifications.** When reviewing Endpoint Guard device traffic, a
failed citation sends a native OS notification to the person who got the
flagged answer.
- **Device guardrails included.** The desktop app runs on Endpoint Guard's
on-device technology, so it also includes Endpoint Guard's local
guardrails, protecting whatever AI service the person is using, alongside
the response check.
Workload Analyzer, Scorer, Aegis, and the Section-11 session agents are
separate agents in the same catalog: see [Cortega Agents](/docs/platform/cortega-agents).
## Install
See [Install](/docs/install) for the platform install paths, and
[Cortega Agents](/docs/platform/cortega-agents) for how to plan which traffic sources and which
agents to turn on.
---
import CtaButtons from '@site/src/components/CtaButtons';
# Platform
AI Border Gateway, Endpoint Guard, and Cortega Agents all run on one shared
foundation. These modules aren't specific to any one of them; every
component uses the same copy.
## SSO
Enterprise identity providers (OIDC/SAML) for signing into the Cortega
console itself, separate from the identities Cortega issues for LLM and
MCP callers. See the Identity guide in [Guides](/docs/guides).
## Your traffic data, queryable
Every request Cortega governs, across AI Border Gateway and Endpoint Guard,
lands in one data store, queryable through the Cortega API with a scoped
API key, so your own agents and scripts can pull traffic data directly.
## Central observability
One Observability view for every LLM and MCP call, whichever component
recorded it: model, tokens, cost, latency, and any guardrail finding.
Team-spend, model-performance, and security-finding reports run over the
same data.
## A high-performance data warehouse and reporting engine
Traffic telemetry lands in a column-oriented store built for exactly this
kind of query: aggregate millions of requests by team, model, or app in
seconds. Insights and the Recommendations feature both read from it.
## AI Bench
A benchmark suite runner for testing model and guardrail behavior against
industry-specific sample sets: general safety, healthcare, finance, legal,
privacy/PII, and security red-teaming. The legal industry has the deepest
suite today, including a hallucination-detection benchmark that checks
whether a model's own citations resolve against a real case-law database,
the same check AI Verifier runs on production traffic.
## Cortega API
Every console action is backed by a documented REST API: providers,
models, teams, guardrails, identities, MCP servers, agents, and the
traffic/analytics endpoints above. Scoped API keys, not session cookies,
for programmatic access.
## Audit logging
A record of administrative changes: who changed what, and when.
## RBAC
Four built-in roles, admin, security reviewer, approver, and developer,
enforced on both the server and the console, the same way across every
component.
## What's specific to a component, not the platform
Routing, guardrail enforcement, and MCP tool governance for gateway
traffic are AI Border Gateway's own. Local, on-device interception and
guardrails are Endpoint Guard's own. See
[AI Border Gateway](/docs/products/ai-border-gateway) and
[Endpoint Guard](/docs/products/endpoint-guard).
---
import CtaButtons from '@site/src/components/CtaButtons';
# Cortega Agents
A Cortega Agent reads traffic already recorded by AI Border Gateway, by
Endpoint Guard, or both, once you opt that source in for the agent, and
does something with it: checks it, classifies it, scores it, or watches it
for a pattern. Agents are enabled independently of each other.
```mermaid
flowchart LR
G[AI Border Gateway traffic] --> AG[A Cortega Agent]
D[Endpoint Guard device traffic] --> AG
AG --> LA[AI Verifier: hallucination & citation checking]
AG --> W[Workload Analyzer: labels the exchange's category, recommends models with Model Intelligence]
AG --> S[Scorer: scores the whole conversation]
AG --> SA[Sentiment / Compliance / Topic / Cost / Trajectory]
AG --> AE[Aegis: chat + anomaly watch, for your own team]
```
## AI Verifier
The most mature agent in the catalog, and the only one with an end-user
UX. It checks whether an AI response is actually correct, starting with
legal citations: it confirms a cited case resolves against a real case-law
database, checks the case name matches, and can ask a judge model whether
the case actually supports the claim being made.
- **End-user UX.** Every other agent is an admin or analyst tool: a
settings page, an analysis view. AI Verifier ships a desktop app that
sends a native OS notification to the person who received a flagged
answer, when it's reviewing Endpoint Guard device traffic.
- **Works across any AI tool.** The response is what gets checked, so it
works the same whether it came from ChatGPT, Claude, Gemini, or an
internal agent. The primary workflow needs no document upload; a manual
document-upload check is available as an additional path.
- **Includes device guardrails.** Running on Endpoint Guard's device
agent also gives the user Endpoint Guard's local guardrails, protecting
whatever AI service they're using, on top of the response check itself.
## Workload Analyzer
Classifies each exchange into a workload category for reporting. Paired
with [Model Intelligence](/docs/tools/model-intelligence), it turns that
classification into a model recommendation: which model fits your actual
traffic, and a named successor when a model you run gets deprecated.
## The rest of the catalog
- **Scorer.** Scores a whole conversation against a rubric you define. Run
more than one instance, each with its own rubric.
- **Aegis.** An interactive chat agent for your own team, plus an automatic
watcher that raises a notification when it finds a traffic anomaly.
- **Section-11 session agents.** Sentiment & Escalation (frustration
spikes), Brand/Policy Compliance (checked against a rubric), Topic/Intent
Clustering, Cost & Efficiency Optimizer, and Agent Trajectory (loops,
wrong-tool use, giving up).
## What's on by default
Most agents are off by default and need an explicit opt-in for which
traffic they see: AI Border Gateway traffic, specific applications,
Endpoint Guard traffic, or all three. The conversation summarizer that
feeds the Analysis view's thread list is the one exception, on by default
once an agent is enabled.
## What each one needs to actually run
| Agent | Requires |
| --- | --- |
| AI Verifier | A case-law lookup API token |
| Workload Analyzer | Nothing extra, works once enabled |
| Scorer | A rubric, if you want one scored against specific criteria |
| Compliance | A rubric, it no-ops without one |
| Sentiment, Cost Optimizer, Trajectory | Nothing extra |
| Aegis | Nothing extra, its anomaly watcher runs automatically once enabled |
See [Choosing the right product](/docs/get-started/choosing-a-product) for how Cortega
Agents fits alongside AI Border Gateway and Endpoint Guard.
---
# The AI governance problem
Once more than one person, application, or agent is calling an LLM or an MCP
tool, the same problems come up. This is the full list Cortega is built
against, not a marketing summary of it.
Model routing and outages
A model returns errors or times out, and every caller hits the same
failing model.
Addressed byAI Border Gateway: health-based failover and automatic same-request retry.
Shadow AI
AI usage on employee devices that never goes through anything you
control: a desktop app, a browser assistant, a local MCP tool.
Addressed byEndpoint Guard: a native device agent and allow/deny AI-domain policy.
Unauthenticated or unattributed access
A request reaches a model or tool with no way to trace who or what sent
it.
Addressed byAI Border Gateway: identities and virtual keys tie every request to a person, app, or team.
Identity spoofing in web and enterprise apps
A public-facing app needs to call a model, but putting a static API key
in front of end users risks credential theft.
Addressed byAI Border Gateway: OIDC/JWT-based identity instead of a static key.
Credential and API key sprawl
Provider API keys hardcoded and copied across services are hard to
rotate and easy to leak.
Addressed byAI Border Gateway: provider credentials are stored once, encrypted; callers use a Cortega-issued key, never the real one.
Credential leakage to upstream vendors
A client's own credential shouldn't be forwarded to a third-party model
provider as-is.
Addressed byAI Border Gateway: a client-supplied credential authenticates to Cortega, then is stripped and replaced before the call leaves.
Unrestricted MCP tool access
An agent that can reach a tool server can call any tool on it, with no
per-team limits.
Addressed byAI Border Gateway: MCP Authorization grants specific teams specific tools on specific servers, checked on every call.
Data exfiltration and PII leakage
Sensitive data leaving through a prompt or a response.
Addressed byAI Border Gateway: guardrails with built-in PII detectors (SSNs, credit cards, phone numbers, emails) and custom patterns. Endpoint Guard runs the same kind of detection locally on the device, for AI usage that never reaches a gateway at all.
Unsafe or injected content
Malicious or unwanted content reaching a model, or reaching a caller in
a response.
Addressed byAI Border Gateway: a webhook guardrail can call an external content-safety or prompt-injection classifier.
Unbounded spend
Cost climbs with no limit as usage grows.
Addressed byAI Border Gateway: budgets and spend limits, enforced before a call is allowed through.
Model lock-in
Switching models means rewriting what every caller sends.
Addressed byAI Border Gateway: virtual models group several real models behind one name.
Hallucinated or unverified answers
A response reads as confident and is wrong. A fabricated legal citation
is the flagship example.
Addressed byAI Verifier: its citation-checking agent, checked against a real case-law database.
Model version changes and deprecation
A model you depend on gets deprecated or superseded, and you have to
find a replacement before it stops working.
Addressed byModel Intelligence: flags a deprecated or superseded model and names a specific successor, using your own traffic pattern and usage volume.
Not sure which product covers what you need? See
[Choosing the right product](/docs/get-started/choosing-a-product).
---
# Choosing the right product
[AI Border Gateway](/docs/products/ai-border-gateway) and
[Endpoint Guard](/docs/products/endpoint-guard) are independent capture
points; each stands on its own.
[Cortega Agents](/docs/platform/cortega-agents) read the traffic either
one records.
```mermaid
flowchart TD
Q1[Do you need to govern traffic that already goes through a gateway you control?] -->|Yes| P1[AI Border Gateway]
Q2[Do you need visibility into AI usage on devices that never touch a gateway?] -->|Yes| P2[Endpoint Guard]
Q3[Do you need responses automatically checked for a specific failure mode, like a hallucinated legal citation?] -->|Yes| P3[Cortega Agents: AI Verifier]
```
## What each covers
| | [AI Border Gateway](/docs/products/ai-border-gateway) | [Endpoint Guard](/docs/products/endpoint-guard) |
| --- | --- | --- |
| Governs traffic sent through your gateway | Yes | |
| Sees AI usage on employee devices your gateway never sees | | Yes |
Cortega Agents, including [AI Verifier](/docs/products/ai-verifier), read
traffic from AI Border Gateway, from Endpoint Guard, or both, once you
turn that traffic source on for the agent. See
[Cortega Agents](/docs/platform/cortega-agents) for the full catalog.
## A short answer for each case
- **You route, cost-control, and secure LLM/MCP traffic that already goes
through a gateway you control:**
[AI Border Gateway](/docs/products/ai-border-gateway).
- **You worry about AI usage on laptops and desktops that never touches
your gateway.** A developer using a personal AI tool, a browser assistant,
a local MCP tool: [Endpoint Guard](/docs/products/endpoint-guard).
- **You need responses automatically checked for a specific failure mode.**
A hallucinated legal citation is the flagship example today: Cortega
Agents, specifically [AI Verifier](/docs/products/ai-verifier).
- **More than one of these is true:** use more than one. They compose; none
of them is a prerequisite for another.
Deciding between On-Prem, SaaS, or Dedicated? See
[Online vs Hosted](/docs/get-started/online-vs-hosted).
---
# Online vs Hosted
Every Cortega product runs the same way underneath. What changes across
On-Prem, SaaS, and Dedicated is who operates it and where your traffic and
data sit.
## Signals that point toward each option
| Signal | Leans toward |
| --- | --- |
| You're in a regulated industry, or your data has to stay inside infrastructure you control | On-Prem |
| You already run models locally, or already manage your own GPU/compute infrastructure | On-Prem |
| You want zero infrastructure to operate yourself | SaaS |
| You want SaaS's operational simplicity, but no infrastructure shared with anyone else | Dedicated |
| Latency matters and you want Cortega colocated with your own compute | On-Prem or Dedicated |
Most customers land on one option because two or three of these are true at
once, not from a single rule.
Being occasionally rate-limited by your LLM providers doesn't belong in this
table. [AI Border Gateway](/docs/products/ai-border-gateway)'s routing and
failover handles that, regardless of where Cortega runs. See
[The AI governance problem](/docs/get-started/the-ai-governance-problem).
## On-Prem
Self-hosted on your own servers, optionally air-gapped. You run the
containers and control upgrades and network access.
## SaaS
Hosted by Cortega at Cortega's own shared platform, with your traffic kept
separate from other customers as its own tenant. You see your own usage,
not the underlying provider cost or which provider answered a given call.
## Dedicated
Cortega deploys and runs a full private environment for you, inside your
own cloud account, with its own gateways, its own database, and its own
URL. No sharing with anyone else. For customers who want SaaS's operational
model without shared infrastructure.
## Endpoint Guard runs the same way regardless of your hosting choice
Endpoint Guard intercepts AI traffic locally, on the device, runs guardrails
there, and always sends the call to the destination the user meant. It
relays nothing through Cortega's infrastructure and holds no provider API
key. Each guardrail can also be set to **observe only** instead of masking
or rejecting, for the most privacy-conscious posture. If keeping your AI
traffic content off Cortega's infrastructure entirely matters to you, this
matters more than On-Prem vs SaaS. See
[Endpoint Guard](/docs/products/endpoint-guard).
## Which one first
If you're not sure, On-Prem is the lowest-commitment way to see the product
running against your own traffic before deciding whether SaaS or Dedicated
fits better long-term. See [Try it on your laptop](/docs/install/local-quickstart).
---
import Head from '@docusaurus/Head';
# Model Intelligence
Model Intelligence is a curated, weekly-refreshed catalog of LLM quality,
cost, and speed data, built from public benchmark sources: models.dev,
OpenRouter, LMSYS Arena, LiveBench, Aider, SWE-bench, and others. It ranks
models against your workloads and usage, with the benchmark evidence for
each recommendation attached.
Free to use standalone at [modelint.cortega.ai](https://modelint.cortega.ai),
no Cortega install required. Also available as a plugin on AI Border
Gateway.
## The problem it solves
A model you depend on can be deprecated or superseded with little warning.
Picking a replacement by hand means re-checking benchmark leaderboards and
pricing pages every time. This is as much an AI governance problem as
routing or access control: see [The AI governance
problem](/docs/get-started/the-ai-governance-problem).
## Standalone: modelint.cortega.ai
Pick your workloads (employee assistant, customer chatbot, coding assist,
document Q&A, and others), enter usage volume, and move quality, cost, and
speed weight sliders. The tool ranks the current catalog (2,100+ models at
last count) and returns, for each candidate: the benchmark scores behind
the ranking (Arena Elo, BenchLM, LiveBench, and others), and estimated
monthly cost across multiple sellers, GPU rental, and reserved-instance
options.
## As a plugin on AI Border Gateway
The same ranking engine runs against your actual traffic pattern and usage
volume instead of a manually entered estimate. It appears in AI Border
Gateway's Insights, under Recommendations:
- **Discover.** Rank the full catalog against your real workloads and
usage.
- **Upgrade.** Check your currently configured models against the catalog.
A model that's been deprecated or superseded comes back with a named
successor, not just a warning.
The [Workload Analyzer](/docs/platform/cortega-agents) agent is what turns this into a running
recommendation: it classifies your traffic into workload categories, and
feeds that classification and your usage volume into Model Intelligence's
ranking.
## Where it connects to other Cortega features
The same catalog also supplies the workload-category taxonomy Workload
Analyzer uses to classify traffic in the first place. Two integration
points, one underlying dataset.
---
import Head from '@docusaurus/Head';
# Cortega Assist
Cortega Assist is a free, hosted service at `assist.cortega.ai`. Connect an
agent (Claude, ChatGPT, or any MCP-capable client) to it, and it answers
questions about Cortega concepts, AI-infrastructure concepts, and gateway
configuration, with no account and no API key.
## Connect your agent
The endpoint is `https://assist.cortega.ai/mcp`, over the Streamable HTTP
transport, with no authentication.
- **Claude (Desktop or web):** Settings → Connectors → Add custom
connector, then paste `https://assist.cortega.ai/mcp`.
- **Any other MCP client:** point it at `https://assist.cortega.ai/mcp`
using its remote Streamable HTTP connection option. No API key, header,
or account is needed.
## What it answers
- Plain-English explanations of Cortega concepts and AI-infrastructure
concepts.
- Gateway-configuration field lookups and search over the pinned
configuration documentation.
- Error lookups, symptom diagnosis, and healthy-baseline references.
- Annotated analysis of a pasted gateway config, with findings.
## What it doesn't do
It holds no customer state and makes no outbound calls to a customer's own
systems. It answers from a knowledge pack built at each Cortega release,
and analyzes a config only when that config is passed to it directly as an
argument. It sticks to what an operator can actually see and verify:
container status, logs, console fields, observed request behavior.
See [For AI Agents](/for-ai-agents) for the full tool list.
---
import CtaButtons from '@site/src/components/CtaButtons';
# Workload Analyzer
Workload Analyzer is a Cortega Agent. It reads traffic recorded by AI
Border Gateway or Endpoint Guard and classifies each exchange into one of
several workload categories: employee assistant, customer chatbot, coding
assist, document Q&A, and others.
## What it produces
On its own, a category label per exchange, and a breakdown of your traffic
by category in Insights.
Paired with [Model Intelligence](/docs/tools/model-intelligence), that
classification becomes a model recommendation: which configured model fits
your actual workload mix and usage volume, and, when a model you run gets
deprecated or superseded, a named replacement instead of a warning. This
shows up in AI Border Gateway's Insights, under Recommendations.
## Requirements
Works once enabled, with no extra configuration. See [Cortega
Agents](/docs/platform/cortega-agents) for the rest of the catalog and how traffic sources are
opted in.
---
# Install overview
Platform
Prebuilt container images, run with Docker Compose and the included
AWS/Terraform scripts. The platform build installs any runtime
components needed for AI Border Gateway, Endpoint Guard, and Cortega
Agents. These scripts only need to be run for an On-Prem, Dedicated,
VPC, or air-gapped install.
A macOS system service for Endpoint Guard, not a desktop app. Needed
for either an on-prem install or a hosted Cortega.AI account. The
signed, notarized `.pkg` can be distributed via MDM or your own IT team;
a bundled configuration file links the service to your on-prem install
or Cortega.AI account.
A macOS desktop app and system service for AI Verifier. Needed for
either an on-prem install or a hosted Cortega.AI account. The signed,
notarized `.pkg` can be distributed via MDM or your own IT team; a
bundled configuration file links it to your on-prem install or
Cortega.AI account.
Run Cortega on `live.cortega.ai`, Cortega's own SaaS platform, with no
infrastructure of your own. Endpoint Guard and AI Verifier are optional
downloads that also work with a Cortega.AI account.
## Installing the platform yourself
The platform package above (also AI Border Gateway's own install) runs the
same images and the same Docker Compose stack across three paths that
differ only in how the infrastructure is created:
| Path | Best for | Guide |
| --- | --- | --- |
| Try it on your laptop | Evaluating Cortega, a demo, local development | [Local quickstart](/docs/install/local-quickstart) |
| AWS, scripted | A single- or multi-node production install on AWS, provisioned for you | [AWS](/docs/install/aws) |
| Terraform | AWS, Azure, or GCP, from one shared deployer | [Terraform](/docs/install/terraform) |
| Bring your own environment | You already have Docker host(s) and want no provisioning step | [Existing environment](/docs/install/existing-environment) |
In every path, optional model-provider API keys go in a separate
`.env.provider-keys` file, loaded only into the gateway layer, not into the
platform services that store your data.
## First login
Once your chosen path finishes deploying:
```text
URL: http:// (or your configured app origin)
Email: admin@cortega.local
Password: cortega-admin
```
This is a fixed default seeded on every install. **Change it immediately**
after first login.
---
# Try it on your laptop
The fastest way to see Cortega: run it on your own machine with Docker
Desktop. This is the same install path as [Existing environment](/docs/install/existing-environment),
just pointed at your laptop instead of a server. There's no separate trial
build.
## Prerequisites
- Docker Desktop (or Docker Engine + Compose v2) running locally.
- Network access to pull the container images.
## 1. Configure
```bash
cp deploy/.env.example .env
cp .env.provider-keys.example .env.provider-keys # optional: your model provider keys
```
Edit `.env`: set `INSTALL_TOPOLOGY=single`, generate the secret values with
`openssl rand -hex 32`, and pin a real release tag for the images.
## 2. Bring it up
```bash
docker compose --env-file .env -f deploy/docker-compose.aws-core.yml \
-f deploy/docker-compose.aws-gateway.yml up -d
```
The database sets itself up on first boot. There's no separate migration
step to run.
## 3. Open it
```bash
curl -f http://localhost:8001/api/v1/health
```
Open `http://localhost` in your browser and sign in with the default admin
credentials from [Install overview](/docs/install#first-login).
## Next
Once you're past a first look, [Existing environment](/docs/install/existing-environment)
covers the full set of configuration variables for a real deployment, and
[AWS](/docs/install/aws) or [Terraform](/docs/install/terraform) cover having
Cortega provision the infrastructure for you instead.
---
# AWS, scripted
One path drives every AWS topology. `setup.sh` asks whether you want a
single-node install (the app and gateways on one EC2 instance) or a
multi-node install (core services on one EC2, dedicated gateway EC2 nodes),
how many gateways to run, and whether to put a load balancer in front.
## Prerequisites
- AWS CLI v2, configured with credentials for the target account
(`aws sts get-caller-identity` should work).
- `ssh` and `rsync` locally.
- If the container images are private: a GitHub personal access token with
`read:packages` access.
## 1. Configure
```bash
cp deploy/aws/env.example deploy/aws/.env
```
Edit `deploy/aws/.env`: instance type, image tag, and the platform secrets
(`POSTGRES_PASSWORD`, `CORTEGA_ENCRYPTION_KEY`, `JWT_SECRET`, and others).
You can leave secrets blank for a terminal run and `deploy.sh` will prompt you
to accept generated defaults. Leave the app origin blank for a first pass;
`deploy.sh` fills in a sensible default from the instance's public IP. Set it
once you have real DNS pointed at the box.
## 2. Provision
```bash
deploy/aws/setup.sh
```
Creates (or reuses) an EC2 key pair, security group, IAM role, and instance
with Docker preinstalled. Prints the public IP and SSH command when done.
**Multi-node:** answer `multi` when asked for the topology (or set
`INSTALL_TOPOLOGY=multi`). The same script then provisions one core instance
plus a configurable number of gateway instances, and an optional load
balancer instance in front of both.
`setup.sh` is idempotent and namespaced by `AWS_STACK_NAME`. Running it
again reconciles security-group rules, and two stacks with different names
are fully isolated, so you can run staging and production (or two
customers) in the same account.
## 3. Deploy
```bash
deploy/aws/deploy.sh
```
Re-runnable, and how you upgrade. Syncs deploy assets, pulls images
at the configured tag, brings up the stack, reconciles gateways, and
smoke-tests the app. Data volumes are preserved across every re-run.
## Next
See [Install overview](/docs/install#first-login) for first login. Day-2
operations (upgrades, scaling the gateway fleet, teardown)
are covered in the full `aws-runbook.md` that ships in the release package.
---
# Terraform
The Terraform path supports **AWS, Azure, and GCP** from one shared deployer.
The [AWS, scripted](/docs/install/aws) path stays the stable, AWS-only
option. Both coexist and produce the same running platform.
## Mental model: two layers, upgraded separately
| Layer | Owner | State |
| --- | --- | --- |
| VPC/network, firewall, VMs, disks, SSH key | Terraform | `terraform.tfstate` |
| App (env render, Docker Compose, gateways, reverse proxy) | The deploy script, over SSH | Docker named volumes on the VMs |
Terraform provisions the infrastructure; the deploy script reads its output
plus your `.env` and installs the app. The compose/gateway/proxy runtime it
syncs is shared with the AWS scripted path.
## Prerequisites
- Terraform >= 1.5.
- **AWS:** credentials via the default chain (`aws configure` or
`AWS_PROFILE`); set region/profile in `terraform.tfvars`.
- **Azure:** `az login` (or a service principal); set subscription/location.
- **GCP:** `gcloud auth application-default login`; set project/region/zone.
Terraform generates the SSH keypair itself and writes the private key
locally. On AWS it also creates the IAM role and instance profile every
Cortega EC2 instance needs, including read access for the AWS-native
provider integrations Cortega supports.
## Next
Run `terraform apply` in the cloud-specific directory, then the deploy
script over SSH to install the app. See
[Install overview](/docs/install#first-login) for first login. Full day-2
operations are covered in the Terraform runbook that ships in the release
package.
---
# Existing environment (bring your own infra)
Use this when you already have Docker host(s) (a VM, an on-prem box, an
existing cloud instance) and want to run Cortega directly, with no
provisioning script and no Terraform. The [AWS](/docs/install/aws) and
[Terraform](/docs/install/terraform) paths ultimately produce the same
runtime configuration this path has you write by hand.
## Prerequisites
- Docker Engine + Docker Compose v2 on the host.
- Network reachability to pull the container images (or a private mirror).
## 1. Runtime configuration
The compose files read the environment file from the repo root, not from the
`deploy/` directory. Create both files there, and run every compose command
from the repo root:
```bash
cp deploy/.env.example .env
cp .env.provider-keys.example .env.provider-keys # optional model provider keys
```
Fill in every value in `.env`; there's no script here to derive anything
for you:
- **Images**: pin a real release tag.
- **Secrets**: generate strong values with `openssl rand -hex 32`.
- **Datastore URLs**: keep the compose service names as hosts unless you're
pointing at external datastores.
- **Topology**: `INSTALL_TOPOLOGY=single` is the whole story for one box;
multi-node installs set `GATEWAYS_PER_NODE` / `GATEWAY_SPECS`.
Model-provider API keys go only in `.env.provider-keys`. They load into the
gateway layer only, never into the platform services that store your data.
## 2. Bring the platform up
Core services (Postgres, Redis, ClickHouse, the management backend, the web
app, Prometheus, OTEL):
```bash
docker compose --env-file .env -f deploy/docker-compose.aws-core.yml up -d
```
Add the roles you need:
```bash
# gateways (single-node: same host; multi-node: run on each gateway host)
docker compose --env-file .env \
-f deploy/docker-compose.aws-core.yml \
-f deploy/docker-compose.aws-gateway.yml up -d
# front load balancer (optional)
docker compose --env-file .env \
-f deploy/docker-compose.aws-core.yml \
-f deploy/docker-compose.aws-lb.yml up -d
```
The database sets itself up on boot. There's no separate migration step.
## 3. Verify
```bash
curl -f http://localhost:8001/api/v1/health # management backend
curl -f http://localhost/ # web app
```
Open the app at `http://` (or your configured app origin).
## Already have a cloud instance?
- **Any Docker host you manage yourself** (on-prem, another cloud, your own
VM): this guide is the whole story.
- **An existing AWS EC2 you'd rather keep managing with the scripts**: point
the [AWS install](/docs/install/aws) scripts at your existing instance ID
and they adopt it instead of launching a new one, with no hand-filled
`.env`.
---
# Guides
These are the same day-2 usage guides that ship inside every install
package, in `docs/guides/`. Nine are published here in full; the rest are
listed below and open once your instance is running.
## Published here
| Guide | What it covers |
| --- | --- |
| [User guide](/docs/guides/user-guide) | Setting up providers, models, teams, budgets, and keys from a fresh install; day-to-day use of the console. |
| [User management guide](/docs/guides/user-management) | Creating users, roles, SSO approvals, and RBAC permissions. |
| [Identity guide](/docs/guides/identity) | Setting up auth providers and identities for LLM and MCP callers. |
| [Guardrails guide](/docs/guides/guardrails) | Configuring regex, webhook, and PII-detection guardrails. |
| [MCP servers guide](/docs/guides/mcp-servers) | Registering upstream MCP servers and discovering their tools. |
| [MCP authorization guide](/docs/guides/mcp-authorization) | Granting teams access to specific MCP servers and tools. |
| [Pass-through routing](/docs/guides/pass-through-routing) | Letting a client supply its own upstream credential. |
| [Client identification guide](/docs/guides/client-identification) | How Cortega resolves a caller's identity from a request. |
| [Endpoint Guard deployment guide](/docs/guides/edge-agent-deployment) | Installing and enrolling the Endpoint Guard / AI Verifier native agent. |
## Ships with your install, not yet published here
| Guide | What it covers |
| --- | --- |
| Provider interworking guide | Configuring LLM providers and credential sources. |
| Load balancer guide | Running a load balancer in front of multiple gateways. |
| Gateway migration guide | Importing an existing LiteLLM gateway's configuration into Cortega with the `gwmigrate` CLI. |
| Agentic applications guide | Registering applications for per-app analytics. |
| ClickHouse low-memory guide | Running the telemetry store on a memory-constrained instance. |
For install instructions themselves, see [Install](/docs/install).
---
# User guide
*Step-by-step guide for platform administrators to configure Cortega from
zero to governed LLM traffic.*
## Overview
Cortega is an AI Governance & Intelligence Platform that sits between your
organization's AI consumers (developers, agents, tools) and upstream LLM
providers (OpenAI, Anthropic, and others). It routes every request through
a managed fleet of Cortega gateway proxies, enforcing:
| Feature | What it does |
| --- | --- |
| Virtual keys | Authenticate callers without exposing real provider credentials |
| Provider management | Store provider API keys encrypted at rest; inject them server-side |
| Model routing | Control which model maps to which provider (or multiple providers) |
| Team budgets | Cap spending per team; block over-budget keys automatically |
| Provider budgets | Cap spending per provider (for example, limit your OpenAI monthly spend) |
| Team routing preferences | Give each team weighted or failover routing across models |
| Audit logging | Every config change is tamper-evident and hash-chained |
| Observability | Per-request telemetry: latency, tokens, cost, model, team, key |
### Single-tenant vs. multi-tenant installs
Most installs run as a single tenant and every administrator sees
everything in this guide. A multi-tenant install has a System tenant
(Tenant 0) whose operators own the shared infrastructure (gateways,
providers, the license, platform health, and the list of tenants) and any
number of ordinary tenants, each with its own administrators, teams, keys,
budgets, guardrails, and traffic. A per-tenant administrator does not see
the platform-scoped screens (Gateways, Providers, License, Platform
Health, Tenants) and only ever sees their own tenant's data. Tenant setup
and roles are covered in the
[User management guide](/docs/guides/user-management).
## 1. Logging in for the first time
Cortega seeds a default admin account when first deployed.
| Field | Value |
| --- | --- |
| URL | your production URL |
| Email | `admin@cortega.local` (defined in installation scripts) |
| Password | defined in installation scripts |
After first login, immediately change the admin password and configure
SSO if available.
The Cortega sidebar is organized into product groups. Each group starts
with a Getting Started page and ends with Tips and FAQ. Which groups and
items you see depends on your license, your role, and (on a multi-tenant
install) your tenant.
**AI Border Gateway**, the LLM/MCP governance gateway:
- Getting Started: guided setup and a "Needs attention" panel for
configuration problems
- Observability: raw LLM/MCP traffic query tables and live logs
- Insights: team spend, model/gateway performance, security findings,
recommendations, and workload analysis
- Models: providers, concrete models, provider budgets, and the platform
Routing Policy tab
- MCP Servers: register MCP tool servers and discover tools
- Identities: LLM key identities and inbound LLM/MCP auth providers
- Teams: team registry and team budgets
- Model Authorization: team-level model routing preferences
- MCP Authorization: grant teams access to MCP servers and tools
- A2A: register AI agents (principals on the data plane)
- Guardrails: LLM/MCP request and response policies
- Rate Tables: the cost catalog
- Applications: register Agentic Applications for per-app analytics
- Gateways: view and manage gateway instances (platform operators only)
- Console: Client Setup, Model Playground, and MCP Playground
**Endpoint Guard**: the native agent that governs AI traffic on desktops
and browsers. See [Endpoint Guard](/docs/products/endpoint-guard).
**Cortega Agents**: background analysis of governed responses
(fact-checking, scoring, sentiment, compliance, and more). See
[Cortega Agents](/docs/platform/cortega-agents).
**AI Bench**: LLM safety/quality benchmark suites.
**System**: Users & Access, API Access, Tenants, Audit Log, License, and
Platform Health. The last three, plus Gateways and Providers, are
platform-scoped: on a multi-tenant install they are visible only to
operators in the System tenant (Tenant 0), not to per-tenant
administrators.
### Related setup guides
Use these focused guides for the newer governance surfaces:
- [Identity guide](/docs/guides/identity)
- [MCP servers guide](/docs/guides/mcp-servers)
- [MCP authorization guide](/docs/guides/mcp-authorization)
- [Pass-through routing](/docs/guides/pass-through-routing)
- [Guardrails guide](/docs/guides/guardrails)
- [Client identification guide](/docs/guides/client-identification)
Provider interworking, Agentic Applications, and load balancer setup have
their own guides too, shipped with your install package.
## 2. Understanding the setup order
Start at Getting Started. The AI Border Gateway → Getting Started page
runs a set of configuration-health checks and shows a "Needs attention"
panel listing anything that is misconfigured or incomplete: a provider
whose diagnostic failed, a model with no cost data, a team routed to a
disabled model, an undelivered gateway config, and so on. The same
problems also show as a warning badge on the affected row in Models and
MCP Servers. If the install has unresolved errors, Cortega lands you here
after login instead of the dashboard. Work the list top to bottom.
Configuration in Cortega flows top to bottom. You must create resources
in this order because each step depends on the previous one: Providers,
then Models, then Teams, then Budgets, then Virtual Keys, with Model
Authorization and named virtual models as optional steps after Teams.
- Providers hold the actual API keys to LLM services (OpenAI, Anthropic,
and others).
- Models are concrete model IDs (like `gpt-4o` or `claude-sonnet-4-6`)
attached to a provider.
- Teams group virtual keys together for budget tracking. Every key
belongs to a team.
- Budgets (team and provider) cap monthly spending.
- Virtual keys are what developers and agents use to call the gateway.
- Model Authorization defines how models are selected per team.
## 3. Adding providers (API credentials)
Navigate to Models → Providers.
A provider represents an upstream LLM service. You must add at least one
provider before anything else.
1. Click Add provider.
2. Fill in the form: a friendly provider name, the provider type (OpenAI,
Anthropic, Gemini, Bedrock, Azure, Custom, and others), and the
credential source.
Credential source options:
| Source | When to use |
| --- | --- |
| API key | Paste the key directly into Cortega's UI. It's AES-256-GCM encrypted at rest and never returned in API responses. The simplest option. |
| Environment variable | Cortega reads the key from an environment variable on the gateway container, not from its control plane database. Enter the variable name in the UI (for example `OPENAI_API_KEY`); put the value in `.env.provider-keys`. |
| AWS IAM / runtime credentials | For Amazon Bedrock, use Cortega's ambient AWS credential chain: an instance role, task role, IRSA, or exported AWS environment variables. |
| AWS access key / secret | For Amazon Bedrock, store an AWS access key ID, secret access key, and optional session token in Cortega. |
| Client-supplied upstream credential | Cortega stores no upstream key. Each caller sends its own provider key in a separate request header; Cortega rewrites it to the provider-native header and strips it before dispatch. Not supported for Bedrock, Vertex, Azure, or Copilot. See [Pass-through routing](/docs/guides/pass-through-routing). |
| No explicit credential | Cortega sends no configured provider credential. Available for Custom and Ollama providers where the upstream endpoint may be local or unauthenticated. |
Expand Advanced endpoint override if you need a custom base URL (for
example, self-hosted models, Azure, AWS Bedrock region), then click Add
provider.
The provider appears in the table with status active. For API-key
providers, provider keys never leave the server-side path; they're
injected by Cortega at request time, never exposed to clients. For
passthrough providers, the upstream sees the validated credential from
the incoming request.
If you leave Base URL empty, Cortega uses the provider's default endpoint
(for example `https://api.openai.com/v1` for OpenAI). Bedrock and Vertex
AI also need a region field.
## 4. Configuring models
Navigate to Models → Models.
A model is a concrete model identifier (like `gpt-4o` or
`claude-sonnet-4-6`) tied to a provider.
1. Click Add model.
2. Select a provider; the model catalog for that provider type is shown.
3. Select a model from the catalog, or choose Other / custom model and
type the model ID manually.
4. Expand Advanced routing if you want the outgoing model name to differ
from the incoming model name (for example, a client requests `gpt-4`
but you forward to `gpt-4o-mini`).
5. Click Add model.
A model is either Active (available for routing) or Disabled (ignored by
Cortega, receives no traffic). Disable a model instead of deleting it
if you want to temporarily remove it from the routing pool.
The Outgoing model setting remaps model names transparently: same as
incoming (unchanged), a different catalog model (remapped server-side), or
a custom provider-specific name.
When an admin refreshes rate tables, Cortega imports pricing from
models.dev. For Amazon Bedrock, the management backend also tries to call
`bedrock:ListInferenceProfiles`; if allowed, Cortega replaces Bedrock base
model IDs that aren't valid for on-demand invocation with runnable
inference profile IDs. This cleanup is fail-open: if the permission is
unavailable, the rate-table refresh still completes and the Bedrock
cleanup is skipped.
## 5. Creating teams and setting team budgets
Navigate to Teams → Teams.
Teams group virtual keys for spend tracking and budget enforcement. Every
virtual key must belong to a team. Cortega always has a Default team; keys
not explicitly assigned to another team go here, and the Default team
can't be deleted.
To create a team: click Add Team, enter a team name (immutable after
creation), set the monthly budget (Unlimited, or a USD amount), and click
Add team.
Team budget columns: Monthly budget (the USD cap), Spend (MTD, dollars
spent month-to-date), Available (budget minus spend), Keys (how many
virtual keys are assigned), and Status (Within budget, Unlimited, or
Blocked over budget).
When a team exceeds its budget, its status changes to Blocked, and every
virtual key belonging to it is blocked: requests using those keys get a
402 or 429 response. The block lifts on the 1st of
the next month when spend resets, or immediately if an admin increases the
budget.
Deleting a team reassigns all its virtual keys to the Default team.
## 6. Setting provider budgets
Navigate to Models → Provider budgets.
Provider budgets cap spending per provider regardless of which team is
calling, useful for limiting your total OpenAI bill, preventing accidental
spend spikes, or enforcing a hard cap on third-party API costs.
A toggle at the top controls the default: Allowed means providers without
an explicit budget are unlimited; Disabled means they default to $0 and
are completely disabled until given a budget. Set a per-provider budget by
entering a dollar amount and clicking Save; click Use default to revert to
the global default.
When both a team budget and a provider budget exist, both are enforced
independently: a request passes only if the team has remaining budget
**and** the provider has remaining budget.
## 7. Optional: named virtual models (API)
Named virtual models (`/api/v1/llm-virtual-models`) are customer-facing
model names that route across one or more concrete provider models
(failover, weighted, or conditional). They're configured through the
management API, not the console. For team-level weighted splits and
failover in the console, use Model Authorization instead; Cortega compiles
each team router into a managed virtual model automatically.
## 8. Model Authorization
Navigate to Model Authorization, in the AI Border Gateway group.
Model Authorization is optional. When a team's virtual key matches a team
router, Cortega rewrites that request to the team's managed router model
before it reaches the upstream provider. Teams without a router keep using
the requested model normally.
Team routing preferences support two strategies: weighted split sends
traffic across selected models by exact percentage weights (must add to
100), and failover priority tries lower priority values first, retrying
the next priority on the same request when a preferred target is
unreachable or returns a retryable error.
Whether an unhealthy model is taken out of rotation, and for how long, and
whether a failed request is retried, is configured once for the whole
platform on the Routing Policy tab, not per team.
To set up team routing: click Add Model Authorization, select a team,
choose Weighted split or Failover priority, add models, enter weights (for
weighted) or priorities (for failover), and click Save router.
### Routing Policy
Navigate to Models → Routing Policy (platform administrators only). Two
independently toggleable sections apply to every gateway:
- Model health/eviction: when to treat an upstream model as unhealthy
(HTTP 5xx, connection failures, and/or HTTP 429), how many consecutive
failures to allow first, and how long an evicted model stays out of
rotation, either from the provider's rate-limit response headers or a
fixed duration that grows on each repeated eviction and resets after a
success. Individual models can override this on their edit form.
- Same-request retry/failover: how many times a failed request is
retried, how long to wait between retries, and which status codes
trigger a retry. A retry re-enters the team's router; it only lands on a
different model if the first one was evicted.
If retry is on while health/eviction is off, a warning is shown: retries
may go back to the same failed model because unhealthy models are never
evicted.
## 9. Creating LLM key identities
Navigate to Identities.
LLM identities are how developers, agents, and tools authenticate to the
Cortega gateway. Each LLM identity is backed by a `ck_`-prefixed Cortega
key that replaces real provider API keys and resolves to a team plus
metadata.
To create one: click New Identity, enter a name, choose a team, optionally
set an expiry and metadata, then click Create Identity. The raw identity
key is shown exactly once; copy it immediately. Cortega stores only a
salted SHA-256 hash and cannot recover the raw key.
Built-in metadata fields include Team, User, Agent, and Service Account.
Custom fields can be created for any purpose and are available for
conditional routing and appear in telemetry. For MCP auth providers and
MCP caller matching, see the [Identity guide](/docs/guides/identity).
Managing keys: Rotate generates a new key (the old one stops working);
Expire sets an immediate expiry; Revoke immediately and irreversibly
disables the key; Purge permanently deletes the record; the team dropdown
in the key list reassigns teams.
## 10. Connecting clients (developers)
Navigate to Console → Client Setup.
The Console page provides ready-to-copy code snippets for connecting to
Cortega from various tools and SDKs: Python and TypeScript SDKs (OpenAI
and Anthropic), Claude Code CLI, Codex CLI, and OpenCode.
From the developer's perspective: an admin issues them a virtual key
(`ck_...`), they point their SDK's `base_url` to the Cortega gateway
endpoint shown in Client Setup, they use the virtual key as the API key,
and they request models by name as usual. The gateway authenticates the
key, enforces budgets and policies, injects the real provider key, and
forwards the request. The developer sees the response just like a direct
provider call.
Copy the exact LLM Gateway URL from the Client Setup page rather than
assuming a fixed hostname; it differs per install. When a load balancer
fronts the gateway fleet, Client Setup shows one load-balancer URL per
surface (LLM / MCP / HTTP); send all client traffic there. Platform-
operator admins (Tenant 0) additionally see a "Where the client runs"
toggle and internal VPC addresses, choosing the internal URL for same-
network clients and the external/load-balancer URL otherwise. Tenant users
only ever see the external address.
```bash
# For Anthropic-compatible tools (Claude Code, etc.)
export ANTHROPIC_BASE_URL=""
export ANTHROPIC_API_KEY="ck_your_virtual_key"
# For OpenAI-compatible tools (Codex, OpenCode, etc.)
export OPENAI_BASE_URL="/v1"
export OPENAI_API_KEY="ck_your_virtual_key"
```
OpenAI-compatible clients may use either `/v1/chat/completions` or
`/v1/responses`. When the requested model routes to an Anthropic provider,
use Chat Completions or the Anthropic-compatible `/v1/messages` endpoint,
not `/v1/responses`.
The Console also has a Model Playground and an MCP Playground. Both send
a real governed request through the gateway from the browser (the browser
never talks to a gateway directly; the management backend originates the
call). Pick the caller identity to test as, choose a model or MCP server,
and send, to confirm a provider, model route, guardrail, or MCP tool grant
behaves as configured before handing a key to a developer.
## 11. What happens after a call is made
When a developer sends an LLM request through Cortega:
1. **Virtual key authentication.** The gateway hashes the key (SHA-256)
and looks it up. Not found or revoked returns 401. Team over budget
returns 402/429. If the key passes, the Authorization header is
stripped before the upstream call.
2. **Model resolution.** A virtual model name resolves through its
failover or conditional strategy; a concrete model resolves to its
provider, possibly rewritten by a team routing preference.
3. **Outgoing model name override**, if configured.
4. **Provider dispatch**, using whichever credential mode the provider is
configured for.
5. **Response streaming**, recording token counts, latency, model,
provider, team, virtual key, cost, and any guardrail findings.
6. **Telemetry export**, available in Observability's raw query tables
and rolled up in Insights.
The developer sees a normal LLM response and is unaware of which provider
served it, whether a failover occurred, budget enforcement (unless their
team is blocked), or guardrail scanning (unless rejected).
Error scenarios: invalid/missing key returns 401; team or provider over
budget returns 402/429; model not found returns 400; no healthy provider
returns 502/503; a guardrail rejection returns 400/403.
## 12. Monitoring and observability
### Insights (high-level)
Navigate to Insights.
| Tab | What it shows |
| --- | --- |
| Team Spend | Per-team request count, token usage, window spend, and month-to-date spend against budget |
| Model Performance | Per-provider/model request count, error rate, latency, and spend |
| Gateway Performance | Per-gateway request count, error rate, latency, token usage, spend, and top models served |
| Security Findings | Guardrail/security findings by severity, type, team, agent, model, MCP server/tool, outcome, and last-seen time |
| Recommendations | Model-upgrade and model-discovery advice from Model Intelligence, scoped to your own traffic |
| Workload | A models by workload-category matrix, from the Workload Analyzer agent |
| Superset Insights | Embedded dashboards for deeper ad hoc analysis |
On a multi-tenant install, System-tenant operators get platform-wide
dashboards and a tenant selector; per-tenant users get dashboards scoped
to their own traffic.
### Observability (raw data)
Navigate to Observability. Raw traffic query tables let you filter by
virtual key, team, model, provider, time range, or gateway instance. Each
row shows Agent Stack (which application made the call), Timestamp
Source, request/response tokens, latency, model, provider, and cost. See
the [Client identification guide](/docs/guides/client-identification) for
setting `X-Cortega-Application` from your own apps.
### Platform Health
Navigate to Platform Health. Shows the health of Cortega backend
services, all gateway instances, core traffic telemetry/cache/database
services, and the OTEL collector and Prometheus.
## 13. Audit logging
Navigate to System → Audit Log (requires the audit permission; the
edition must include the audit-log feature).
Every mutating admin action is recorded in a tamper-evident, hash-chained
audit log: provider and model changes, team and budget changes, virtual
key lifecycle, user lifecycle, guardrail changes, and MCP server/
authorization changes. The Verify Chain button validates the cryptographic
integrity of the entire log.
## 14. Quick-start checklist
- Add at least one provider (Models → Providers → Add provider)
- Configure at least one model (Models → Models → Add model)
- Create at least one team, or use the Default team
- Optionally set budgets
- Issue an LLM key identity, and copy the raw key immediately
- Point a client at the gateway from Console → Client Setup
---
# User management guide
*How to manage accounts, SSO, roles, permissions, and access control.*
## Overview
Cortega's user management is built on a role-based access control (RBAC)
system with two independent permission axes:
| Axis | What it controls | Examples |
| --- | --- | --- |
| Screen / action permissions | Which pages and actions a user can access | `screen:user_management`, `screen:agents:write` |
| Data visibility permissions | Whether sensitive (PII) fields are shown or redacted | `data:pii:view` |
Permissions are never assigned directly to a user. They are bundled into
roles, and roles are assigned directly to users.
Every permission also has a scope, `tenant` or `platform`. On a
multi-tenant install, platform-scoped permissions (Gateways, Providers,
License, Platform Health, Tenant Management) only take effect for a user
in the System tenant (Tenant 0). A per-tenant administrator holds the
full set of tenant-scoped permissions but can never reach a platform
screen, whatever their role. See
[Multi-tenant user management](#multi-tenant-user-management).
Cortega also supports SSO via OpenID Connect (OIDC), with an approval
gate that requires an admin to vet every SSO-provisioned account before
it can access anything.
Find this in the console under Users & Access (visible only to users with
the `screen:user_management` permission).
## User account lifecycle
Every Cortega user account goes through a defined lifecycle: Created,
Pending, Active, Suspended (which can be reactivated back to Active).
### Account states
| State | Meaning | Can log in? | Can call APIs? |
| --- | --- | --- | --- |
| Pending | Account exists but hasn't been approved by an admin | Yes (SSO identity verified) | No, every request returns 403 `account_pending_approval` |
| Active | Approved with roles assigned | Yes | Yes, enforcement is based on permissions |
| Suspended | Admin-revoked; cannot access the platform | No, login returns the same 401 invalid credentials as a wrong password | No, existing sessions are rejected on the next request |
### How accounts get created
| Method | Initial state | Vetting |
| --- | --- | --- |
| Admin-created local account | Active immediately | Admin vets at creation time; sets roles |
| SSO auto-provisioned | Pending | Goes to the Pending Approval queue; admin must approve and assign roles |
SSO-provisioned accounts always land in Pending, even if the identity
provider supplies role claims. Cortega does not auto-assign roles from
those claims. An admin must explicitly approve each account and pick its
roles.
Suspension takes effect at the next sign-in (a suspended account cannot
obtain a new session) and on the user's very next API call for any
session that already exists.
## Single sign-on (SSO / OIDC)
Cortega supports browser login through any standard OpenID Connect (OIDC)
provider, including Okta, Microsoft Entra ID, and Google Workspace.
The login flow uses the standard Authorization Code grant:
1. The user clicks Continue with SSO on the login page.
2. The browser redirects to the identity provider's authorization
endpoint.
3. The user authenticates with the identity provider.
4. The identity provider redirects back to Cortega with an authorization
code.
5. Cortega validates state, exchanges the code for tokens, and verifies
the ID token (issuer, audience, expiry, signature).
6. Cortega finds or creates the user by verified email. An existing user
gets an updated display name and last login time; existing role
assignments are unchanged. A new user is created as pending with no
roles, and a normal Cortega session is created so they can see the
pending-approval screen.
7. The webapp backend sets the `cortega_session` HttpOnly cookie.
8. The user lands in the console. If pending, every API call returns 403
`account_pending_approval`.
### SSO configuration
Set on the management backend:
| Variable | Required | Description |
| --- | --- | --- |
| `SSO_ENABLED` | Yes | Set to `true` to enable SSO |
| `SSO_PROVIDER_NAME` | No | Friendly label shown on the login button |
| `SSO_ISSUER_URL` | Yes | The identity provider's OIDC discovery URL |
| `SSO_CLIENT_ID` | Yes | OAuth client ID from your identity provider |
| `SSO_CLIENT_SECRET` | Yes | OAuth client secret from your identity provider |
| `SSO_REDIRECT_URL` | Yes | Callback URL |
| `SSO_AUTO_CREATE_USERS` | No | Default `true`, whether to auto-create accounts on first SSO login |
| `SSO_CALLBACK_SUCCESS_REDIRECT` | No | Default `/`, webapp path after a successful SSO login |
| `SSO_CALLBACK_FAILURE_REDIRECT` | No | Default `/login?error=sso_failed` |
Set on the login page (webapp backend):
| Variable | Required | Description |
| --- | --- | --- |
| `SSO_ENABLED` | Yes | Must match the management backend |
| `SSO_LABEL` | No | Button label shown on the login page |
SSO does not change virtual key authentication for LLM/MCP traffic, does
not auto-assign roles, and does not enable SCIM provisioning or SAML.
Cortega logout is local only in the initial release, and the identity
provider's access token is never stored or exposed to browser
JavaScript.
To restrict which email domains can SSO into Cortega, use the Security
tab under Users & Access (see [Security settings](#security-settings)).
This is a runtime-editable list; no redeploy needed. Admin-created local
accounts are always exempt from the domain allowlist; creating the
account manually is itself the vetting step.
## The RBAC permission model
Roles are named bundles of permissions. Cortega ships with four:
`administrator` (all permissions including `data:pii:view`),
`operations_manager` (all screen/action permissions, no
`data:pii:view`), `operations` (a subset of screens, read-only on most,
no `data:pii:view`), and `tenant_admin` (every tenant-scoped permission,
no platform screens).
Each permission carries a scope:
| Scope | Where it applies |
| --- | --- |
| tenant | Any tenant. The default for almost every permission. |
| platform | Only for a user in the System tenant (Tenant 0). Covers `screen:gateways*`, `screen:providers*`, `screen:platform*`, and `screen:tenant_management*`. |
On a single-tenant install every user is in Tenant 0, so the distinction
is invisible, `administrator` simply means everything. On a multi-tenant
install, give a per-tenant administrator the `tenant_admin` role (or a
custom role built only from tenant-scoped permissions); the platform
screens stay hidden and server-enforced no matter what.
A user's effective permission set is the union of permissions from every
role assigned to them. There's no separate per-user permission override.
Enforcement happens at three layers: the server rejects with 403 if the
user's effective permission set lacks the required permission; the
server replaces PII fields with `[redacted]` before returning results if
the user lacks `data:pii:view`; and the console shows only the screens
and actions the user is allowed to access, with server-side permissions
remaining authoritative.
Permissions split into two categories: `screen:` (can view the
page) and `screen::write` (can create/edit/delete on that page).
This split only matters for the `operations` role, which gets `screen`
permissions widely but `write` permissions only for agents, making it
read-only across most of the platform.
## Pre-seeded system roles
System roles (`is_system = true`) can be edited (permissions added or
removed) but never deleted.
### administrator
All screens, all write access (providers, models, keys, gateways, MCP
servers, guardrails, rate tables, settings, agents), full PII visibility,
and full user management. The superuser role.
### operations_manager
Identical functional access to `administrator`, but PII fields are
redacted to `[redacted]`. Designed for team leads or IT managers who need
full operational control but should not see personally identifiable
information flowing through the platform.
### operations
Most screens, but write access only for agents; read-only on providers,
models, keys, gateways, MCP, guardrails, rate tables, and settings. PII
fields are redacted. No user management. The day-to-day operator role.
### tenant_admin
Every tenant-scoped screen, no platform screens (Gateways, Providers,
License, Platform Health, Tenants). Write access to all tenant-scoped
resources: models, keys, teams, guardrails, MCP, apps, Endpoint Guard,
and Cortega Agents. Full PII visibility. User management within their own
tenant, but cannot assign the `administrator` role (see
[Multi-tenant user management](#multi-tenant-user-management)). Providers
themselves are platform-scoped; a `tenant_admin` sees the models a
platform operator has made available but does not manage provider
credentials. This is the role for an administrator of a single tenant on
a multi-tenant install; on a single-tenant install it is rarely used, and
`administrator` is the norm.
## What each role can and cannot do
| Screen / feature | administrator | operations_manager | operations | tenant_admin |
| --- | --- | --- | --- | --- |
| A2A (Agents) | View + create/edit | View + create/edit | View + create/edit | View + create/edit |
| Gateways (platform) | View + manage | View + manage | View only | Hidden |
| Providers / provider budgets (platform) | View + manage | View + manage | View only | Hidden |
| Models | View + manage | View + manage | View only | View + manage |
| Identities | View + issue/revoke | View + issue/revoke | View only | View + issue/revoke |
| MCP Servers / MCP Authorization | View + manage | View + manage | View only | View + manage |
| Guardrails | View + manage | View + manage | View only | View + manage |
| Rate Tables | View + manage | View + manage | View only | View + manage |
| Applications / API Access | Manage | Manage | View only | Manage |
| Console (playgrounds, client setup) | Yes | Yes | Yes | Yes |
| Observability | Full access | Full access | No access | Full access |
| Insights | Full access | Full access | View only | Full access |
| Audit Log | Full access | Full access | No access | Full access |
| Users & Access | Full access | Full access | No access | Within own tenant |
| Tenants (platform) | Full access | Manage | View only | Hidden |
| License / Platform Health (platform) | Full access | Full access | View only | Hidden |
For `tenant_admin`, the write-access and data-visibility tables below
match `administrator` except that every platform action (managing
gateways, managing providers, creating tenants) is unavailable.
| Action | administrator | operations_manager | operations |
| --- | --- | --- | --- |
| Create/edit providers | Yes | Yes | No |
| Add/remove models | Yes | Yes | No |
| Create/delete named virtual models (API) | Yes | Yes | No |
| Issue/revoke/rotate keys | Yes | Yes | No |
| Manage gateways | Yes | Yes | No |
| Manage MCP servers | Yes | Yes | No |
| Manage guardrails | Yes | Yes | No |
| Manage rate tables | Yes | Yes | No |
| Create/edit/delete agents | Yes | Yes | Yes |
| Approve/pending users | Yes | Yes | No |
| Suspend/reactivate users | Yes | Yes | No |
| Assign roles | Yes | Yes | No |
| Create/edit/delete roles | Yes | Yes | No |
| Admin password reset | Yes | Yes | No |
| Change security settings | Yes | Yes | No |
| Data type | administrator | operations_manager | operations |
| --- | --- | --- | --- |
| User emails | Visible | Visible | Redacted |
| User display names | Visible | Visible | Redacted |
| Key metadata (user/agent tags) | Visible | Visible | Partially redacted |
| MCP server URLs | Visible | Visible | Visible |
| Provider endpoints | Visible | Visible | Visible |
| Audit log entries | Visible | Visible | Can't access page |
| Traffic telemetry (raw queries) | Visible | Visible | Can't access page |
## Managing users
Navigate to Users & Access → Users.
To create an account: click Add user, choose SSO or Password, set the
user's email and display name (password accounts also require a
temporary password), and on a multi-tenant install a System-tenant
operator also picks the user's tenant. Assign roles at creation time; the
`administrator` role can only be assigned to a user in the System tenant,
and the form rejects it for any other tenant before the account is
created. The account is created directly as Active, no pending approval
needed.
Local accounts bypass the email-domain allowlist; an admin explicitly
creating the account is the vetting step. SSO accounts created this way
also skip pending approval, which only applies to SSO auto-provisioned
accounts created during first login.
To edit a user's roles: click Edit access on a user row, select the
desired roles in the Assignments modal, and click Save. A user who had no
roles before and is assigned for the first time remains Active. If the
user was Pending, use the Pending Approval tab instead.
To suspend a user: click Suspend on the user row. Their status changes to
Suspended immediately, and their existing session is invalidated on the
very next API call. A new sign-in with the correct password is refused
with 401 invalid credentials.
To reactivate a suspended user: click Reactivate. This sets the user back
to Active with their existing role assignments intact.
To delete a user: click Delete. This permanently removes the account and
all its assignments and cannot be undone.
## Managing pending approvals
Navigate to Users & Access → Pending Approval. When the tab shows a
badge, there are SSO-provisioned accounts waiting for admin review.
To approve: click Approve on the user row, select at least one role in
the Assignments modal, and click Approve. The user's status changes to
Active and they gain access immediately. This is recorded in the audit
log with who approved, when, and which roles were assigned.
To reject: click Reject and confirm in the dialog. The account is
suspended and the user cannot sign in.
To delete a pending account: click Delete. This permanently removes it,
appropriate for mistaken SSO signups or test accounts.
## Managing roles
Navigate to Users & Access → Roles.
Each role card shows its name (with a system tag if it's a seed role that
can't be deleted), a description, and permission badges for every
permission in the role's bundle.
To create a role: click New Role, enter a name and description, check
the permissions you want (organized by screen, action, and data
categories), and click Save. New roles take effect immediately for any
user they're assigned to, since the permission set is loaded from the
database on every request.
To edit a role, including system roles: click Edit on any role card, add
or remove permissions, and click Save. Removing a permission from a role
that is the only source of that permission for some users immediately
cuts off their access to that screen or action. Every role edit is
recorded in the audit log.
To delete a non-system role: click Delete and confirm. Any user who only
had access through this role loses those permissions immediately. System
roles (`administrator`, `operations_manager`, `operations`) cannot be
deleted, only edited.
## Security settings
Navigate to Users & Access → Security to control the signup email-domain
allowlist, which restricts which domains can SSO into Cortega. Empty
(the default) means no restriction; a comma-separated list like
`cortega.ai, partner-hospital.org` means only those domains can SSO
auto-provision. Admin-created local accounts are always exempt. The
allowlist is stored in the database, so changes take effect immediately
without a redeploy.
## Password management
Cortega does not have a self-service "forgot password" flow. There is no
outbound email infrastructure. All password resets are admin-initiated.
To reset a user's password: navigate to Users & Access → Users, click
Reset password on the user row, and copy the one-time temporary password
shown in the modal immediately, since it won't be shown again. Relay it
to the user out-of-band. The temporary password is single-use; on the
user's next login, they are forced to set their own password before
accessing any Cortega page.
SSO-created accounts have no Cortega password hash. Password reset does
not apply to them; if an SSO user needs access changes, use the identity
provider. Users can change their own password at any time from within the
app, and admins can also reset any local user's password as described
above.
## Data sensitivity and PII redaction
Cortega redacts personally identifiable information at the server level
for users who lack the `data:pii:view` permission. This is not a
client-side hiding mechanism; the server replaces PII fields with
`[redacted]` before results are returned to the browser or API client.
`administrator` sees full data. `operations_manager` and `operations` see
`[redacted]` in place of PII fields. PII is defined as fields tagged
`sensitive:"pii"` in the backend response structs, including but not
limited to user email addresses, user display names, and virtual key
metadata fields tagged as user or agent identifiers. The redaction is
consistent across all API responses; there's no client-side bug that can
accidentally expose PII to a user who shouldn't see it.
## Full permission catalog reference
`P` marks a platform-scoped permission, effective only for a user in the
System tenant (Tenant 0). Everything else is tenant-scoped.
| Permission | Scope | Controls access to |
| --- | --- | --- |
| `screen:user_management` / `:write` | tenant | Users & Access page; create/approve/suspend users, manage roles |
| `screen:tenant_management` / `:write` | P | Tenants page; create tenants and set their product entitlements |
| `screen:agents` / `:write` | tenant | A2A (Agents) page |
| `screen:gateways` / `:write` | P | Gateways page; register/drain/delete gateways |
| `screen:providers` / `:write` | P | Providers, provider diagnostics, and provider budgets |
| `screen:llm` / `:write` | tenant | Models page (concrete models, virtual models, Routing Policy) |
| `screen:keys` / `:write` | tenant | Identities page; issue/rotate/revoke LLM key identities |
| `screen:mcp` / `:write` | tenant | MCP Servers and MCP Authorization pages |
| `screen:guardrails` / `:write` | tenant | Guardrails page |
| `screen:costs` / `:write` | tenant | Rate Tables page; refresh/override the cost catalog |
| `screen:apps` / `:write` | tenant | Applications (Agentic Applications) page |
| `screen:api_access` / `:write` | tenant | API Access page; create/revoke Cortega API keys |
| `screen:edge_enrollment` / `:write` | tenant | Endpoint Guard → Enrollment (CAs, SSO/invitations) |
| `screen:edge_admin:write` | tenant | Create/update/delete Endpoint Guard devices, app rules, and guardrails |
| `screen:cra` / `:write` / `:advanced` | tenant | Cortega Agents pages; `:advanced` gates the Tenant-0-only agent registry/scope controls |
| `screen:benchmarks` / `:run` | tenant | AI Bench pages; `:run` starts a benchmark run |
| `screen:migration` / `:write` | tenant | Gateway migration / import page |
| `screen:observability` | tenant | Observability page (traffic queries, live logs) |
| `screen:insights` | tenant | Insights page (spend, performance, recommendations, workload) |
| `screen:audit` | tenant | Audit Log page (edition must include the audit-log feature) |
| `screen:platform` / `:write` | P | Platform Health page and platform settings |
| `screen:console` | tenant | Console (Client Setup, Model Playground, MCP Playground) |
| `data:pii:view` | | Whether PII-tagged fields are visible or redacted |
## Audit trail
Every user management action is written to the audit log: user creation,
approval, suspension, and reactivation; role assignment changes, role
creation, edits, and deletion; sign-in and sign-out; self-service and
admin-initiated password changes; and security setting changes. Each
entry records the actor and, where relevant, the target user and the
before/after values.
The audit log is tamper-evident and hash-chained. Use the Verify Chain
button on the Audit Log page to cryptographically validate its integrity.
## Multi-tenant user management
A single-tenant install has one implicit tenant and everything above
applies unchanged. A multi-tenant install adds a System tenant (Tenant 0)
that owns the shared platform: gateways, upstream providers, the
license, platform health, and the tenant list. Only a user in Tenant 0
can hold a platform-scoped permission, so only Tenant 0 operators see the
Gateways, Providers, License, Platform Health, and Tenants screens. Every
other tenant is an ordinary customer boundary with its own users, teams,
keys, budgets, guardrails, traffic, and telemetry.
Every user belongs to exactly one tenant. The Add user form (Tenant 0
operators) has a tenant selector; the account, its data, and its traffic
all live in that tenant. The pending SSO approval dialog also assigns the
tenant: Cortega first tries to place the account by email domain (a
per-tenant list of SSO domains can be set when a tenant is created or
edited) and otherwise leaves it for the operator to choose. A per-tenant
`tenant_admin` manages only their own tenant's users and cannot change
anyone's tenant.
`administrator` carries platform permissions, so Cortega refuses to
assign it to a user outside Tenant 0. The check runs on Add user (before
the account is created), on approve, and on edit access. Give a
per-tenant administrator the `tenant_admin` role instead.
Tenant 0 operators see the current record's tenant in the top bar and in
list views, and can act across every tenant. Per-tenant users never see
another tenant's name or data.
Shared (Tenant 0 manages): gateways, upstream providers, provider
budgets; the license and edition features; the tenant list and
entitlements; platform health and platform settings; console-login SSO
and the signup email-domain allowlist; the rate tables cost catalog.
Per-tenant: teams, team budgets, LLM/MCP identities; guardrails, MCP
servers, MCP authorization; agentic applications, Cortega API keys;
Endpoint Guard devices/CAs, Cortega Agents config; per-tenant Endpoint
Guard SSO/enrollment domains; observability and Insights data.
---
# Identity guide
*How to configure caller identities for LLM and MCP traffic.*
## Overview
Cortega uses identities to decide who is calling, which team owns the
traffic, and which policies apply.
Pass-through LLM traffic is different: clients use their own upstream
provider credentials, so Cortega does not create a virtual-key identity
for those calls. Keyless pass-through LLM traffic falls to the Default
team. See [Pass-through routing](/docs/guides/pass-through-routing).
There are two common identity paths:
| Surface | What authenticates the caller | What Cortega uses it for |
| --- | --- | --- |
| LLM | Cortega-generated key, or another configured LLM auth provider | Team budgets, routing, guardrails, and observability |
| MCP | MCP auth provider plus identity matching | Team assignment, MCP server/tool authorization, guardrails, and observability |
## LLM key identities
Navigate to **Identities**.
Use a Cortega key identity when developers, apps, or agents need to call
the LLM gateway.
1. Create or select a Cortega key identity.
2. Assign it to a team.
3. Add optional metadata such as user, agent, service account, project, or
cost center.
4. Save the identity.
5. Give the raw `ck_...` key to the caller only once.
The raw key is shown once. After that, Cortega stores only a hash and safe
display metadata.
## MCP auth providers
Use MCP auth providers to tell Cortega how MCP callers prove who they are.
Supported methods:
| Method | Use when |
| --- | --- |
| MCP OAuth/JWT | MCP clients obtain bearer tokens from your IdP |
| Generic JWT | Callers already have a standard JWT bearer token |
| API key | You want a simple key-based MCP caller |
| Basic Auth | You need username/password-style MCP access |
| OIDC | Browser-oriented identity is needed |
For JWT-shaped methods, configure claim names for subject, role, and
tenant. The defaults are `sub`, `roles`, and `tenant`.
Required fields:
| Method | Required | Optional |
| --- | --- | --- |
| MCP OAuth/JWT | Name, MCP surface, issuer, JWKS URL, protected-resource URL, at least one claim-to-team rule | Audiences, scopes, provider kind, introspection |
| Generic JWT | Name, LLM and/or MCP surface, issuer, JWKS URL, at least one claim-to-team rule | Audiences, introspection |
**JWKS URL** (MCP OAuth/JWT and Generic JWT) must be a URL that already
serves a JWKS JSON document (`{"keys":[...]}`), typically
`https:///.well-known/jwks.json` or a Keycloak
`/protocol/openid-connect/certs` URL. Cortega fetches that URL when you
save. A homepage, 404, or HTML page is rejected, so Cortega is never
given a JWKS URL it cannot load.
**Generic JWT and API key identities can be enabled together** on the same
surface: Cortega accepts a validated JWT or a known key on the shared
`Authorization: Bearer` header. **MCP OAuth/JWT** (the OAuth discovery
flow) is the exception: it can't share the header with API keys, so
enabling it on MCP still requires disabling MCP key identities. Use
Generic JWT instead if you need both. On a multi-tenant install, MCP
OAuth/JWT is unavailable altogether; use Generic JWT.
Basic Auth may still combine with JWT (it uses the `Basic` scheme).
Cortega only accepts one Basic Auth policy per listener, so it allows at
most one Basic Auth identity on LLM and one on MCP; extra users belong in
username-to-team rows on that provider. While **MCP OAuth/JWT** is
enabled, the MCP Playground rejects Playground Key and pasted keys; paste
a JWT instead.
Two tenants can each configure their own Generic JWT identity. If they use
different IdP issuers it just works; if they share an issuer (both on
Google, say), each must set a distinct **Audience** so Cortega can tell
their tokens apart.
If the MCP Playground returns `JWT token required`, Cortega did not
accept a valid JWT. Paste the raw token, not `Bearer …`. The token `iss`
must match Issuer, `aud` must match Audiences (or the protected-resource
URL when Audiences is blank), and the token must verify against the JWKS
URL. Re-save the MCP OAuth/JWT identity or restart management-backend so
Cortega picks up audience defaults.
## MCP team resolution
MCP authorization is granted per Cortega team. MCP auth providers
authenticate the caller and expose a trusted team value, such as API key
metadata, a JWT/OIDC tenant claim, or a Basic Auth username-to-team
mapping stored on the auth provider. The MCP Authorization table then
grants that team access to servers and tools.
Example:
| Field | Value |
| --- | --- |
| API key metadata `team` | `Default` |
| JWT/OIDC `claim_teams` tenant=`Default` | team `Default` |
| Basic Auth `user_teams` username `alice` | team `Default` |
Each team should have at most one MCP Authorization row.
## Sorting and review
The Identities table is sorted alphabetically by name. Check:
1. Surface: LLM, MCP, or both.
2. Auth method.
3. Team.
4. Enabled state.
Disable identities that should not resolve traffic, rather than deleting
them immediately, if you want an audit-friendly rollback path.
## Troubleshooting
| Symptom | Likely cause | What to check |
| --- | --- | --- |
| LLM call is attributed to the wrong team | Key metadata or team assignment is wrong | Open the identity and verify its team |
| MCP call says no identity matches | The trusted team from the credential has no enabled MCP authorization | Check API key metadata, JWT/OIDC `claim_teams`, or Basic Auth username-to-team mapping, then MCP Authorization |
| JWT authenticates but LLM uses the Default router | Token verified, but no `claim_teams` row matched | Add claim=value to team on the Identities JWT/OIDC provider; do not rely on MCP Authorization grants |
| MCP call authenticates but cannot call a tool | Identity resolved, but MCP Authorization does not grant that server/tool | Open MCP Authorization |
| MCP Playground only sees the Default team's tools | The shared Playground MCP key is created on the Default team | Set that key's team (MCP > Identities, "[Playground] MCP Shared") to the team you want to test; the Playground keeps your choice from then on |
| Basic Auth identity does not match | Username/password authentication failed, or `user_teams` does not include that username | Confirm htpasswd and the username to team row on the Identities Basic Auth provider |
## Related guides
- [MCP servers guide](/docs/guides/mcp-servers)
- [MCP authorization guide](/docs/guides/mcp-authorization)
- [Pass-through routing](/docs/guides/pass-through-routing)
- [Guardrails guide](/docs/guides/guardrails)
---
# Guardrails guide
*How to configure LLM and MCP request/response guardrails.*
## Overview
Guardrails inspect traffic before it leaves Cortega or before it is
returned to the caller.
Use guardrails to:
- mask PII or secrets
- block unsafe prompts or responses
- call moderation or safety providers
- enforce different policies for models, keys, MCP servers, or MCP tools
## Guardrail types
| UI type | What it does |
| --- | --- |
| Regex | Built-in detectors (SSN, credit card, phone, email, CA SIN) plus your own patterns; masks or blocks on a match. No external call. |
| Presidio | Microsoft Presidio entity detection and anonymization, run by Cortega's Presidio service. Supports custom recognizers and the Log persistence scope (see below). |
| Webhook | Calls your own HTTP endpoint implementing Cortega's guardrail webhook contract. |
| OpenAI moderation | Calls the OpenAI moderations API. |
| Local model | Calls a locally hosted classifier model; no upstream credential. |
| Azure AI Content Safety | Calls Azure AI Content Safety. |
| Google Model Armor | Calls Google Model Armor. |
| Bedrock Guardrails | Applies an AWS Bedrock guardrail. |
The model-backed types (OpenAI moderation, Azure AI Content Safety, Google
Model Armor, Bedrock Guardrails) need a credential or an endpoint/region.
See [Provider credentials](#provider-credentials).
## Create a guardrail
Navigate to **Guardrails**. Use **Guided setup** for a walkthrough that
also proposes a starter set of guardrails, or **New Guardrail** to add one
directly:
1. Click **New Guardrail**.
2. Enter a name.
3. Choose phase: request or response.
4. Choose the guardrail type (see the table above).
5. Choose execution type.
6. Configure type-specific settings, and a credential for the model-backed
types.
7. Choose scope.
8. Save as draft or activate it.
Draft guardrails do not enforce. Active guardrails enforce after the
gateway receives updated config.
## Provider credentials
The model-backed guardrail types call an external service. The Guided
setup wizard has a credentials step that collects what each type you keep
needs:
- **OpenAI moderation**: choose Reuse OpenAI provider (Cortega uses the
stored, encrypted credential from an existing Models → Providers OpenAI
entry) or Use environment variable (Cortega reads a named env var,
pre-filled with the conventional name). Reuse avoids keeping a second
copy of the key.
- **Azure AI Content Safety**: the resource endpoint.
- **Bedrock Guardrails**: the guardrail ID, region, and version (`DRAFT`
or a published number). Cortega signs with its ambient AWS credentials.
- **Google Model Armor**: the project and location.
Cortega never returns a stored credential in an API response. A guardrail
whose credential can't be resolved does not enforce.
## Execution types
Guardrails run in this order:
```text
1. Sanitize
2. Parallel checks start
3. Ordered checks run while parallel checks are still running
4. Cortega allows only after ordered checks pass and the parallel expression passes
```
| UI term | Stored type | Use when |
| --- | --- | --- |
| Sanitize | `sanitize` | The guardrail may mask or transform content |
| Parallel checks | `async` | The guardrail only passes or blocks and can run concurrently |
| Ordered checks | `sync` | The guardrail must run in a specific order after sanitation |
Sanitize and ordered checks run in the order shown in their tables.
Parallel checks run concurrently.
## Async pass logic
Parallel checks use `AND` and `OR` join behavior.
- `AND` checks must all pass unless an `OR` check passes.
- An `OR` check can allow the parallel expression when it passes.
- If the expression is conclusively blocked, Cortega blocks the
request/response.
Use `AND` for mandatory checks. Use `OR` for alternative safety checks
where any passing check is acceptable.
## Scopes
Choose the narrowest scope that matches your intent.
| Scope | Applies to |
| --- | --- |
| All Models | LLM traffic for all models |
| Model | A specific direct LLM model (`provider:model_id` in the dropdown) or a managed team router (`cortega-team-…`) |
| Key | A specific LLM key identity |
| Log persistence | Presidio only. Redacts PHI in stored gateway telemetry (LLM/MCP query fields and Guardrail Log content attributes) before ClickHouse |
| MCP Server | Eligible MCP traffic for a server |
| Tool | Eligible MCP traffic for a tool |
Model scope matches the model name Cortega stamps after any team-router
rewrite. For a team with Model Authorization configured, choose that
team's router name in the Model dropdown so the guardrail covers the
team's traffic. Direct models still cover unrouted calls that name that
model. Hand-authored virtual models are not listed as Model choices; use
All Models or Key for that traffic.
Request/response Model (or All Models) scope controls what the provider
sees. **Log persistence** is a separate binding: without it, Guardrail Log
and traffic rows can still store the pre-mask text even when the wire
mask worked. Add Log persistence on a Presidio guardrail when
observability must not retain cleartext PHI.
## MCP guardrail coverage
MCP guardrails scan only methods that carry useful request/response
content:
- `tools/call`
- `resources/read`
- `prompts/list`
- `prompts/get`
- `roots/list`
- `resources/templates/list`
Other MCP protocol calls, such as `initialize` and notifications, are
logged in MCP Queries but are not content-scanned by guardrails.
## Presidio custom patterns
When you create or edit a Presidio guardrail, use **Custom detection
patterns** to teach Presidio identifiers its built-in detectors miss, for
example an internal patient number or a local licence format.
Each pattern needs:
| Field | Purpose |
| --- | --- |
| Name | Recognizer name stored on the guardrail |
| Entity type | Entity the match is reported as (for example `LOCATION` or `PERSON`) |
| Regex | Detection pattern |
| Score | Confidence for the match (typically `0.85`) |
| Context words | Optional nearby words that raise confidence |
Saving the guardrail sends these as `presidio_ad_hoc_recognizers`.
Clearing every custom pattern removes them from the guardrail.
When `LOCATION` is enabled, Cortega also applies built-in defaults for
US street lines and state/ZIP fragments. Those defaults do not appear in
the form; add custom patterns only for formats they do not cover. When
`MEDICAL_LICENSE` is enabled, a US state-prefixed medical licence default
is applied the same way.
## Runtime logs
Use **Observability → Guardrail Log** to see what guardrails did.
Important fields:
| Field | Meaning |
| --- | --- |
| Runtime scope | LLM Request, LLM Response, MCP Request, or MCP Response |
| Input text | Text inspected on request paths |
| Output text | Text inspected on response paths |
| Guardrail | Guardrail name |
| Type | Guardrail provider/type |
| Score / threshold | Provider score compared to configured threshold |
| Action | Pass, mask, block, or below threshold |
| Latency | Time spent in that guardrail evaluation |
LLM Queries and MCP Queries show applied guardrails in their security area
when the traffic row can be correlated with guardrail execution rows.
## Troubleshooting
| Symptom | Likely cause | What to check |
| --- | --- | --- |
| Guardrail does not fire | It is draft, disabled, wrong phase, or wrong scope | Check status, phase, and scope |
| Model-scoped guardrail misses a routed team | Scope is bound to a direct model, but the team router rewrote the request | Bind Model scope to that team's `cortega-team-…` router (or use All Models / Key) |
| Model scope does not apply to a hand-authored virtual model | Hand-authored virtual models are not Model-scope choices | Use All Models or Key |
| MCP request is not scanned | MCP method is outside the eligible method list | Check method in MCP Queries |
| MCP Guardrail Log row exists but MCP Query security is empty | MCP request correlation is not available yet | Use Guardrail Log directly |
| Output text appears without input text | Response guardrail row | Runtime scope should say LLM Response or MCP Response |
| Input text appears without output text | Request guardrail row | Runtime scope should say LLM Request or MCP Request |
## Related guides
- [Identity guide](/docs/guides/identity)
- [MCP servers guide](/docs/guides/mcp-servers)
- [MCP authorization guide](/docs/guides/mcp-authorization)
---
# MCP servers guide
*How to register upstream MCP servers and discover their tools.*
## Overview
MCP Servers are upstream Model Context Protocol servers that Cortega
exposes through the gateway. Registering a server tells Cortega where the
server is, how to authenticate to it, and whether it should be rendered
into gateway config.
MCP Servers do not assign caller teams. Teams come from Identities and MCP
Authorization.
## Add an MCP server
Navigate to **AI Border Gateway → MCP**.
1. Click **Add Server**.
2. Enter a server name.
3. Select the transport.
4. Enter the endpoint or command details.
5. Select upstream auth, if the upstream server requires it.
6. Save.
## Transport choices
| Transport | Use when |
| --- | --- |
| Streamable HTTP | The MCP server exposes the streamable HTTP transport |
| HTTP SSE | The MCP server uses Server-Sent Events |
| Stdio | You want to store a local command-based MCP server definition |
Enabled HTTP servers are rendered into gateway config. Stdio server
records are stored, but the current gateway target render path only
includes HTTP transports.
## Enable or disable a server
Use the **Enabled** toggle on the MCP Servers table.
| State | Result |
| --- | --- |
| Enabled | Rendered into gateway config if it uses an HTTP transport |
| Disabled | Removed from gateway config |
The legacy approval field is informational. Rendering is controlled by
**Enabled**.
## Upstream auth
Choose upstream auth based on how Cortega should authenticate when it
forwards calls to the server.
Common options:
| Auth type | Use when |
| --- | --- |
| None | The upstream server needs no auth |
| API key | Cortega should attach a stored key to upstream calls |
| Client-supplied upstream credential | The client sends its own credential for this server in a request header; Cortega never stores it |
| Copilot | The upstream is GitHub Copilot MCP |
| GCP / AWS / Azure implicit | The gateway environment supplies cloud identity |
API keys are encrypted at rest and rendered as secret references.
Choose **Client-supplied upstream credential** when the client brings its
own credential for the upstream server. The client still authenticates to
Cortega with an MCP identity; it sends the server credential in the
upstream-credential header, and Cortega forwards that value as the
upstream `Authorization` and strips the header before the call. See
[Pass-through routing](/docs/guides/pass-through-routing) for the safety
rules and the stored-credential override.
## Discover tools
Tool discovery reads the upstream server's current tool list and stores it
in Cortega.
Use discovery when:
- you first register a server
- an upstream server adds or removes tools
- MCP Authorization needs current tool checkboxes
You can discover tools for one server, or use **Get All Tools** where
available.
Discovery updates existing tools and removes tools that no longer exist on
that server. Existing MCP Authorization selections are preserved when the
same tool remains present.
## SSE servers
For HTTP SSE servers, Cortega initializes the SSE connection first and
posts JSON-RPC messages to the server-provided message endpoint. Directly
posting `initialize` to an SSE URL can return `404`.
## Troubleshooting
| Symptom | Likely cause | What to check |
| --- | --- | --- |
| Server does not appear in gateway config | Disabled, non-HTTP transport, or global MCP toggle off | Check server Enabled state and transport |
| Tool discovery returns 404 | SSE endpoint was treated as direct POST endpoint | Confirm server transport is HTTP SSE |
| No tools appear under MCP Authorization | Tools have not been discovered yet | Run discovery for the server |
| Upstream call fails auth | Wrong upstream auth type or missing credential | Edit server upstream auth settings |
## Related guides
- [Identity guide](/docs/guides/identity)
- [Pass-through routing](/docs/guides/pass-through-routing)
- [MCP authorization guide](/docs/guides/mcp-authorization)
- [Guardrails guide](/docs/guides/guardrails)
---
# MCP authorization guide
*How to grant teams access to MCP servers and tools.*
## Overview
MCP Authorization decides what an authenticated MCP caller may see and
execute.
The flow is:
```text
MCP caller authenticates
-> gateway auth resolves a team
-> MCP Authorization grants servers/tools to that team
-> allowed calls continue; disallowed calls are blocked
```
## Before you start
Make sure you have:
1. At least one MCP auth provider on **Identities**.
2. A trusted team value from the MCP credential, such as API key metadata
or a JWT/OIDC tenant claim.
3. At least one enabled MCP server.
4. Discovered tools for that MCP server.
## Create an authorization rule
Navigate to **MCP Authorization**.
1. Click **New Authorization**.
2. Select the team this rule applies to.
3. Select the MCP servers the team can reach.
4. Expand each server to review its tools.
5. Check or uncheck individual tools.
6. Save.
Each team can have only one MCP authorization row. Creating a second row
for the same team is refused (HTTP 409). Change grants by editing the
existing row; that replace is the update path, not create.
## Server and tool checkbox behavior
Server checkboxes are hierarchical:
| Action | Result |
| --- | --- |
| Check a server | Selects all currently discovered tools under that server |
| Uncheck a server | Unselects all tools under that server |
| Check one tool | Grants only that tool, unless other tools are already checked |
| Re-discover tools | Preserves selections for tools that still exist |
## Related guides
- [Identity guide](/docs/guides/identity)
- [MCP servers guide](/docs/guides/mcp-servers)
- [Guardrails guide](/docs/guides/guardrails)
---
# Bring-your-own upstream credential
*How to let clients use their own upstream provider or MCP-server
credentials while Cortega still governs the traffic, without Cortega
storing those credentials.*
## Overview
Some teams already have provider API keys or MCP server credentials in
their own clients and don't want to hand those to Cortega. Cortega
supports that on both surfaces, and they work the same way:
| Surface | How a client authenticates to Cortega | How the upstream credential travels |
| --- | --- | --- |
| **LLM** | A normal Cortega identity (LLM key or JWT), required. | A separate request header (`X-Cortega-Upstream-Authorization` by default). Cortega rewrites it to the provider-native header and strips it before the upstream call. |
| **MCP** | A normal Cortega identity (MCP key or JWT), required. | The same header. Cortega forwards its value as the upstream `Authorization` for a client-supplied-credential MCP server and strips the header before the call. |
In both cases Cortega still applies gateway policy, guardrails,
observability, and the confused-deputy safety check below. It never
stores the client's upstream credential.
Neither surface has a keyless mode. Every caller authenticates with a
Cortega identity, so its traffic is attributed to a team and a tenant like
any other. Only the *upstream credential* is supplied by the client, in a
header.
## LLM: client-supplied upstream credential
### 1. Configure the provider
Navigate to **Models → Providers → Add provider** (or use **Guided
setup**).
1. Choose the provider type (OpenAI, Anthropic, Gemini, DeepSeek, Groq,
OpenRouter, or a custom OpenAI-compatible endpoint).
2. Set **Credential source** to **Client-supplied upstream credential**.
3. Set the endpoint or a base URL override if needed.
4. Save.
Bedrock, Vertex, Azure, and Copilot are **not** supported for
client-supplied credentials; they need SigV4 / OAuth signing that a raw
per-request key can't satisfy.
### 2. Register the models
Navigate to **Models → Models** and add a concrete model for every model
name clients will request (`gpt-4o`, `claude-sonnet-4-6`, and so on).
There is no wildcard model; register the specific names. Two enabled
models may not share a routing name, even across providers.
### 3. Decide how clients reach the model
- **Direct model selection on** (Model Authorization tab): a client's LLM
key can request any registered model by name.
- **Direct model selection off** (default): the identity's team needs a
model authorization (routing preference) that includes the model.
The **Guided setup** wizard walks through provider, model, identity, and
model authorization in one flow.
### 4. Calling the gateway
The client sends **two** headers: its Cortega identity in `Authorization`,
and its own provider key in the upstream-credential header.
```bash
curl "$CORTEGA_LLM_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer $CORTEGA_LLM_KEY" \
-H "X-Cortega-Upstream-Authorization: $OPENAI_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]}'
```
Cortega rewrites `X-Cortega-Upstream-Authorization` to what the provider
expects (`Authorization: Bearer …` for OpenAI-compatible providers,
`x-api-key` plus `anthropic-version` for Anthropic) and removes it before
the upstream call.
If a request routes to a client-supplied-credential provider and the
header is missing, Cortega fails closed with a 403
(`upstream_credential_required`). The request never reaches the provider.
### Changing the header name
**Model Authorization → Upstream credential header.** Any valid HTTP
header name except the provider-native ones (`Authorization`,
`x-api-key`, `x-goog-api-key`, `anthropic-version`) and the `x-cortega-*`
namespace.
## MCP: client-supplied upstream credential
1. Add or edit an MCP server (**MCP → Add Server**) and set **Upstream
Auth** to **Client-supplied upstream credential**.
2. Issue an MCP identity for the client as usual (**Identities**), and
grant it the server and tools it needs (**MCP Authorization**).
The client authenticates to the MCP listener with its Cortega identity and
sends its own MCP-server credential in the upstream-credential header
(same setting as LLM). Cortega forwards that value as the upstream
`Authorization` verbatim (the client controls whether it is `Bearer …` or
a raw token) and strips the header before the call.
If a request routes to a client-supplied-credential MCP server and the
header is missing, Cortega denies it. The request never reaches the
server.
A request that carries the upstream-credential header may only reach a
pass-through-safe MCP server:
- servers with **Upstream Auth = Client-supplied upstream credential**
- stored-credential servers where an administrator has explicitly allowed
credential substitution (see below)
For a server with **Upstream Auth = None**, Cortega strips both the
caller's `Authorization` and the upstream-credential header before the
call.
## The confused-deputy guard and the substitution override
Cortega protects against a confused-deputy mistake: a caller must not be
able to present its own credential (LLM) or an unvalidated one (MCP) and
then have Cortega silently use its *stored* provider/MCP credential
instead.
- **LLM**: a request that carried `X-Cortega-Upstream-Authorization` may
only reach a client-supplied-credential provider. If it routes to a
stored-key provider, Cortega denies it 403 unless the override below is
on. The header is stripped before dispatch either way.
- **MCP**: a pass-through caller may only reach a pass-through-safe
server.
**The override.** When editing a stored-credential provider or MCP server
you may see "Allow a request that carried its own upstream credential to
use this provider's stored credential instead." Leave it off unless you
deliberately want that. Turning it on is a privilege escalation.
## Security key management
| Key type | Where it lives | Who manages it |
| --- | --- | --- |
| Provider key for a client-supplied-credential LLM provider | Client / agent environment | The client owner |
| MCP credential for pass-through MCP traffic | MCP client environment | The MCP client owner |
| Cortega LLM key / JWT | Client environment | Cortega admin issues it; it is the enforcement identity |
| Stored provider or MCP server credential | Cortega or gateway runtime | Cortega administrator |
Operational guidance:
- Rotate client-owned provider keys outside Cortega.
- Do not paste a client-supplied provider key into a Cortega provider
form.
- Review stored-credential providers and MCP servers before enabling the
substitution override.
## What to verify
1. An LLM call with both headers succeeds and appears in **Observability**
under the right team and model.
2. The same call **without** `X-Cortega-Upstream-Authorization` fails
closed (403).
3. Guardrails still apply.
4. A request carrying the upstream header cannot reach a stored-key
provider unless the override is enabled.
5. The upstream provider sees the client's key, not a Cortega-stored one.
## Troubleshooting
| Symptom | Likely cause | What to check |
| --- | --- | --- |
| 403 `upstream_credential_required` | The routed model's provider is client-supplied-credential and the request carried no upstream header | Confirm the client sends the upstream-credential header on every request; check the header name on **Model Authorization** |
| 403 `credential_substitution_forbidden` | A request carrying the upstream header routed to a stored-key provider | Route to a client-supplied-credential provider, or deliberately enable the substitution override |
| Upstream provider rejects the request as unauthorized | The client's own provider key is wrong or the header value is malformed | The value is the raw key; Cortega adds the `Bearer ` prefix / `x-api-key` shaping |
| "Model not found" | The requested model isn't registered | Add the concrete model under **Models → Models** |
| MCP caller is denied "no MCP identity matches" | The caller has no matched Cortega MCP identity | Issue an MCP identity and match attributes; there is no keyless MCP mode |
| MCP caller is denied "requires an upstream credential" / "may not use Cortega's stored credential" | Missing upstream header for a client-supplied-credential server, or the header was sent toward a stored-key server | Send the upstream-credential header; only route header-carrying requests to pass-through-safe servers |
## Related guides
- [MCP servers guide](/docs/guides/mcp-servers)
- [Identity guide](/docs/guides/identity)
- [Guardrails guide](/docs/guides/guardrails)
---
# Client identification guide
Cortega records which application made each governed request so operators
can answer "which system called this?" without minting a virtual key per
app.
## What appears in Observability
On **Observability → LLM Queries** (and the other traffic tables), the
first column is **Agent Stack**, above **Timestamp Source**.
Agent Stack is composed from request headers Cortega captures on every
call:
| Source | Header | Role |
| --- | --- | --- |
| Application name (recommended) | `X-Cortega-Application` | Stable name you choose for the workload |
| HTTP client identity | `User-Agent` | What the client library or tool already sends |
| OpenAI / Stainless SDK metadata | `X-Stainless-Lang`, `X-Stainless-Package-Version`, `X-Stainless-Runtime`, `X-Stainless-Runtime-Version`, `X-Stainless-OS`, `X-Stainless-Arch`, `X-Stainless-Async` | Language, runtime, OS, and SDK version |
| Anthropic API pin | `anthropic-version` | Anthropic SDK API version when present |
Example Agent Stack values:
- `billing-reconciler · pydantic-ai/2.25.0 · python CPython · Windows · sdk 2.53.0`
- `cortega-console/model-playground · cortega-console/model-playground`
- `curl/8.7.1` (no application header set)
Gateway config must have been published after this capture was added;
older gateways only start recording these fields after their next config
reload.
## Set X-Cortega-Application from your app
Send a short, stable name for the workload on every request to the
gateway:
```http
POST /v1/chat/completions HTTP/1.1
Host: gateway.example.com
Authorization: Bearer
X-Cortega-Application: billing-reconciler
User-Agent: my-service/1.4.0
Content-Type: application/json
```
Python (`openai` SDK):
```python
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.example.com/v1",
api_key="",
default_headers={
"X-Cortega-Application": "billing-reconciler",
},
)
```
Naming tips:
- Prefer a durable workload name (`claims-intake`, `nightly-summarizer`),
not a host or pod name that changes every deploy.
- Keep it under a few dozen characters; avoid secrets or PII.
- One shared virtual key can still separate traffic when each caller sets
a distinct application name.
## What the Cortega Console sends
Console-originated gateway calls set both `User-Agent` and
`X-Cortega-Application` so playground and diagnostic traffic is obvious
next to customer apps:
| Surface | Value |
| --- | --- |
| Model Playground | `cortega-console/model-playground` |
| MCP Playground | `cortega-console/mcp-playground` |
| Provider diagnostics | `cortega-console/provider-diagnostics` |
| LLM benchmarks | `cortega-console/llm-benchmark` |
| AI Verifier | `cortega-console/edge-verifier` |
You do not need to configure these; the management backend adds them when
it originates the governed call.
## Related guides
- [Pass-through routing](/docs/guides/pass-through-routing): credential
modes are separate from client identification.
---
# Endpoint Guard deployment guide
*How to try Cortega Endpoint Guard on one machine, then enroll licensed
devices with MDM or administrator-provided certificates.*
The product is Cortega Endpoint Guard (the headless agent) and Cortega
AI Verifier (the same agent plus a native desktop app). This guide calls
the running software "the agent" and the product "Endpoint Guard."
## Quick reference
The Endpoint Guard agent is a native agent that captures AI traffic from
desktop apps, browsers, and local MCP tools, the traffic Cortega's
gateway never sees because it isn't pointed at the gateway. It installs
as a system-level service (macOS: a LaunchDaemon; Windows: an SCM
service) and runs before login, with no per-user setup, available for
macOS and Windows.
System requirements:
- macOS: 11.0 Big Sur or later. One universal package installs on both
Apple Silicon and Intel Macs. Admin/root access is required to install.
- Windows: a current, supported Windows 10/11 release. Administrator
access is required to install.
Packages:
```text
cortega-endpoint-guard-.pkg # macOS, agent only
cortega-endpoint-guard--windows.zip # Windows, agent only
cortega-ai-verifier-.pkg # macOS, agent + AI Verifier app
cortega-ai-verifier--windows.zip # Windows, agent + AI Verifier app
```
Pick the endpoint-guard package for headless fleet deployment, and the
ai-verifier package when users need the desktop app. A machine runs one
or the other, never both. See [Install](/docs/install) for where to get
these packages.
Before testing any mode, restart AI apps such as Claude Desktop, ChatGPT,
and other agent clients so existing provider connections close and
reconnect through Endpoint Guard.
## Deployment modes
Endpoint Guard supports a local trial mode and licensed enrollment
modes. The trial mode never talks to Cortega. New licensed deployments
should prove device identity with a per-device client certificate; a
shared enrollment key remains available as a test-only path.
| Mode | Who uses it | Identity proof | Security | Manageability |
| --- | --- | --- | --- | --- |
| MDM rollout | Enterprise fleet deployment | MDM-issued per-device client cert | Highest; unique device cert, MDM lifecycle, optional non-exportable key | Best for fleets; MDM owns install, cert, config, removal |
| Self rollout | Admin-managed pilots | Cortega-generated per-device client cert | High; unique cert per device, no shared secret | Good for pilots; secure distribution required |
| Shared key-based activation | Internal installs/testing | Shared enrollment key | Lowest | Simple and familiar |
Recommended default: use MDM rollout or self rollout without MDM, and use
key-based activation only as a test path while certificate enrollment is
adopted.
The modes above cover the headless Endpoint Guard service. The AI
Verifier desktop app enrolls differently: it signs the user in through
SSO or an invitation link, and an unknown user is routed to a Cortega
admin for approval rather than being auto-provisioned.
## Certificate model
Licensed Endpoint Guard enrollment uses one trusted enrollment authority
and one client certificate per device. Do not share one client
certificate across machines; a shared cert would behave like a shared
enrollment key.
The client certificate identifies the device and the assigned user. The
Cortega URL is part of configuration, and it must be the public
Endpoint-Guard-facing HTTPS origin (the nginx, load balancer, or app URL
the device can reach). The Endpoint Guard → Enrollment screen prefills
this from the browser origin. Since the certificate includes the user
email, the activation command does not need a separate email argument.
## Administrator setup: TLS, nginx, and client-cert headers
Certificate enrollment needs a TLS terminator that can see the agent's
client certificate. Cortega then verifies that cert against the trusted
enrollment CAs and mints a short-lived token.
There are two supported topologies:
- **Direct HTTPS to management-backend.** Use this only for a lab or a
dedicated listener. The backend requests a client certificate on the
TLS handshake and verifies it against trusted enrollment CAs directly.
Do not publish this port to the internet if the public console already
sits on another origin.
- **TLS-terminating proxy or load balancer (normal production path).**
The public console and the agent share one HTTPS origin. The proxy
terminates TLS, optionally requests a client certificate, and forwards
the verified leaf cert in one HTTP header. management-backend never
sees the TLS client cert directly.
For the proxy topology, four properties matter: the proxy must overwrite
the identity header (clearing any client-supplied value before setting it
from the TLS handshake, otherwise a caller could paste a stolen
certificate and impersonate that device); management-backend and
webapp-backend must not be reachable from the internet directly, only the
TLS terminator; client certs must be optional at the TLS layer, since
browsers loading the console have no client cert, though Cortega still
rejects certificate-mode calls that arrive without a valid one; and the
enrollment CA must be exported to the terminator and kept in sync with
what's uploaded in Endpoint Guard → Enrollment.
Supported terminators, and what to send Cortega:
| Terminator | What to send Cortega |
| --- | --- |
| nginx | The URL-encoded PEM of the client cert, forwarded in a custom header |
| AWS ALB passthrough | `X-Amzn-Mtls-Clientcert` (built-in, URL-encoded PEM) |
| GCP HTTPS LB | Needs a custom header with URL-encoded PEM; its built-in header format isn't one Cortega parses. Put nginx behind the GCP LB, or configure a matching custom header. |
| Azure Application Gateway | Rewrite the client-certificate variable (PEM) into the configured header; URL-encode it if the rewrite leaves raw newlines |
Always configure the exact header name the terminator sends.
Security notes for certificate mode: one client cert per device, since a
shared fleet cert is the shared enrollment key with extra steps; trusting
the forwarded header trusts that header, not possession of the private
key, so the terminator must have already proven possession during the
TLS handshake; and rotating or disabling a CA from Endpoint Guard →
Enrollment must be matched by updating the terminator's trusted CA file,
since Cortega rejecting a cert does not by itself stop the terminator
from accepting the handshake.
## 1. Local trial without Cortega
Use this when an admin wants to download the package and try Endpoint
Guard on one machine without a Cortega backend.
Install the package for your platform. It installs and starts the system
service with no Cortega URL and no enrollment identity, and captures
locally against a built-in list of common AI domains such as ChatGPT,
Claude, Gemini, Copilot, DeepSeek, and Kimi.
Open `http://127.0.0.1:7878` and generate traffic to an AI site. You
should see local captures on the diagnostic page. The table shows only
Time and App columns until the agent is registered with Cortega, since
nothing is sent to Cortega while no backend is configured.
Trial behavior: works for 15 minutes per service start. After 15 minutes
without Cortega connectivity, Endpoint Guard enters passthrough mode: no
interception, no capture, no guardrails, no budget checks, the same
behavior a real network outage produces. Restarting the service starts a
new 15-minute local trial window. This mode is not licensed, not
enrolled, and not connected to a Cortega backend.
## 2. MDM rollout with MDM-issued certificates
Use this for production fleet rollout with Jamf, Kandji, Intune, Mosyle,
or a similar MDM.
Admin workflow in Cortega: open Endpoint Guard → Enrollment, choose
MDM-issued certificates, upload the MDM/SCEP/ACME issuing CA certificate
or select an existing trusted enrollment CA, download the CA PEM and
install it as the client CA on the TLS terminator, configure the
expected certificate identity fields (tenant ID, device ID, user email,
serial number, or MDM device ID), and copy the public HTTPS Cortega URL
for the deployment.
MDM workflow: deploy the endpoint-guard package, deploy a per-device
client certificate through SCEP, ACME, or an MDM certificate payload
(non-exportable private key when the MDM supports it), and deploy a
configuration profile or file with the Cortega URL and the client
certificate/key paths. Start or restart the service.
Expected device behavior: the agent finds the installed client
certificate, registers with Cortega using mutual TLS or an equivalent
certificate-backed request, and Cortega verifies the cert chains to a
trusted enrollment CA, is not expired, has Client Authentication usage,
and maps to an allowed tenant/device identity. Cortega then creates or
updates the device record, mints a short-lived token, and returns
runtime policy. The device appears in Endpoint Guard → Devices.
MDM installs must be noninteractive; MDM supplies the certificate and
config separately rather than relying on package prompts.
## 3. Self rollout with Cortega-generated certificates
Use this for pilots, small fleets, or customers without MDM. Cortega acts
as the enrollment CA and generates unique per-device client
certificates.
Admin workflow in Cortega: open Endpoint Guard → Enrollment, choose
Cortega-generated certificates, create or select the Cortega enrollment
CA and install its downloaded PEM on the TLS terminator if not already
done, generate one client certificate per device or user/device
assignment, leaving Cortega URL as the public HTTPS origin the device
will call, choose a finite certificate lifetime (usually 90 days to 1
year for pilots, up to 3 years for managed fleets with a rotation
process), download the certificate/key or full identity bundle, and send
the package, identity material, and Cortega URL to the target user
through a secure channel.
User/admin install workflow: install the package, then install the
per-device identity using the platform's import-identity helper with the
Cortega URL and either the separate certificate/key files or the full
identity bundle. The helper copies the certificate/private key into the
Cortega identity directory, writes the Cortega URL and PEM paths, clears
any shared enrollment key, and restarts the service. The device then
registers with Cortega and appears in Endpoint Guard → Devices.
Certificate import runs as an explicit, elevated/root-run helper for
manual/self rollout; package install scripts cannot safely prompt during
MDM installs, which is why MDM deployment uses mode 2 instead.
## 4. Key-based activation
Use this for existing deployments that already rely on the shared
enrollment key. This is a compatibility path, less secure than
certificate enrollment because the same secret can be reused across many
devices.
Admin workflow in Cortega: configure the enrollment key on the Cortega
backend, share the Cortega URL and enrollment key only through an
approved secret channel, and rotate the key if it's exposed or if a
deployment cohort should no longer be able to enroll.
Device workflow: run the platform's activation script with the Cortega
URL, enrollment key, and user email. The script writes the Cortega URL,
agent key, and email into the local Endpoint Guard config (clearing any
leftover client-cert identity from a prior certificate enrollment) and
restarts the service. On startup, the agent registers with Cortega by
presenting the shared key plus the claimed email; Cortega compares the
key to its configured enrollment key, validates the email/domain,
records the device, and returns a short-lived token plus runtime policy.
Security notes: the key proves access to the enrollment secret, not
possession of a specific managed device; any holder of the shared key
can attempt to register a device and claim an allowed email; the key is
stored in the device's Endpoint Guard config and must be protected as a
secret; prefer per-device certificate enrollment for new production
deployments.
## Verify
For local trial: restart AI apps, browse to an AI site such as
`chatgpt.com` or `claude.ai`, open `http://127.0.0.1:7878`, and confirm
local captures appear (and that nothing appears in Cortega, since the
device is not enrolled).
For licensed enrollment: confirm the device appears in Endpoint Guard →
Devices, confirm `http://127.0.0.1:7878` shows the device as registered,
restart AI apps, generate AI traffic, and confirm Endpoint Guard →
Observability shows captured LLM or MCP activity.
### Managing devices
Endpoint Guard → Devices lists enrolled devices. The Identity column
shows how Cortega last verified the device: Enrollment key (shared
enrollment secret), Client certificate · `{CA name}` (mTLS or forwarded
client cert chained to that trusted enrollment CA), or Unknown
(registered before identity was recorded; the next successful register
updates it).
Serial is the hardware serial the agent reads from the device.
Certificate enrollment uses the cert's device identity as Device ID. The
Devices table's Device column and the drawer title are the OS hostname,
which is not the Device ID.
Intercept CA is separate: it is whether the device trusts Cortega's local
TLS inspection certificate, not the enrollment CA.
Active Clients lists AI apps currently running on the device (ChatGPT,
Claude Desktop, Cursor, and similar). The agent reports this on register
and on each config poll.
Delete a device to free a license seat. The device must re-enroll to
appear again.
### Other Endpoint Guard screens
| Screen | What it does |
| --- | --- |
| Endpoint Guard → Apps | Allow/deny rules for AI domains. A rule can cover all Endpoint Guard AI domains or one exact domain, and can turn request/response content capture off for that domain. Cortega returns the resolved rules in each device's runtime config; the agent blocks any domain whose action resolves to deny. |
| Endpoint Guard → Guardrails | Guardrails scoped to Endpoint Guard traffic, the same guardrail types as AI Border Gateway (see the [Guardrails guide](/docs/guides/guardrails)), applied to what the agent captures. |
| Endpoint Guard → Observability | The Endpoint Guard LLM/MCP query tables, every captured exchange, in the same telemetry pipeline as gateway traffic. |
### Device notifications from Cortega Agents
If the Cortega Agents product is licensed and the Legal Agent (AI
Verifier) is enabled, a false or unverified verdict on an Endpoint
Guard-captured response is pushed back to the originating device on its
next config poll and shown as a native OS notification. Delivery is
best-effort and at-most-once; there is no acknowledgement. Gateway
traffic (no device) never triggers this.
## Uninstall
Uninstalling stops the service, removes Endpoint Guard files, removes the
trusted local interception certificate, and reverts system proxy
settings the agent changed.
For certificate-based licensed installs, uninstall should not
automatically delete an MDM-issued identity certificate unless Cortega
installed it during self rollout. MDM-owned certificates should be
removed by MDM.
## Troubleshooting
| Symptom | Likely cause |
| --- | --- |
| Diagnostic page shows no traffic | Restart the AI app and confirm the domain is in the Endpoint Guard app policy. |
| Trial stops capturing after 15 minutes | Expected local-trial timeout; restart the service for another local trial window. |
| Device never appears in Cortega | Missing Cortega URL, missing client certificate, untrusted CA, expired cert, or certificate identity mismatch. |
| Certificate import fails | User lacks root/admin access, the PEM files are missing or malformed, or the cert lacks Client Authentication usage. |
| Sign in with SSO returns "account pending" / a "request submitted" screen | Working as intended: the email's domain isn't on any tenant's SSO-enrollment list and there's no invitation, so the request went to Users & Access → Pending Approval for a Cortega admin. Add the domain to the tenant, issue an invitation link, or provision the user from the pending row. |
| Sign in with SSO returns "seats full" | The tenant's AI Verifier seat count is exhausted. Raise the seat count on the tenant or remove an inactive device. |
| SSO tries to reach the public Cortega domain instead of your instance | The Cortega URL field was left blank; it defaults to the public instance. Type your full instance URL. |
| Client certificate is required, through the proxy | The proxy isn't configured to trust client certificates, isn't setting the expected header, or a component in front of Cortega isn't forwarding it. |
| Invalid client certificate | The proxy forwarded a cert that does not chain to a trusted enrollment CA, is expired, or lacks Client Authentication. Download the CA PEM again and confirm it matches the proxy's trusted CA configuration. |
| Agent fails TLS to a local test URL | The OS trust store doesn't trust the local test CA; the agent uses system roots, not a custom CA file. |
| Browser console breaks after enabling mTLS | The terminator required a client cert instead of making it optional. Browsers connect without a cert and need that to succeed. |
| Registered locally, but no Endpoint Guard Observability rows | Check network access from the device to the Cortega gateway/observability URL and widen the time selector. |
| MDM install hangs waiting for input | A package prompt was used in MDM mode; move cert/config delivery into MDM payloads and keep install noninteractive. |
| Device never appears in Cortega's Devices page (key-based) | Re-run the activation script and check its output for errors; confirm the agent key matches what's configured on your Cortega instance. |
| (Windows) Install/activate fails with an access-denied error | The install/activate/import-identity/uninstall scripts all need an elevated (Administrator) PowerShell session. |