Guardrails
A guardrail is a rule the gateway applies to every request of what it is assigned to, before any model runs. It has an id (grd_...), a name, one of three types, its settings, its assignees and a state, on or off: one that is off applies to no request and keeps its settings and assignees. Guardrails are made, changed and assigned in the Console's Guardrails; there is no API route for them yet.
Note
Guardrails are on in production: budgets, model and pool access, the pattern checks and the checks a decision service judges (prompt injection, and the person name, postal address and other personal data patterns). When that service fails, gets no answer within the check's deadline, or the day's checks are used up, the check has no answer: a guardrail that blocks or redacts refuses the request with 503 guardrail_unavailable (the request is not charged, only what the check read), and one that flags lets the request go on and says the check could not run. A guardrail that redacts never lets through text it could not check. Where the request itself kept the check from being asked, the refusal names why: region for a request that requires a region, workspace_share once the workspace's own share of the day is used up, which its own requests can do, and day_share once it holds its part of what is left of the day.
| Type | Name | What it does |
|---|---|---|
| Budget | budget | A spending limit with a reset interval. Each assignee counts on its own, never pooled. |
| Model and pool access | access | Which models, pools and regions requests may use, and whether they may move to another pool. |
| Content moderation | content_moderation | Detects prompt injection and sensitive information, and flags, redacts or blocks it. |
- Type
- Budget
- Name
budget- What it does
- A spending limit with a reset interval. Each assignee counts on its own, never pooled.
- Type
- Model and pool access
- Name
access- What it does
- Which models, pools and regions requests may use, and whether they may move to another pool.
- Type
- Content moderation
- Name
content_moderation- What it does
- Detects prompt injection and sensitive information, and flags, redacts or blocks it.
Parts list: A budget's settings
limit_microsmicro-dollarsThe spending limit, a positive whole number (the Console takes dollars).
resetday,week,month,neverEvery day at 00:00 UTC, every Monday at 00:00 UTC, the 1st of each month at 00:00 UTC, or never: a lifetime limit.
alertsfractionsUp to five fractions of the limit, above 0 and at most 1 (
0.5,0.8). At each, the owners and admins, and a member it is assigned to, are told by email and in the Console, once per period.action_at_limitblock,alertblock, the default: the assignee's requests are refused until the reset.alert: they go on, and crossing the limit is told.
- Each assignee has its own counter, never pooled: a budget assigned to five keys gives each key the whole limit each period, and one assigned to the workspace is one counter for all of the workspace's requests. A rotated key keeps its counter.
- Every charge of the assignee's own requests counts, a content moderation check's charge included.
- A request is admitted while its counter has anything left, its whole maximum charge held until it is settled, so a counter can pass its limit by what the requests then in flight cost. While what is left is held by requests in flight, a request is answered 503
guardrail_unavailable, retry after one second, never 402. - At the limit with
blockthe answer is 402budget_exceeded, naming the guardrail, withresets_at, the end of the period (nullfornever). It is never a payment challenge: requests resume at the reset, or once the limit is raised or the guardrail turned off.
Parts list: An access guardrail's settings
models{"allow": [...]}or{"deny": [...]}Up to 256 entries: catalog ids (each covers every version), aliases, pinned ids, a family as
<family>-*, the workspace's deployments (dep_...), or a model type:language,image,video,audio,vision,classifier,specialist, or a task such aschat,embedding,rerank,speech,transcription. Entries are lowercase, with*only at the end, as-*. A model is judged by every name it answers to, the ids it had before a rename included.poolscommunity,certifiedThe pools allowed. Auto, the default, chooses only among them. A request that names a pool outside them is 403
pool_not_allowed; a key's or a tool's default pool outside them runs as Auto.regionsregion codesThe region requirements allowed, on the Business plan. No region code is offered yet: a request that names a region is refused before any guardrail is read, 400
invalid_requirementon the Business plan and 403region_not_on_planbelow it, so this setting applies once region codes open. Then a request naming a region outside it is 403region_not_allowed. The Console marks a region whose requirement is not enforced yet.fallbacktrue,falsetrueby default.falseforbids moving a request to another allowed pool when its own has no capacity, whatever a key or a request asks.
An access guardrail restricts something: models, pools, regions, or fallback off. Several combine as their intersection, so a request may use only what every one of them allows, and a refusal names the guardrail that refused: 403 model_not_allowed, pool_not_allowed or region_not_allowed. With a router name in model, an access guardrail narrows the models the router may choose (Router).
Two checks, each switched on or off in the guardrail, each with its own action and the messages it scans. The checks read text only: images and files are not scanned. Answers are not scanned either, and the gateway never edits an answer.
| Check | Detects | How |
|---|---|---|
Prompt injection (injection) | Text that tries to override the model's instructions, such as a fetched page or a pasted document | Judged by a decision service, part by part |
Sensitive information (sensitive) | The patterns chosen, and custom patterns | The patterns are found in the gateway; person names, postal addresses and other personal data are judged by a decision service |
- Check
- Prompt injection (
injection) - Detects
- Text that tries to override the model's instructions, such as a fetched page or a pasted document
- How
- Judged by a decision service, part by part
- Check
- Sensitive information (
sensitive) - Detects
- The patterns chosen, and custom patterns
- How
- The patterns are found in the gateway; person names, postal addresses and other personal data are judged by a decision service
| Pattern | Matches | Found by |
|---|---|---|
email | Email addresses | The gateway |
phone | Phone numbers | The gateway |
ssn | United States Social Security numbers, reserved ranges excluded | The gateway |
card | Credit card numbers, their checksum verified | The gateway |
iban | IBANs, their checksum verified | The gateway |
ip | IP addresses, v4 and v6 | The gateway |
secret | API keys and secrets: HIPS's own keys and tokens, the known formats of other services, JSON web tokens and private key blocks | The gateway |
name | Person names, offered as early | A decision service |
address | Postal addresses, offered as early | A decision service |
personal | Other personal data the chosen patterns do not cover | A decision service |
- Pattern
email- Matches
- Email addresses
- Found by
- The gateway
- Pattern
phone- Matches
- Phone numbers
- Found by
- The gateway
- Pattern
ssn- Matches
- United States Social Security numbers, reserved ranges excluded
- Found by
- The gateway
- Pattern
card- Matches
- Credit card numbers, their checksum verified
- Found by
- The gateway
- Pattern
iban- Matches
- IBANs, their checksum verified
- Found by
- The gateway
- Pattern
ip- Matches
- IP addresses, v4 and v6
- Found by
- The gateway
- Pattern
secret- Matches
- API keys and secrets: HIPS's own keys and tokens, the known formats of other services, JSON web tokens and private key blocks
- Found by
- The gateway
- Pattern
name- Matches
- Person names, offered as early
- Found by
- A decision service
- Pattern
address- Matches
- Postal addresses, offered as early
- Found by
- A decision service
- Pattern
personal- Matches
- Other personal data the chosen patterns do not cover
- Found by
- A decision service
A custom pattern is a name and a regular expression. Its name is 1 to 40 letters, digits and _, starting with a letter, and becomes its placeholder (ticket gives [TICKET_1]). Its expression is compiled when it is saved, by an engine whose time is linear in the text, so lookarounds and backreferences are not accepted; one that does not compile, that can match an empty span or that can match nothing is refused. Write ASCII classes such as [A-Za-z0-9_] in place of \w to stay within the compiled size.
| Setting | Values |
|---|---|
action | flag: the request goes on unchanged, and the answer names the guardrail. redact: each match is replaced before any model sees it, and a request the check cannot read in full is refused rather than sent unchecked. block: the request is refused before any model runs, 400 guardrail_blocked, uncharged |
scan | all: every message, system and developer, user, the assistant's earlier turns and tool results, the default for sensitive information. inputs: what did not come from your own instructions or the model, user messages and tool results, the default for prompt injection. last_turn: the newest user message and every message after it |
applies | every_pool, the default: every request. community_only: only attempts placed in the Community pool, so the Certified pool's data-center GPUs receive the full, unredacted text |
- Setting
action- Values
flag: the request goes on unchanged, and the answer names the guardrail.redact: each match is replaced before any model sees it, and a request the check cannot read in full is refused rather than sent unchecked.block: the request is refused before any model runs, 400guardrail_blocked, uncharged
- Setting
scan- Values
all: every message, system and developer, user, the assistant's earlier turns and tool results, the default for sensitive information.inputs: what did not come from your own instructions or the model, user messages and tool results, the default for prompt injection.last_turn: the newest user message and every message after it
- Setting
applies- Values
every_pool, the default: every request.community_only: only attempts placed in the Community pool, so the Certified pool's data-center GPUs receive the full, unredacted text
Redaction replaces sensitive information with a typed placeholder numbered within the request, the same value always the same placeholder, so the model can still tell two addresses apart. A part judged a prompt injection is replaced with the sentence "[Removed by a guardrail: content suspected of prompt injection.]", the rest of the message kept. With a guardrail that redacts email and a custom pattern ticket (TCK-[0-9]{4}), scanning every message:
system: Support desk for ops@example.com.user: Mail jane@example.com or bob@example.com, then jane@example.com. Ticket TCK-1234.| Assignee | What it covers |
|---|---|
| The workspace | Every request the workspace makes: every key, every person's tools, the Playground |
| A member | That person's own requests in the workspace: their tools' sign-ins and their Playground runs; never an API key, which belongs to the workspace whoever made it |
| An API key | Every request made with the key |
A tool's sign-in (dva_...) | One tool on one computer, such as hi or HIPS Code, signed in by a person |
- Assignee
- The workspace
- What it covers
- Every request the workspace makes: every key, every person's tools, the Playground
- Assignee
- A member
- What it covers
- That person's own requests in the workspace: their tools' sign-ins and their Playground runs; never an API key, which belongs to the workspace whoever made it
- Assignee
- An API key
- What it covers
- Every request made with the key
- Assignee
- A tool's sign-in (
dva_...) - What it covers
- One tool on one computer, such as
hior HIPS Code, signed in by a person
Every guardrail that is on and assigned to the workspace, to the request's credential or to its person applies, all of them:
| Type | How several combine |
|---|---|
| Budget | Each counter on its own: a request is refused when any one with block is at its limit |
| Model and pool access | The intersection: what every one allows |
| Content moderation | Every check switched on runs; where two act on one match the strictest action wins (block, then redact, then flag), and the widest messages to scan |
- Type
- Budget
- How several combine
- Each counter on its own: a request is refused when any one with
blockis at its limit
- Type
- Model and pool access
- How several combine
- The intersection: what every one allows
- Type
- Content moderation
- How several combine
- Every check switched on runs; where two act on one match the strictest action wins (
block, thenredact, thenflag), and the widest messages to scan
A key's or a tool's defaults (its pool, region and fallback) stay defaults: a request may override a default, never a guardrail. A default outside a guardrail is refused when it is saved, 400 requirement_conflict naming the guardrail. Owners and admins read and set every guardrail; the billing role reads and sets budgets; a developer reads none.
The gateway checks a request in this order before any GPU receives it: model and pool access, then budgets, then the patterns, then the checks a decision service judges. Every refusal names the guardrail; none names a matched value.
| Event | Chat completions and Responses | Messages |
|---|---|---|
| Blocked by content moderation | 400 invalid_request_error, guardrail_blocked, param the message (messages[2]; on Responses instructions or input), and guardrail: id, name, check (prompt_injection or sensitive_info) and pattern (the pattern's type, or prompt_injection) | invalid_request_error, the same members, no param |
| A budget at its limit | 402 insufficient_credit, budget_exceeded, with guardrail and resets_at | billing_error |
| A model, pool or region outside access | 403 permission_error, model_not_allowed, pool_not_allowed or region_not_allowed, with guardrail | permission_error |
A block or redact check that could not run, or a budget that could not be checked | 503 overloaded_error, guardrail_unavailable, Retry-After; the request is not charged, only what a check read | overloaded_error |
A block or redact check a decision service judges, on a request that requires a region, once the workspace's share of the day is spent, or once it holds its part of what is left of the day | 503 overloaded_error, guardrail_unavailable, Retry-After (30 seconds) and x-hips-guardrails naming the check, its action and why (grd_...;redact;unavailable;region, grd_...;block;unavailable;workspace_share, day_share); nothing is sent to the decision service and the request is not charged. Sending it again soon will not help | overloaded_error |
A block or redact check whose text passes what one request's check covers | 400 guardrail_input_too_long, param messages; send less text, or scan only the last turn | invalid_request_error |
Text the checks do not scan yet: the text of a /v1/tasks, /v1/embeddings or /v1/rerank request, a batch's lines | 403 permission_error, guardrail_unsupported, with guardrail | permission_error |
| A body the scan cannot read | 400 invalid_json at body | invalid_request_error |
| Flagged or redacted | The answer as usual, with the header x-hips-guardrails and the hips object's guardrails | The header, and on a stream hips in message_delta |
- Event
- Blocked by content moderation
- Chat completions and Responses
- 400
invalid_request_error,guardrail_blocked,paramthe message (messages[2]; on Responsesinstructionsorinput), andguardrail:id,name,check(prompt_injectionorsensitive_info) andpattern(the pattern's type, orprompt_injection) - Messages
invalid_request_error, the same members, noparam
- Event
- A budget at its limit
- Chat completions and Responses
- 402
insufficient_credit,budget_exceeded, withguardrailandresets_at - Messages
billing_error
- Event
- A model, pool or region outside access
- Chat completions and Responses
- 403
permission_error,model_not_allowed,pool_not_allowedorregion_not_allowed, withguardrail - Messages
permission_error
- Event
- A
blockorredactcheck that could not run, or a budget that could not be checked - Chat completions and Responses
- 503
overloaded_error,guardrail_unavailable,Retry-After; the request is not charged, only what a check read - Messages
overloaded_error
- Event
- A
blockorredactcheck a decision service judges, on a request that requires a region, once the workspace's share of the day is spent, or once it holds its part of what is left of the day - Chat completions and Responses
- 503
overloaded_error,guardrail_unavailable,Retry-After(30 seconds) andx-hips-guardrailsnaming the check, its action and why (grd_...;redact;unavailable;region,grd_...;block;unavailable;workspace_share,day_share); nothing is sent to the decision service and the request is not charged. Sending it again soon will not help - Messages
overloaded_error
- Event
- A
blockorredactcheck whose text passes what one request's check covers - Chat completions and Responses
- 400
guardrail_input_too_long,parammessages; send less text, or scan only the last turn - Messages
invalid_request_error
- Event
- Text the checks do not scan yet: the text of a
/v1/tasks,/v1/embeddingsor/v1/rerankrequest, a batch's lines - Chat completions and Responses
- 403
permission_error,guardrail_unsupported, withguardrail - Messages
permission_error
- Event
- A body the scan cannot read
- Chat completions and Responses
- 400
invalid_jsonatbody - Messages
invalid_request_error
- Event
- Flagged or redacted
- Chat completions and Responses
- The answer as usual, with the header
x-hips-guardrailsand thehipsobject'sguardrails - Messages
- The header, and on a stream
hipsinmessage_delta
A content moderation block, on chat completions:
400 guardrail_blocked
{ "error": { "message": "The guardrail \"No cards\" blocked this request: its sensitive information check found a match of card in messages[2]. Nothing was sent to a model and the request was not charged.", "type": "invalid_request_error", "param": "messages[2]", "code": "guardrail_blocked", "guardrail": { "id": "grd_...", "name": "No cards", "check": "sensitive_info", "pattern": "card" } }}A budget at its limit:
402 budget_exceeded
{ "error": { "message": "The guardrail \"Daily key budget\" is at its spending limit. Requests resume at its reset, or once the limit is raised in the Console's Guardrails.", "type": "insufficient_credit", "param": null, "code": "budget_exceeded", "guardrail": { "id": "grd_...", "name": "Daily key budget" }, "resets_at": "<the end of the period, RFC 3339 in UTC, or null>" }}A model an access guardrail keeps out, on Messages, in its own shape:
403 model_not_allowed on Messages
{ "type": "error", "error": { "type": "permission_error", "message": "The guardrail \"Approved models\" does not allow the model `<model>` for this credential.", "code": "model_not_allowed", "guardrail": { "id": "grd_...", "name": "Approved models" } }, "request_id": "req_..."}A request a guardrail flagged or redacted goes on. x-hips-guardrails lists each guardrail that acted with its action (grd_...;redact, comma-separated), and the hips object lists each check's action per message with a count per pattern type, never a matched value. On chat completions it is the answer's top-level hips object and, on a stream, the final usage chunk's; on a Responses stream, response.completed's. The redaction above answers:
x-hips-guardrails: grd_...;redactA flag check that could not run says so, where null and unavailable true, and the request goes on; a redact check that could not run refuses the request, as block does:
A check that could not run
x-hips-guardrails: grd_...;flag;unavailable "guardrails": [ { "id": "grd_...", "name": "Injection watch", "check": "prompt_injection", "action": "flag", "where": null, "counts": {}, "unavailable": true }]A request that requires a region is processed only in its region (Privacy Notice section 10.2(b)), and the decision service runs outside HIPS, so the checks it judges are not run for that request: prompt injection, and the patterns name, address and personal. None of the request's text is sent to the service, and no verdict kept from another request is used, so the answer is the same every time. The other patterns run in the gateway as usual, and a match under block is still 400 guardrail_blocked. What a request names never lifts a guardrail an administrator set, so a check that blocks or redacts refuses the request rather than let it through unchecked:
- A
blockorredactcheck the service judges refuses the request with 503guardrail_unavailable, itsRetry-Afterthe longest a 503 gives (30 seconds), andx-hips-guardrailsnaming it with its action,grd_...;redact;unavailable;region. Sending it again will not help: send it without the region requirement, or under a guardrail whose check only flags. - A
flagcheck the service judges lets the request go on and says why it could not run,reasonregionafterunavailable, in the header and in thehipsobject. - The workspace's own share of the day's checks works the same way once it is spent, with the reason
workspace_share(grd_...;redact;unavailable;workspace_share): its requests can spend it, so it never lifts a redaction either. A workspace may also use at most a quarter of what is left of the day's checks, a part that shrinks as the day fills, so a few workspaces never spend the day for every other; a refusal for it namesday_share(grd_...;block;unavailable;day_share). Both renew at 00:00 UTC.
A check not run for a request that requires a region
x-hips-guardrails: grd_...;flag;unavailable;region "guardrails": [ { "id": "grd_...", "name": "Injection watch", "check": "prompt_injection", "action": "flag", "where": null, "counts": {}, "unavailable": true, "reason": "region" }]GET /v1/models marks a model an access guardrail keeps out with hips.allowed: false and the guardrail in hips.allowed_by, in the list and in GET /v1/models/{id}. The list's own hips.defaults.pools holds only the pools your guardrails allow. The Models reference has the rest of the list.
{ "id": "<model id>", "object": "model", "hips": { "allowed": false, "allowed_by": { "guardrail": "grd_...", "name": "Approved models" } }}The workspace's earlier restrictions are guardrails too. Each is marked in the Console with where it comes from, changes where the setting lives, and does not count toward the workspace's 100 guardrails.
| Setting | Its guardrail | What stays |
|---|---|---|
| The workspace budget, in Billing | "Workspace budget": a budget on the workspace, reset month, its alerts, block when the budget stops requests at its cap and alert when it does not | Billing edits it. At the cap the answer stays 402 budget_exceeded, "The workspace has reached its budget cap.", without a guardrail member |
| The pools the workspace allows, and its regions on the Business plan, in Workspace settings | "Workspace pools and regions": an access guardrail on the workspace | Workspace settings edits it. A request naming a pool outside it is 403 pool_not_allowed, naming it |
| The exclusion of the Community pool, the DPA section 7.4 exclusion | "Community pool excluded (DPA section 7.4)": the Certified pool alone, fallback off, marked as the DPA's exclusion | Its meaning under the DPA. A request naming the Community pool, or turning fallback on, is 400 requirement_conflict, as before |
| An API key held to the Certified pool with fallback off | An access guardrail on that key: the Certified pool alone, fallback off | The key's defaults edit it. A request with that key naming the Community pool is 403 pool_not_allowed |
- Setting
- The workspace budget, in Billing
- Its guardrail
- "Workspace budget": a budget on the workspace, reset
month, its alerts,blockwhen the budget stops requests at its cap andalertwhen it does not - What stays
- Billing edits it. At the cap the answer stays 402
budget_exceeded, "The workspace has reached its budget cap.", without aguardrailmember
- Setting
- The pools the workspace allows, and its regions on the Business plan, in Workspace settings
- Its guardrail
- "Workspace pools and regions": an access guardrail on the workspace
- What stays
- Workspace settings edits it. A request naming a pool outside it is 403
pool_not_allowed, naming it
- Setting
- The exclusion of the Community pool, the DPA section 7.4 exclusion
- Its guardrail
- "Community pool excluded (DPA section 7.4)": the Certified pool alone, fallback off, marked as the DPA's exclusion
- What stays
- Its meaning under the DPA. A request naming the Community pool, or turning fallback on, is 400
requirement_conflict, as before
- Setting
- An API key held to the Certified pool with fallback off
- Its guardrail
- An access guardrail on that key: the Certified pool alone, fallback off
- What stays
- The key's defaults edit it. A request with that key naming the Community pool is 403
pool_not_allowed
Budgets, access and the pattern checks cost nothing. A check a decision service judges is charged for the text it reads, by its input tokens, as a usage record of its own marked guardrail, and counts toward budgets. A request a check blocks or could not check is not charged, only what the check read.
| Limit | Value |
|---|---|
| Guardrails a workspace's members make | 100, the ones made from earlier settings not counted |
| Assignees of one guardrail | 1,000 |
Entries in a models list | 256 |
| Alerts of a budget | 5 |
| A guardrail's name | 1 to 120 characters |
| Custom patterns | 20 in one guardrail, 64 across a workspace's content moderation guardrails |
| A custom pattern | A name of 1 to 40 letters, digits and _; an expression of at most 1,000 bytes that compiles within 64 KiB |
| Text one request's check covers | 2 MiB judged by the decision service and 8 MiB scanned by the built-in patterns. Past it, a block or redact check answers 400 guardrail_input_too_long, and a flag check says it could not run |
- Limit
- Guardrails a workspace's members make
- Value
- 100, the ones made from earlier settings not counted
- Limit
- Assignees of one guardrail
- Value
- 1,000
- Limit
- Entries in a
modelslist - Value
- 256
- Limit
- Alerts of a budget
- Value
- 5
- Limit
- A guardrail's name
- Value
- 1 to 120 characters
- Limit
- Custom patterns
- Value
- 20 in one guardrail, 64 across a workspace's content moderation guardrails
- Limit
- A custom pattern
- Value
- A name of 1 to 40 letters, digits and
_; an expression of at most 1,000 bytes that compiles within 64 KiB
- Limit
- Text one request's check covers
- Value
- 2 MiB judged by the decision service and 8 MiB scanned by the built-in patterns. Past it, a
blockorredactcheck answers 400guardrail_input_too_long, and aflagcheck says it could not run
- A matched value and a redacted original stay in the gateway's memory for the request alone: never stored, logged, returned or sent to a model's server. Answers and the Console name guardrails, checks, messages and counts per pattern type, never a value.
- Redaction happens before any GPU receives the request, so a provider's device in the Community pool receives only the redacted text. With
community_only, only the attempts placed in the Community pool are redacted. - A check a decision service judges sends it only the parts the guardrail scans, after the patterns' redaction, for the one call; the service is run outside HIPS. A verdict is kept for a bounded time under a keyed hash of the workspace and the text, never the text, so a conversation's earlier turns are not judged again.
- A request that requires a region sends nothing to the decision service: the checks it judges are not run for that request, as A request that requires a region says.
- Custom patterns are the workspace's configuration, stored with the guardrail and shown to its owners and admins.
- Guardrails, in the Inference menu: the workspace's guardrails with their type, assignees and state, those made from earlier settings marked with where they come from, and the Community pool exclusion named as the DPA's.
- New guardrail, in three steps: Choose type, Configure, Assign. Each step's Continue says beside it what it waits for, and custom patterns are checked as you type, with a sample text to try them on.
- A guardrail's page: its configuration, its assignees, what applies once every access guardrail on an assignee is combined, its history, and Turn off, Edit and Delete.
- A content moderation guardrail with prompt injection on, or with person names, postal addresses or other personal data among its patterns, says beside that check, on the form and on its page, that the check is not run on a request that requires a region.
- Activity, one row per action a guardrail took. The platform does not record actions yet, so the log says nothing is logged yet, and its filters and Export CSV open once it does.
- The Playground names the guardrail that refused a run, with its check and the pattern's type.
Related sheets
- Sheet
- 15 of 19
- Updated
- 2026-11-11