Access lists are a per-project (or per-user) firewall that runs before the policy engine. They’re the right tool for “I know I never want to hear from this source again” — block in O(1), no ML inference, no upstream cost.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.
Targets
Each rule blocks or allows a single value of one of these target types:| Target type | Matches against | Example value |
|---|---|---|
ip | Exact source IP of the inbound request | 203.0.113.10 |
ip_cidr | Source IP inside a CIDR block | 203.0.113.0/24 |
end_user | The X-End-User header on the inbound request | customer-42 |
country | ISO-3166 alpha-2 code, looked up via the cached GeoIP table | RU |
Semantics
The decision logic is intentionally boring and predictable:- Block always wins. If any active block rule matches the request, reject with
403 access_list_block. Done. - Non-empty allow list flips to default-deny. If the project (or user) has any active allow rule, the request must match at least one allow rule to proceed. Otherwise reject.
- Otherwise, allow. No rules and no allow list = no opinion = let the policy engine decide.
Scope: project vs. user
Each rule lives at one of two scopes:- Project-scoped (
project_idset) — the tightest scope. Use when one project needs different access rules from the rest of your account. - User-scoped (
project_idisNULL) — applies to every project you own. Convenient default for “block this abusive user across all my apps”.
check_access evaluates both scopes in the same query, so a user-wide block plus a project-scoped allow behave exactly the way you’d expect: the block fires.
Recipes
Block a specific abusive end-user across all projects
Block a specific abusive end-user across all projects
project_id → user-wide. The next call from this user, on any project, returns 403.Lock one project to a single allowed CIDR
Lock one project to a single allowed CIDR
10.0.0.0/8 is rejected.Country-block with an expiry
Country-block with an expiry
expires_at lets the rule auto-deactivate without a follow-up DELETE.What gets denied
A blocked request returns403 with this body:
rule_id is the access-list rule that fired, so your client (or your support team) can immediately point at the row in the dashboard.