# 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 Agentic & back-office AI agents, apps Desktop & personal devices CORTEGA PLATFORM AI BORDER GATEWAY Routing, cost, automatic failover Guardrails, identity, MCP tool governance One observability view, every call ENDPOINT GUARD Local interception, on the device Local guardrails: observe, mask, or reject Sees traffic your gateway never does GOVERNED, LOGGED, AND REPORTED: EVERY CALL, EVERY DEVICE CORTEGA AGENTS Read traffic from either box above, or both AI Verifier: hallucination and citation checking Workload Analyzer, Scorer, Aegis, and others 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 by AI 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 by Endpoint 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by AI 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 by Model 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.

Download

Endpoint Guard (macOS)

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.

Download

AI Verifier (macOS)

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.

Download

Hosted

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.

Sign Up

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