> ## Documentation Index
> Fetch the complete documentation index at: https://docs.promptguard.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Gateway Overview

> How PromptGuard sits in front of your LLM provider and what it does on every request

PromptGuard is a smart gateway between your application and your LLM provider. Every request flows through five stages, in this order:

```mermaid theme={"system"}
flowchart TD
    App(["Your app"]) --> Auth{"1 · Authenticate<br/>X-API-Key"}
    Auth -->|"invalid / revoked"| E401["401 Unauthorized"]
    Auth -->|valid| ACL{"2 · Access list<br/>IP · end-user · country"}
    ACL -->|"block rule matches"| E403["403 Blocked"]
    ACL -->|allowed| Route["3 · Routing rules<br/>rewrite provider / model"]
    Route --> Cred["4 · Resolve provider key<br/>inject upstream Authorization"]
    Cred --> Policy{"5 · Policy engine<br/>injection · PII · jailbreak · exfil"}
    Policy -->|block| Blk["Block"]
    Policy -->|redact| Red["Redact, then forward"]
    Policy -->|allow| Up(["LLM provider"])
    Red --> Up
    Up -->|"5xx & failover set"| FO["Retry once:<br/>failover provider"]
    Policy -.->|"decision · tokens · cost"| Log[("security_events")]
```

<Steps>
  <Step title="Authenticate the call">
    Your `X-API-Key` is verified against the project that issued it. Invalid or revoked keys return `401` immediately.
  </Step>

  <Step title="Check the access list">
    The request's source IP, end-user ID, and (if cached) country are matched against your project's [Allow & Block lists](/gateway/access-lists). Block rules always win. A non-empty allow list flips the project to default-deny.
  </Step>

  <Step title="Apply routing rules">
    [Routing rules](/gateway/routing-rules) can rewrite the upstream provider/model based on the request shape — e.g. downgrade short prompts to a cheaper model, or pin a specific tenant to a specific vendor.
  </Step>

  <Step title="Resolve the upstream credential">
    If you've stored a [Provider Key](/gateway/provider-keys), PromptGuard injects it as the upstream `Authorization` header so your app code never has to ship vendor credentials. The original `Authorization` header on the inbound request is replaced.
  </Step>

  <Step title="Run the policy engine">
    The prompt is evaluated against your [security policies](/security/overview) (prompt injection, PII, jailbreaks, exfiltration, custom rules). Decisions: `allow`, `block`, or `redact`.
  </Step>
</Steps>

Every decision is persisted to `security_events` with the source IP, end-user ID, country (looked up lazily from the cached GeoIP table), tokens in/out, and an estimated dollar cost — so the dashboard can show you per-end-user, per-country, and per-project rollups without a separate logging pipeline.

## Why this shape

Most "AI security" products only do step 5 — the policy engine. PromptGuard owns the full gateway because the access decisions you actually care about live in the cross-product of all five stages:

* "Block this user across every project I own" — solved by user-wide access lists (step 2).
* "Don't ship vendor secrets to my front-end" — solved by Provider Keys (step 4).
* "Downgrade summarisation calls to Haiku, keep code generation on Opus" — solved by Routing Rules (step 3).
* "Why is this end-user costing me \$40/day?" — solved by per-end-user attribution (logged after step 5).

Each of the next four pages covers one of those primitives end-to-end.

## Failover

If a Routing Rule specifies a `failover_provider` and the primary upstream returns 5xx, PromptGuard retries exactly once against the failover. Non-5xx responses (rate limits, validation errors) are surfaced to the caller as-is — you don't want a "smart" gateway turning a 400 into a 200 by silently switching vendors.

## Latency budget

The policy-engine stage is the only one that can do meaningful work. The other four stages are designed to be near-zero:

* Auth: cached for the lifetime of the request.
* Access list: a single indexed query (`user_id, project_id`).
* Routing rules: in-Python evaluation against the rules cached for the project.
* Provider key: a single indexed lookup, decryption is a single Fernet call.

In typical traffic the four gateway stages add \< 5 ms; the policy engine is the dominant cost. See the [latency breakdown](/platform/dashboard) on the Overview tile for live numbers from your account.
