Enable Amazon Bedrock Model Invocation Logging
Overview
This check verifies that model invocation logging is enabled for Amazon Bedrock. When enabled, Bedrock captures request and response data for all model API calls, giving you visibility into how models are being used in your AWS account.
Risk
Without invocation logging enabled, you lose critical visibility into model activity. This creates several security and operational risks:
- No audit trail: You cannot investigate who used which models, when, or what they asked
- Missed abuse detection: Prompt injection attempts, jailbreaks, or misuse go undetected
- Compliance gaps: Many frameworks require logging of AI/ML system interactions
- Delayed incident response: Without logs, troubleshooting issues becomes significantly harder
- Unexpected costs: You may not notice unusual usage patterns until the bill arrives
By default, model invocation logging is disabled in Amazon Bedrock.
Remediation Steps
Prerequisites
You need:
- AWS account access with permissions to configure Bedrock settings
- An S3 bucket to store logs (you can create one during setup)
- Optionally, a CloudWatch Log Group for real-time log access
Required IAM permissions
To configure Bedrock logging, you need these IAM permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:PutModelInvocationLoggingConfiguration",
"bedrock:GetModelInvocationLoggingConfiguration"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:PutBucketPolicy"
],
"Resource": "arn:aws:s3:::your-bedrock-logs-bucket"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"iam:CreateRole",
"iam:PutRolePolicy"
],
"Resource": "*"
}
]
}
AWS Console Method
- Open the Amazon Bedrock console in us-east-1
- In the left navigation pane, click Settings
- Select the Model invocation logging tab
- Click Edit
- Toggle Enable model invocation logging to ON
- Under Log destination, choose one or both:
- S3: Select an existing bucket or create a new one
- CloudWatch Logs: Select an existing log group or create a new one
- Under Data types to log, select the types you want to capture:
- Text: For chat and text completion models
- Image: For image generation models
- Embeddings: For embedding models
- If using CloudWatch Logs, you will need to specify an IAM role that allows Bedrock to write logs
- Click Save changes
AWS CLI (optional)
Enable logging with S3 only:
aws bedrock put-model-invocation-logging-configuration \
--region us-east-1 \
--logging-config '{
"s3Config": {
"bucketName": "<your-bedrock-logs-bucket>"
},
"textDataDeliveryEnabled": true,
"imageDataDeliveryEnabled": true,
"embeddingDataDeliveryEnabled": true
}'
Enable logging with both S3 and CloudWatch:
aws bedrock put-model-invocation-logging-configuration \
--region us-east-1 \
--logging-config '{
"cloudWatchConfig": {
"logGroupName": "/aws/bedrock/model-invocation-logs",
"roleArn": "arn:aws:iam::<account-id>:role/BedrockModelInvocationLoggingRole"
},
"s3Config": {
"bucketName": "<your-bedrock-logs-bucket>"
},
"textDataDeliveryEnabled": true,
"imageDataDeliveryEnabled": true,
"embeddingDataDeliveryEnabled": true
}'
Replace:
<your-bedrock-logs-bucket>with your S3 bucket name<account-id>with your AWS account ID
Create the required IAM role for CloudWatch logging:
First, create the trust policy file:
cat > bedrock-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<account-id>"
}
}
}
]
}
EOF
Create the role:
aws iam create-role \
--role-name BedrockModelInvocationLoggingRole \
--assume-role-policy-document file://bedrock-trust-policy.json
Attach the CloudWatch permissions:
aws iam put-role-policy \
--role-name BedrockModelInvocationLoggingRole \
--policy-name BedrockCloudWatchLoggingPolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:<account-id>:log-group:/aws/bedrock/model-invocation-logs:*"
}
]
}'
CloudFormation (optional)
This template creates the S3 bucket, CloudWatch Log Group, and IAM role needed for Bedrock logging. After deployment, you still need to enable logging via the console or CLI.
AWSTemplateFormatVersion: '2010-09-09'
Description: Enable Amazon Bedrock model invocation logging with S3 and CloudWatch
Parameters:
LogBucketName:
Type: String
Description: S3 bucket name for storing Bedrock invocation logs
MinLength: 3
MaxLength: 63
LogGroupName:
Type: String
Description: CloudWatch Log Group name for Bedrock invocation logs
Default: /aws/bedrock/model-invocation-logs
LogRetentionDays:
Type: Number
Description: Number of days to retain logs in CloudWatch
Default: 90
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653]
Resources:
BedrockLoggingBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref LogBucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Enabled
BedrockLoggingBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref BedrockLoggingBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowBedrockLogging
Effect: Allow
Principal:
Service: bedrock.amazonaws.com
Action:
- s3:PutObject
Resource: !Sub ${BedrockLoggingBucket.Arn}/*
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
BedrockLoggingLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Ref LogGroupName
RetentionInDays: !Ref LogRetentionDays
BedrockLoggingRole:
Type: AWS::IAM::Role
Properties:
RoleName: BedrockModelInvocationLoggingRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: bedrock.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
Policies:
- PolicyName: BedrockCloudWatchLoggingPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub ${BedrockLoggingLogGroup.Arn}:*
Outputs:
LogBucketArn:
Description: ARN of the S3 bucket for Bedrock logs
Value: !GetAtt BedrockLoggingBucket.Arn
LogGroupArn:
Description: ARN of the CloudWatch Log Group for Bedrock logs
Value: !GetAtt BedrockLoggingLogGroup.Arn
LoggingRoleArn:
Description: ARN of the IAM role for Bedrock logging
Value: !GetAtt BedrockLoggingRole.Arn
Deploy the stack:
aws cloudformation deploy \
--template-file bedrock-logging.yaml \
--stack-name bedrock-invocation-logging \
--parameter-overrides LogBucketName=<your-bedrock-logs-bucket> \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1
After deployment, enable logging using the CLI:
# Get the role ARN from stack outputs
ROLE_ARN=$(aws cloudformation describe-stacks \
--stack-name bedrock-invocation-logging \
--query 'Stacks[0].Outputs[?OutputKey==`LoggingRoleArn`].OutputValue' \
--output text \
--region us-east-1)
# Enable logging
aws bedrock put-model-invocation-logging-configuration \
--region us-east-1 \
--logging-config "{
\"cloudWatchConfig\": {
\"logGroupName\": \"/aws/bedrock/model-invocation-logs\",
\"roleArn\": \"$ROLE_ARN\"
},
\"s3Config\": {
\"bucketName\": \"<your-bedrock-logs-bucket>\"
},
\"textDataDeliveryEnabled\": true,
\"imageDataDeliveryEnabled\": true,
\"embeddingDataDeliveryEnabled\": true
}"
Terraform (optional)
# Amazon Bedrock Model Invocation Logging Configuration
# This Terraform configuration enables logging for Bedrock model invocations
variable "log_bucket_name" {
description = "S3 bucket name for storing Bedrock invocation logs"
type = string
}
variable "log_group_name" {
description = "CloudWatch Log Group name for Bedrock invocation logs"
type = string
default = "/aws/bedrock/model-invocation-logs"
}
variable "log_retention_days" {
description = "Number of days to retain logs in CloudWatch"
type = number
default = 90
}
variable "enable_text_logging" {
description = "Enable logging for text model invocations"
type = bool
default = true
}
variable "enable_image_logging" {
description = "Enable logging for image model invocations"
type = bool
default = true
}
variable "enable_embedding_logging" {
description = "Enable logging for embedding model invocations"
type = bool
default = true
}
# Data source for current AWS account
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
# S3 bucket for Bedrock logs
resource "aws_s3_bucket" "bedrock_logs" {
bucket = var.log_bucket_name
}
resource "aws_s3_bucket_versioning" "bedrock_logs" {
bucket = aws_s3_bucket.bedrock_logs.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "bedrock_logs" {
bucket = aws_s3_bucket.bedrock_logs.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_public_access_block" "bedrock_logs" {
bucket = aws_s3_bucket.bedrock_logs.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_policy" "bedrock_logs" {
bucket = aws_s3_bucket.bedrock_logs.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowBedrockLogging"
Effect = "Allow"
Principal = { Service = "bedrock.amazonaws.com" }
Action = "s3:PutObject"
Resource = "${aws_s3_bucket.bedrock_logs.arn}/*"
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}
]
})
}
# CloudWatch Log Group for Bedrock logs
resource "aws_cloudwatch_log_group" "bedrock_logs" {
name = var.log_group_name
retention_in_days = var.log_retention_days
}
# IAM role for Bedrock to write to CloudWatch
resource "aws_iam_role" "bedrock_logging" {
name = "BedrockModelInvocationLoggingRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "bedrock.amazonaws.com"
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}
]
})
}
resource "aws_iam_role_policy" "bedrock_cloudwatch_logging" {
name = "BedrockCloudWatchLoggingPolicy"
role = aws_iam_role.bedrock_logging.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "${aws_cloudwatch_log_group.bedrock_logs.arn}:*"
}
]
})
}
# Bedrock model invocation logging configuration
resource "aws_bedrock_model_invocation_logging_configuration" "main" {
logging_config {
embedding_data_delivery_enabled = var.enable_embedding_logging
image_data_delivery_enabled = var.enable_image_logging
text_data_delivery_enabled = var.enable_text_logging
cloudwatch_config {
log_group_name = aws_cloudwatch_log_group.bedrock_logs.name
role_arn = aws_iam_role.bedrock_logging.arn
}
s3_config {
bucket_name = aws_s3_bucket.bedrock_logs.id
}
}
}
output "log_bucket_arn" {
description = "ARN of the S3 bucket for Bedrock logs"
value = aws_s3_bucket.bedrock_logs.arn
}
output "log_group_arn" {
description = "ARN of the CloudWatch Log Group for Bedrock logs"
value = aws_cloudwatch_log_group.bedrock_logs.arn
}
output "logging_role_arn" {
description = "ARN of the IAM role for Bedrock logging"
value = aws_iam_role.bedrock_logging.arn
}
Deploy with Terraform:
terraform init
terraform plan -var="log_bucket_name=<your-bedrock-logs-bucket>"
terraform apply -var="log_bucket_name=<your-bedrock-logs-bucket>"
Verification
After enabling logging, verify the configuration:
- In the Bedrock console, go to Settings > Model invocation logging
- Confirm that logging shows as Enabled
- Verify your S3 bucket and/or CloudWatch Log Group are listed as destinations
- Make a test model invocation and check that logs appear within a few minutes
CLI verification commands
Check logging configuration:
aws bedrock get-model-invocation-logging-configuration \
--region us-east-1
Expected output when properly configured:
{
"loggingConfig": {
"cloudWatchConfig": {
"logGroupName": "/aws/bedrock/model-invocation-logs",
"roleArn": "arn:aws:iam::123456789012:role/BedrockModelInvocationLoggingRole"
},
"s3Config": {
"bucketName": "your-bedrock-logs-bucket"
},
"textDataDeliveryEnabled": true,
"imageDataDeliveryEnabled": true,
"embeddingDataDeliveryEnabled": true
}
}
Check for recent logs in CloudWatch:
aws logs describe-log-streams \
--log-group-name /aws/bedrock/model-invocation-logs \
--order-by LastEventTime \
--descending \
--limit 5 \
--region us-east-1
Check for logs in S3:
aws s3 ls s3://<your-bedrock-logs-bucket>/ --recursive | head -20
Additional Resources
- Amazon Bedrock Model Invocation Logging Documentation
- Amazon Bedrock Security Best Practices
- CloudWatch Logs User Guide
Notes
- Regional configuration: Bedrock logging is configured per-region. If you use Bedrock in multiple regions, you must enable logging in each region separately.
- Log latency: Logs typically appear within 1-5 minutes of a model invocation.
- Cost considerations: Both S3 storage and CloudWatch Logs incur costs. Configure lifecycle policies to manage log retention and control costs.
- Large responses: For responses that exceed CloudWatch limits, Bedrock can deliver large data to S3 via the
largeDataDeliveryS3Configoption. - Sensitive data: Model invocation logs may contain sensitive information from prompts and responses. Ensure proper access controls on your log destinations.
- Compliance frameworks: This check maps to C5, ISO27001, KISA-ISMS-P, NIS2, and SOC2 compliance frameworks.