This guide covers the security architecture of this sample, including service-specific credentials, bearer token authentication, regional routing behavior, and audit logging.
⚠️ Important: This sample is intended for informational and educational purposes only. The approach detailed here may not be suitable for all organizations and/or compliance programs. It is important to evaluate this solution against the compliance requirements of your organization and any applicable regulatory obligations you may have. This codebase has not been hardened for production use.
When accessing Bedrock from GovCloud to the Commercial partition, this sample implements:
- Service-Specific Credentials - Limit blast radius (Bedrock access only)
- Bearer Token Authentication - Required for service-specific credentials (handled automatically)
- Regional Routing - US geographic inference profile routes within US regions
- Audit Logging - Track cross-partition access via CloudTrail
Service-specific credentials are a special type of AWS credential that:
- Can ONLY access a specific AWS service (Bedrock in this case)
- Cannot access other AWS services (limited blast radius)
- Use bearer token authentication (not standard access key/secret key)
- Are created via IAM's
CreateServiceSpecificCredentialAPI
The lib/bedrock_client.py module automatically handles bearer token authentication:
# In BedrockClient.__init__():
os.environ['AWS_BEARER_TOKEN_BEDROCK'] = service_credential_password
# Then creates boto3 client WITHOUT access keys:
boto3.client('bedrock-runtime') # Uses bearer token from environmentWhy this matters:
- ✅ Service-specific credentials provide limited blast radius
- ✅ If compromised, attacker can only access Bedrock
- ✅ Cannot be used to access S3, EC2, or other AWS services
- ✅ Automatic rotation support via Secrets Manager
For developers:
You don't need to manually handle bearer tokens — just use the BedrockClient class with service-specific credentials and it works correctly.
This sample uses US geographic inference profiles because newer models like Claude Sonnet 4.5 are only available through inference profiles, not direct model invocation.
When you use a geographic inference profile like:
us.anthropic.claude-sonnet-4-5-20250929-v1:0
Amazon Bedrock uses cross-region inference (CRIS) to route your request to one of the destination regions defined in the profile, optimizing for performance and availability.
This sample targets the bedrock-runtime.us-east-1.amazonaws.com endpoint. Even though the request originates from a Lambda in GovCloud (us-gov-west-1), the source region for CRIS routing purposes is us-east-1 — the region where the Bedrock API call lands.
The cross-partition hop (GovCloud → Commercial) happens at the network/credential layer. By the time Bedrock processes the request, it's a standard commercial-partition operation.
For the US Claude Sonnet 4.5 profile called from us-east-1, requests can be routed to:
| Source Region | Destination Regions |
|---|---|
| us-east-1 | us-east-1, us-east-2, us-west-2 |
All processing stays within US commercial regions. No data leaves the US geography.
For the complete and current list of source/destination region mappings for all models, see Supported Regions and models for inference profiles.
The Commercial stack restricts the IAM user to Bedrock access only:
# infrastructure/stacks/commercial_stack.py
bedrock_user.add_to_principal_policy(
iam.PolicyStatement(
effect=iam.Effect.ALLOW,
actions=[
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
resources=[
f"arn:aws:bedrock:{self.region}::foundation-model/*"
],
conditions={
"StringEquals": {
"aws:RequestedRegion": self.region # us-east-1
}
}
)
)Note: The Converse API (
bedrock-runtime.converse()) uses thebedrock:InvokeModelIAM action under the hood, so the existing policy works without modification.
This policy is already deployed as part of the sample — no additional configuration needed.
All Bedrock API calls are logged in CloudTrail in the source region (us-east-1).
For Converse API calls (via inference profiles):
{
"eventName": "Converse",
"awsRegion": "us-east-1",
"requestParameters": {
"modelId": "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
},
"additionalEventData": {
"inferenceRegion": "us-west-2"
}
}The additionalEventData.inferenceRegion field shows which destination region actually processed the request. This is useful for compliance verification.
Note: The CloudTrail event name is
Conversewhen using the Converse API. The IAM action remainsbedrock:InvokeModel.
Check Lambda logs for errors:
aws logs filter-log-events \
--log-group-name "/aws/lambda/bedrock-demo" \
--filter-pattern "ERROR" \
--profile govcloud| Control | Status | Details |
|---|---|---|
| Service-specific credentials | ✅ Implemented | Bedrock-only access, limited blast radius |
| Bearer token authentication | ✅ Implemented | Handled automatically by lib/bedrock_client.py |
| Credential rotation | ✅ Implemented | Automatic rotation via Secrets Manager |
| Encrypted storage | ✅ Implemented | Secrets Manager encryption at rest |
| TLS encryption | ✅ Implemented | All cross-partition traffic uses TLS 1.2+ |
| Regional routing | ✅ US regions only | us-east-1, us-east-2, us-west-2 |
| CloudTrail audit | ✅ Implemented | All API calls logged in us-east-1 region |