From d55b85c6fd08c48a9fa24a07e1c2c46d1bd53b71 Mon Sep 17 00:00:00 2001 From: Sphia Sadek Date: Wed, 26 Aug 2026 12:22:15 -0400 Subject: [PATCH] docs(model): document bedrockGeoRegion and the global-vs-geo tradeoff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `bedrockGeoRegion` context key added in #764 was documented nowhere — not in the developer guide, not in the canonical model-configuration reference #742 created for exactly this, not in cdk.json. The synth-time error names the key, but only for someone who already knows it exists. Adds a section covering what the key does, its accepted values (derived from what the CDK models: global, us, us-gov, eu, apac, jp, au), and that an unrecognized value fails at synth rather than producing a well-formed ARN for a profile that does not exist. Also states the choice, since it is a real tradeoff rather than a default to accept: `global.` routes to any supported commercial Region for better throughput and resilience under burst, while a geo profile is what a data-residency requirement demands. Plus the two things that fail at runtime rather than synth — a model without a profile in the target geography, and account-level Bedrock access not covering that geography's entitlements. Two existing statements went stale with #764 and are corrected here: the bare-vs-prefixed rule described the grant sites as adding `us.` specifically, and the layer-1 table row described only `bedrockModels`. Both now read in terms of the configured geography. Answers a question that the layering table implies but never states: changing the geography needs a redeploy, because the grants are scoped to profile ARNs resolved at synth, whereas switching among already-granted models does not. Starlight mirror regenerated with `mise //docs:sync`; docs build green. --- docs/guides/DEVELOPER_GUIDE.md | 27 ++++++++++++++++--- .../developer-guide/Model-configuration.md | 27 ++++++++++++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/guides/DEVELOPER_GUIDE.md b/docs/guides/DEVELOPER_GUIDE.md index b8f1bf31..db2e2986 100644 --- a/docs/guides/DEVELOPER_GUIDE.md +++ b/docs/guides/DEVELOPER_GUIDE.md @@ -122,7 +122,7 @@ See the [Cedar policy guide](./CEDAR_POLICY_GUIDE.md) for the full authoring ref | # | Layer | What it controls | Where | ID form | |---|---|---|---|---| -| 1 | **IAM invoke allowlist** | Which models the agent's roles may invoke at all. The outer gate — everything below fails without it. | `DEFAULT_BEDROCK_MODEL_IDS` (`cdk/src/constructs/bedrock-models.ts:34`); override with CDK context `bedrockModels` (key at `:48`, resolver at `:67`) | **Bare** (`anthropic.claude-…`) | +| 1 | **IAM invoke allowlist** | Which models the agent's roles may invoke at all, and in which geography. The outer gate — everything below fails without it. | `DEFAULT_BEDROCK_MODEL_IDS` (`cdk/src/constructs/bedrock-models.ts`); override with CDK context `bedrockModels`. Geography via context `bedrockGeoRegion` (default `us`) | **Bare** (`anthropic.claude-…`) | | 2 | **Platform default model** | The model used when nothing narrower is set. A **Python literal only** — there is no CDK prop or environment knob in front of it today. | `agent/src/config.py:563` (the `ANTHROPIC_MODEL` fallback) and `agent/src/models.py:157` (`TaskConfig.anthropic_model`) | Prefixed (`us.anthropic.…`) | | 3 | **Auxiliary / fast model** | The small model Claude Code uses for auxiliary work (WebFetch page summarization, the pre-flight safety check). | Stack env `ANTHROPIC_DEFAULT_HAIKU_MODEL` (`cdk/src/stacks/agent.ts` (the runtime environment block)); agent-side fallback at `agent/src/config.py:569` | Prefixed (`us.anthropic.…`) | | 4 | **Per-repo override** | One repository's model, with no agent redeploy. | Blueprint `agent.modelId` (`cdk/src/constructs/blueprint.ts`, `BlueprintProps.agent.modelId`) → RepoTable `model_id` (`cdk/src/handlers/shared/repo-config.ts:37`) → ECS injects `ANTHROPIC_MODEL` (`cdk/src/handlers/shared/strategies/ecs-strategy.ts:217`) | Prefixed (`us.anthropic.…`) | @@ -149,7 +149,7 @@ Every one of those is gated by the **IAM invoke allowlist** (layer 1), which is ### Bare vs. prefixed IDs — the one rule that bites -Layer 1 takes **bare foundation-model IDs**; every other layer takes the **prefixed inference-profile ID**. This asymmetry is deliberate: both grant sites derive the inference-profile ARN by *adding* the `us.` prefix themselves, so a prefixed entry in `bedrockModels` would produce an invalid `us.us.anthropic.…` ARN. The resolver rejects a `us.`/`eu.`/`apac.`-prefixed entry at `cdk/src/constructs/bedrock-models.ts:84` so the typo fails at synth rather than at runtime. +Layer 1 takes **bare foundation-model IDs**; every other layer takes the **prefixed inference-profile ID**. This asymmetry is deliberate: both grant sites derive the inference-profile ARN by *adding* the geo prefix themselves, so a prefixed entry in `bedrockModels` would produce an invalid `us.us.anthropic.…` ARN. The resolver rejects an entry carrying any modelled geo prefix so the typo fails at synth rather than at runtime. In the other direction, a **bare** ID cannot be invoked on demand at all. Verified: @@ -160,7 +160,28 @@ throughput isn't supported. Retry your request with the ID or ARN of an inferenc profile that contains this model. ``` -So: `bedrockModels` context → `anthropic.claude-opus-5`. Everywhere else → `us.anthropic.claude-opus-5`. +So: `bedrockModels` context → `anthropic.claude-opus-5`. Everywhere else → `us.anthropic.claude-opus-5` (or whatever geo you have configured — see below). + +### Choosing the inference-profile geography + +Which geography those prefixes name is itself configurable, via CDK context `bedrockGeoRegion`: + +```console +$ cdk deploy -c bedrockGeoRegion=global +``` + +or as a `context` entry in `cdk/cdk.json`. It defaults to `us`, and the accepted values are whatever `@aws-cdk/aws-bedrock-alpha` models — currently `global`, `us`, `us-gov`, `eu`, `apac`, `jp`, `au`. An unrecognized value **fails at synth** rather than at deploy: an invented geography produces a well-formed ARN for a profile that does not exist, so the grant would authorize nothing and the agent would fail at turn 0 with `AccessDenied` and nothing to explain why. + +One value drives everything that needs a prefix — both grant sites (the AgentCore runtime and the ECS task role) and the layer-3 `ANTHROPIC_DEFAULT_HAIKU_MODEL` env var. That is deliberate: a deployment can never grant one geography's profiles while telling the agent to call another's. + +**Which to choose.** A `global.` profile routes to any supported commercial Region, which gives better throughput and resilience under peak demand — worth having for tasks that run for hours and burst. A geo profile (`us.`, `eu.`, `apac.`, …) keeps inference within that geography, which is what you need under a **data-residency requirement**. Pick the geo profile in that case; the throughput benefit is not worth a compliance breach. + +Two things to check when changing it, both of which fail at runtime rather than synth: + +- The models you use must have an active profile in the target geography. Not every model is published to every geo. +- Your account's [Bedrock model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) must cover the deployment Region's entitlements for that geography. + +Changing the geography requires a **redeploy**, because the IAM grants are scoped to explicit profile ARNs resolved at synth. Switching among already-granted models does not — see layer 4. ### Bumping the default model diff --git a/docs/src/content/docs/developer-guide/Model-configuration.md b/docs/src/content/docs/developer-guide/Model-configuration.md index a8a315aa..6e9d0d29 100644 --- a/docs/src/content/docs/developer-guide/Model-configuration.md +++ b/docs/src/content/docs/developer-guide/Model-configuration.md @@ -8,7 +8,7 @@ title: Model configuration | # | Layer | What it controls | Where | ID form | |---|---|---|---|---| -| 1 | **IAM invoke allowlist** | Which models the agent's roles may invoke at all. The outer gate — everything below fails without it. | `DEFAULT_BEDROCK_MODEL_IDS` (`cdk/src/constructs/bedrock-models.ts:34`); override with CDK context `bedrockModels` (key at `:48`, resolver at `:67`) | **Bare** (`anthropic.claude-…`) | +| 1 | **IAM invoke allowlist** | Which models the agent's roles may invoke at all, and in which geography. The outer gate — everything below fails without it. | `DEFAULT_BEDROCK_MODEL_IDS` (`cdk/src/constructs/bedrock-models.ts`); override with CDK context `bedrockModels`. Geography via context `bedrockGeoRegion` (default `us`) | **Bare** (`anthropic.claude-…`) | | 2 | **Platform default model** | The model used when nothing narrower is set. A **Python literal only** — there is no CDK prop or environment knob in front of it today. | `agent/src/config.py:563` (the `ANTHROPIC_MODEL` fallback) and `agent/src/models.py:157` (`TaskConfig.anthropic_model`) | Prefixed (`us.anthropic.…`) | | 3 | **Auxiliary / fast model** | The small model Claude Code uses for auxiliary work (WebFetch page summarization, the pre-flight safety check). | Stack env `ANTHROPIC_DEFAULT_HAIKU_MODEL` (`cdk/src/stacks/agent.ts` (the runtime environment block)); agent-side fallback at `agent/src/config.py:569` | Prefixed (`us.anthropic.…`) | | 4 | **Per-repo override** | One repository's model, with no agent redeploy. | Blueprint `agent.modelId` (`cdk/src/constructs/blueprint.ts`, `BlueprintProps.agent.modelId`) → RepoTable `model_id` (`cdk/src/handlers/shared/repo-config.ts:37`) → ECS injects `ANTHROPIC_MODEL` (`cdk/src/handlers/shared/strategies/ecs-strategy.ts:217`) | Prefixed (`us.anthropic.…`) | @@ -35,7 +35,7 @@ Every one of those is gated by the **IAM invoke allowlist** (layer 1), which is ### Bare vs. prefixed IDs — the one rule that bites -Layer 1 takes **bare foundation-model IDs**; every other layer takes the **prefixed inference-profile ID**. This asymmetry is deliberate: both grant sites derive the inference-profile ARN by *adding* the `us.` prefix themselves, so a prefixed entry in `bedrockModels` would produce an invalid `us.us.anthropic.…` ARN. The resolver rejects a `us.`/`eu.`/`apac.`-prefixed entry at `cdk/src/constructs/bedrock-models.ts:84` so the typo fails at synth rather than at runtime. +Layer 1 takes **bare foundation-model IDs**; every other layer takes the **prefixed inference-profile ID**. This asymmetry is deliberate: both grant sites derive the inference-profile ARN by *adding* the geo prefix themselves, so a prefixed entry in `bedrockModels` would produce an invalid `us.us.anthropic.…` ARN. The resolver rejects an entry carrying any modelled geo prefix so the typo fails at synth rather than at runtime. In the other direction, a **bare** ID cannot be invoked on demand at all. Verified: @@ -46,7 +46,28 @@ throughput isn't supported. Retry your request with the ID or ARN of an inferenc profile that contains this model. ``` -So: `bedrockModels` context → `anthropic.claude-opus-5`. Everywhere else → `us.anthropic.claude-opus-5`. +So: `bedrockModels` context → `anthropic.claude-opus-5`. Everywhere else → `us.anthropic.claude-opus-5` (or whatever geo you have configured — see below). + +### Choosing the inference-profile geography + +Which geography those prefixes name is itself configurable, via CDK context `bedrockGeoRegion`: + +```console +$ cdk deploy -c bedrockGeoRegion=global +``` + +or as a `context` entry in `cdk/cdk.json`. It defaults to `us`, and the accepted values are whatever `@aws-cdk/aws-bedrock-alpha` models — currently `global`, `us`, `us-gov`, `eu`, `apac`, `jp`, `au`. An unrecognized value **fails at synth** rather than at deploy: an invented geography produces a well-formed ARN for a profile that does not exist, so the grant would authorize nothing and the agent would fail at turn 0 with `AccessDenied` and nothing to explain why. + +One value drives everything that needs a prefix — both grant sites (the AgentCore runtime and the ECS task role) and the layer-3 `ANTHROPIC_DEFAULT_HAIKU_MODEL` env var. That is deliberate: a deployment can never grant one geography's profiles while telling the agent to call another's. + +**Which to choose.** A `global.` profile routes to any supported commercial Region, which gives better throughput and resilience under peak demand — worth having for tasks that run for hours and burst. A geo profile (`us.`, `eu.`, `apac.`, …) keeps inference within that geography, which is what you need under a **data-residency requirement**. Pick the geo profile in that case; the throughput benefit is not worth a compliance breach. + +Two things to check when changing it, both of which fail at runtime rather than synth: + +- The models you use must have an active profile in the target geography. Not every model is published to every geo. +- Your account's [Bedrock model access](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) must cover the deployment Region's entitlements for that geography. + +Changing the geography requires a **redeploy**, because the IAM grants are scoped to explicit profile ARNs resolved at synth. Switching among already-granted models does not — see layer 4. ### Bumping the default model