diff --git a/aws/documentation/services/bedrock/scp.md b/aws/documentation/services/bedrock/scp.md new file mode 100644 index 00000000..cad7d3f2 --- /dev/null +++ b/aws/documentation/services/bedrock/scp.md @@ -0,0 +1,113 @@ +# Governance through Service Control Policies + +The following models are approved for use at Census by OIS as of 2026-01-07: + +* All Titan Models +* Claude Sonnet 4.5 +* Claude 3.7 Sonnet +* Claude 3.5 Sonnet v1 +* Claude 3 Haiku +* Llama 3 8B +* Llama 3 70B + +To restrict Amazon Bedrock access across a large AWS Organizations environment (including both GovCloud and Commercial), we will use Service Control Policies (SCPs). +To implement this across a large Organization with **GovCloud** and **Commercial** accounts, we will account for three distinct resource types in the SCP: + +1. **Foundation Models:** The base models (e.g., `anthropic.claude-3-haiku...`). +2. **Inference Profiles:** These are required for cross-region inference (common in GovCloud) and carry a prefix like `us.anthropic...`. +3. **Provisioned Throughput:** These use specific ARNs for reserved capacity and have the format `provisioned-model/...`. + +### 1. The Strategy: Use an "Allowlist" SCP + +The most robust way to manage this is to attach an SCP to the **Root** of your Organization (or specific OUs). This SCP will deny the `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream` actions for any resource that is *not* in your approved list. We may adjust this and move it to individual OUs if we need more granular control, such as allowing access to models other than these in specific OUs. + +#### Key Model IDs + +| Model Name | Model ID / Pattern | +| --- | --- | +| All Titan Models | `amazon.titan` | +| Claude 3.7 Sonnet | `anthropic.claude-3-7-sonnet-20250219-v1:0` | +| Claude 4.5 Sonnet | `anthropic.claude-4-5-sonnet-2025` | +| Claude 3.5 Sonnet v1 | `anthropic.claude-3-5-sonnet-20240620-v1:0` | +| Claude 3 Haiku | `anthropic.claude-3-haiku-20240307-v1:0` | +| Llama 3 8B | `meta.llama3-8b-instruct-v1:0` | +| Llama 3 70B | `meta.llama3-70b-instruct-v1:0` | + +### 2. The Service Control Policy (SCP) + +We will use a policy like this in the Management Account. Note the use of `NotResource` to create the allowlist. +This policy denies all Bedrock model invocations *unless* the resource matches your approved list. It is configured for both the `aws` (Commercial) and `aws-us-gov` (GovCloud) partitions. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "RestrictBedrockModelsAndProfiles", + "Effect": "Deny", + "Action": [ + "bedrock:InvokeModel", + "bedrock:InvokeModelWithResponseStream", + "bedrock:CreateModelInvocationJob", + "bedrock:UseInferenceProfile" + ], + "NotResource": [ + "arn:*:bedrock:*:*:foundation-model/amazon.titan*", + "arn:*:bedrock:*:*:foundation-model/anthropic.claude-4-5-sonnet*", + "arn:*:bedrock:*:*:foundation-model/anthropic.claude-3-7-sonnet*", + "arn:*:bedrock:*:*:foundation-model/anthropic.claude-3-5-sonnet-20240620*", + "arn:*:bedrock:*:*:foundation-model/anthropic.claude-3-haiku*", + "arn:*:bedrock:*:*:foundation-model/meta.llama3-8b*", + "arn:*:bedrock:*:*:foundation-model/meta.llama3-70b*", + "arn:*:bedrock:*:*:inference-profile/*anthropic.claude-4-5-sonnet*", + "arn:*:bedrock:*:*:inference-profile/*anthropic.claude-3-7-sonnet*", + "arn:*:bedrock:*:*:inference-profile/*anthropic.claude-3-5-sonnet-20240620*", + "arn:*:bedrock:*:*:inference-profile/*anthropic.claude-3-haiku*", + "arn:*:bedrock:*:*:inference-profile/*meta.llama3*", + "arn:*:bedrock:*:*:provisioned-model/*" + ] + } + ] +} + +``` + +#### 1. Managing Inference Profiles + +In GovCloud, you almost always use **Inference Profiles** (e.g., `us.anthropic.claude-3-5-sonnet-20240620-v1:0`). + +* The `NotResource` block includes `inference-profile/*...`. +* The wildcard `*` before the model name in the profile ARN is critical because profiles are often prefixed by region indicators (like `us.` or `eu.`). + +#### 2. Provisioned Throughput (PT) + +Provisioned Throughput ARNs look like `arn:{partition}:bedrock:region:account:provisioned-model/resource-id`. + +* In the policy above, we've used a broad allow for `provisioned-model/*`. +* **Best Practice:** To be even stricter, you can tag your Provisioned Throughput resources (e.g., `Approved: True`) and add a `Condition` to the SCP that only allows invocation if the resource has that tag. We +are not likely to pursue this approach. + +#### 3. GovCloud Subscription Linkage + +Remember that in GovCloud, model access is technically granted by "subscribing" in the associated commercial account. + +* **The Guardrail:** Even if a user bypasses the GovCloud console and tries to use an unapproved model via CLI/SDK, this SCP will stop the request at the IAM level before it ever reaches the Bedrock service. + +### 3. Implementation Details for GovCloud + +GovCloud handles Bedrock slightly differently than Commercial regions: + +* **Subscription Linkage:** You must still "Request Access" for models in the **linked standard (commercial) account** before they become available in GovCloud. +* **Regional Availability:** Ensure the specific models (like Claude 3.7 or Llama 3) are actually supported in the GovCloud regions you are using (e.g., `us-gov-west-1`). If a model isn't available in GovCloud yet, the SCP will simply act as a future-proof guardrail. +* **Cross-Region Inference:** If you use "Inference Profiles" (which allow Bedrock to route requests to other regions to handle capacity), you must include the **Inference Profile ARNs** in your `NotResource` list, otherwise, the routed calls will be denied. + +### 4. Important Governance Tips + +* **Provisioned Throughput:** The ARNs will look different (e.g., `...:provisioned-model/...`). We may need to add these patterns to the `NotResource` block. +* **Testing:** Always apply SCPs to a "Sandbox" OU first. An error in a `NotResource` block can inadvertently block all Bedrock access if the ARN patterns don't match exactly. +* **Model IDs:** AWS occasionally updates specific version strings. Using wildcards (e.g., `amazon.titan*`) is safer for entire families, but use specific IDs if you want to force teams onto a specific version (like Sonnet 3.5 **v1**). + +# CHANGELOG + +* 1.0.0 -- 2026-01-07 + - develop guide and document