Follow Discord
Sweep 03 Nov 2026 · 22:27Z Build v2.1.318 536 read Stable v2.1.311 Latest v2.1.318 Next v2.1.318 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Claude apps gateway configuration changedclaude-apps-gateway-config

Nearest release: v2.1.317, published 7 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 2 Nov 2026 16:50 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 2 Nov 2026 17:07 UTC.

Upstream edited
Recorded here
Lines+105added
Lines−10removed
From line 357 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits69to this page, all time

##### Add guardrail input tags ##### What input tags don't cover #### Apply every matching policy

The whole hunk

from line 357, old and new numbered
/
lines
from line 357
357357 # keep the quotes: a bare 1 fails at boot
358358```
359359 
360> [!WARNING]
361>
362> The gateway doesn't support guardrail input tags. It adds no guard content tags to prompts, so a guardrail filter that Amazon Bedrock applies only to tagged input doesn't run on traffic through the gateway. For which filters depend on input tags, see [input tags](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html) in the Amazon Bedrock documentation.
363 
364360Also grant `bedrock:ApplyGuardrail` on the guardrail to the principal that signs this upstream's requests: the gateway's AWS principal, or with [`assume_role`](#bedrock-in-another-aws-account) the role named in `role_arn`.
365361 
366362Set `guardrail` on every `bedrock` upstream or on none. The gateway refuses to start on a mix, because [failover](#multiple-upstreams) could otherwise send a request to a Bedrock upstream that has no guardrail.
from line 365
369365 
370366When a `/v1/messages` request whose body carries an `amazon-bedrock-*` field, such as `amazon-bedrock-guardrailConfig`, reaches a Bedrock upstream that has `guardrail` set, the gateway answers 400 instead of forwarding it.
371367 
368> [!WARNING]
369>
370> By default the gateway adds no input tags to prompts, so a guardrail filter that Amazon Bedrock applies only to tagged input doesn't run on traffic through the gateway. To add the tags, set [`input_tagging`](#add-guardrail-input-tags). For which filters depend on input tags, see [input tags](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html) in the Amazon Bedrock documentation.
371 
372##### Add guardrail input tags
373 
374To have the gateway add the input tags that an Amazon Bedrock guardrail's [prompt attacks filter](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-prompt-attack.html) needs, set `input_tagging` in the `guardrail` block and restart the gateway. Set the same value on every `bedrock` upstream, or the gateway refuses to start. Requires Claude Code v2.1.316 or later on the gateway server. A gateway on a version that lacks the key exits at startup with `Unrecognized key(s) in object: 'input_tagging'`.
375 
376> [!WARNING]
377>
378> According to [Amazon Bedrock's documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-tagging.html), every filter in the guardrail stops evaluating untagged content once a request carries input tags. Try `input_tagging` on a test gateway before you set it on one that developers use.
379 
380`input_tagging` takes one of these values:
381 
382| `input_tagging` | Where the gateway tags text | After the guardrail blocks a prompt |
383| :- | :- | :- |
384| `last_message` | The `user` messages since Claude's last reply | In Claude Code, the next prompt can pass, and Claude then receives the blocked prompt as part of the conversation |
385| `user_messages` | `user` messages | Later prompts in the session can be blocked as well, until the developer removes the blocked prompt |
386| `all_messages` | `user` and `assistant` messages | Same as `user_messages` |
387| `all_messages_and_system` | The system prompt and every message, including [mid-conversation system messages](https://code.claude.com/docs/en/llm-gateway-protocol.md#feature-pass-through) | Same as `user_messages` |
388 
389With `last_message`, if the `user` messages since Claude's last reply hold no text to tag, the gateway tags the mid-conversation system messages since that reply instead. A tool call counts as a reply.
390 
391Amazon Bedrock's guidance for the prompt attacks filter is to [tag user input so that the system prompt is excluded](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-prompt-attack.html). If you set `all_messages_and_system`, a filter that flags Claude Code's own system prompt can block requests.
392 
393The example below tags text in every `user` message:
394 
395```yaml theme={null}
396upstreams:
397 - provider: bedrock
398 region: us-east-1
399 auth: {}
400 guardrail:
401 id: gr-abc123
402 version: "1"
403 input_tagging: user_messages
404```
405 
406`user` messages can also hold text that Claude Code adds, such as [system reminders](https://code.claude.com/docs/en/glossary.md#system-reminder), so check on the test gateway that ordinary requests aren't blocked.
407 
408In Anthropic's testing, a tagged session kept its [prompt cache](https://code.claude.com/docs/en/prompt-caching.md) reads from one prompt to the next, and the tags added no input tokens.
409 
410##### What input tags don't cover
411 
412No `input_tagging` value stops a developer who deliberately puts text where no tag goes. Don't count on the guardrail to evaluate these parts of a request:
413 
414* **Content the gateway doesn't tag**: messages that your `input_tagging` value leaves out, tool definitions, tool call inputs, images, and PDFs, among others. Unless you set `all_messages_and_system`, the system prompt is untagged too.
415* **Tool results**: these hold what Claude's tools return, such as file contents and web pages. In Anthropic's testing, a word filter didn't evaluate them, with or without tags.
416 
417If your AWS account or organization enforces a guardrail, see [Amazon Bedrock's documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-enforcements.html) for how that guardrail treats input tags.
418 
372419##### Bedrock in another AWS account
373420 
374421Set `assume_role` on a Bedrock upstream and the gateway uses its own AWS identity only to call `sts:AssumeRole` on a role you name, which can be in a different AWS account from the gateway. Every Bedrock request from that upstream is signed with the one-hour credentials STS returns, so no long-lived access key crosses accounts.
from line 851
804851 
805852### `managed`
806853 
807The `managed` block defines role-based access policies keyed on IdP groups or email domain. Policies are evaluated in order; the first match is selected, then merged onto the `match: {}` catch-all base. They are served per-user at `GET /managed/settings` with ETag/304 caching.
854The `managed` block defines role-based access policies keyed on IdP groups or email domain. Policies are evaluated in order; by default the first match is selected, then merged onto the `match: {}` catch-all base. A user who matches two role policies gets only the first, so the second policy's deny rules don't apply unless you [apply every matching policy](#apply-every-matching-policy). Policies are served per-user at `GET /managed/settings` with ETag/304 caching.
808855 
809856```yaml theme={null}
810857managed:
from line 892
845892 
846893An authenticated user who matches no policy gets the gateway's defaults, which means every model in the catalog and no managed settings. Add a `match: {}` catch-all last if you want a guaranteed default policy.
847894 
895Put organization-wide deny rules in the `match: {}` policy, because a group policy's rules apply only while the user's token carries that group.
896 
848897> [!NOTE]
849898>
850899> The gateway keeps no user directory of its own. It authorizes each request from the user's IdP token, reading group membership from the token's `groups` claim and evaluating policies against it. There is no roster to enumerate and no accounts to pre-create, and therefore no SCIM endpoint, because there is nothing for SCIM to sync into.
from line 906
857906> * **Group membership**: changing a user's group membership changes which policy matches them. This takes effect on the next session re-mint, meaning the next silent refresh, bounded by `session.ttl_hours`.
858907>
859908> Claude Desktop follows [its own schedule](#when-a-policy-change-reaches-claude-desktop).
909 
910#### Apply every matching policy
911 
912A user who matches several role policies gets only the first unless you set `policy_mode: layered` beside `policies`. With `layered`, every policy that matches the user applies, down to the first `match: {}` policy.
913 
914`policy_mode` requires Claude Code v2.1.316 or later on the gateway server. A gateway on a version that lacks it refuses to start when it finds the key. Upgrade every replica before you add the key, and remove the key before you roll back to an earlier version. This example has one group that loses `WebFetch` and one that gains Opus:
915 
916```yaml theme={null}
917managed:
918 policy_mode: layered
919 policies:
920 - match: { groups: [no-web] }
921 cli:
922 permissions: { deny: ["WebFetch"] }
923 - match: { groups: [opus-users] }
924 cli:
925 availableModels: [opus, sonnet]
926 - match: {}
927 cli:
928 availableModels: [sonnet]
929 enforceAvailableModels: true
930```
931 
932The table shows what a user in both `no-web` and `opus-users` receives under the default, `first_match`, and under `layered`.
933 
934| Setting | `first_match` | `layered` |
935| - | - | - |
936| `availableModels` | `sonnet` | `opus`, `sonnet` |
937| `enforceAvailableModels` | `true` | `true` |
938| `permissions.deny` | `WebFetch` | `WebFetch` |
939 
940The gateway merges each matching policy onto the ones listed below it, by the same [merge rules](#managed) as the base layer:
941 
942* **Allow-lists, single values, and blocks such as `sandbox`**: each comes whole from the first-listed matching policy that sets it, so two groups' `availableModels` lists don't add up.
943* **Deny-lists and hook arrays**: these add up across every matching policy, so a user in two groups gets both groups' deny rules.
944* **`env`, `modelOverrides`, and `skillOverrides`**: entries merge by name, and the first-listed matching policy that sets a name supplies its value.
945* **`desktop` keys**: these merge by [the rules for the base `desktop` block](#how-a-role-policy-inherits-the-base-desktop-block).
946 
947> [!WARNING]
948>
949> Policies can add up to looser rules than any one of them gives alone. For example, the `match: {}` policy sets `sandbox.enabled: true`, one group's policy sets `permissions.allow: ["Bash"]`, and another group's sets `sandbox.enabled: false`. A user in both groups receives `Bash` allowed with the sandbox off. In this case, list the policy that allows `Bash` first, and copy the `match: {}` policy's whole `sandbox` block into it.
950 
951With `layered`, the gateway refuses to start on some settings, including these:
952 
953* **A `!` pattern**: a [`!` negation](https://code.claude.com/docs/en/permissions#special-characters-and-negation) in a `Read` or `Edit` rule in any policy's `permissions.deny` or `permissions.ask` list, the `match: {}` policy's included
954* **A limit on hooks outside the catch-all**: `disableAllHooks`, `allowedHttpHookUrls`, or `httpHookAllowedEnvVars` in any policy other than `match: {}`
860955 
861956#### Start sessions on a model the policy allows
862957 
Feedback