TL;DR
Your IAM user or role is missing the bedrock:InvokeModel permission. Attach this policy to fix it immediately:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*::foundation-model/*"
}
]
}
If you also need model access enabled in the AWS console, see the Step 3 section below β IAM permission alone is not enough for Bedrock.
The Full Error
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the InvokeModel operation: User: arn:aws:iam::123456789012:user/dev is not authorized to perform: bedrock:InvokeModel
This shows up when calling boto3 to invoke a Bedrock foundation model, typically with code like:
import boto3
import json
client = boto3.client("bedrock-runtime", region_name="us-east-1")
response = client.invoke_model(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
body=json.dumps({"prompt": "Hello", "max_tokens": 100}),
)
Root Cause
AWS Bedrock has two separate access controls that both need to be satisfied:
- IAM permission β your user/role must have
bedrock:InvokeModelin its policy - Model access β the specific foundation model must be enabled for your AWS account in the Bedrock console
This error means at least the IAM permission is missing. The ARN in the error message (arn:aws:iam::123456789012:user/dev) tells you exactly which principal is denied.
Step 1 β Identify the IAM Principal
Check which credentials boto3 is actually using:
aws sts get-caller-identity
Output:
{
"UserId": "AIDAEXAMPLEID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/dev"
}
This is the entity you need to grant permissions to. If it's a role (common in EC2, Lambda, ECS), the ARN looks like arn:aws:sts::123456789012:assumed-role/MyRole/session.
Step 2 β Attach the Bedrock IAM Policy
Option A: Via AWS Console
- Go to IAM β Users (or Roles) and select the principal from Step 1
- Click Add permissions β Attach policies directly β Create policy
- Switch to the JSON tab and paste the policy below
- Name it
BedrockInvokeAccessand save
Option B: Via AWS CLI
Create the policy file bedrock-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*::foundation-model/*"
}
]
}
Then create and attach it:
# Create the policy
aws iam create-policy \
--policy-name BedrockInvokeAccess \
--policy-document file://bedrock-policy.json
# Attach to a user
aws iam attach-user-policy \
--user-name dev \
--policy-arn arn:aws:iam::123456789012:policy/BedrockInvokeAccess
# Or attach to a role
aws iam attach-role-policy \
--role-name MyLambdaRole \
--policy-arn arn:aws:iam::123456789012:policy/BedrockInvokeAccess
To restrict to a specific model instead of all (/*), use the model ARN:
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
Step 3 β Enable Model Access in Bedrock Console
Even with correct IAM permissions, you get AccessDeniedException if the model isn't enabled for your account. This is a Bedrock-specific gate separate from IAM.
- Open the AWS Bedrock console
- In the left sidebar, click Model access
- Find your target model (e.g., Claude 3 Sonnet) and click Manage model access
- Check the box next to the model and click Save changes
Approval is usually instant for most models. Anthropic models may require agreeing to usage terms. Meta's Llama models require a brief form submission.
Step 4 β Verify the Fix
Run a quick test to confirm everything is working:
import boto3
import json
client = boto3.client("bedrock-runtime", region_name="us-east-1")
try:
response = client.invoke_model(
modelId="amazon.titan-text-express-v1",
contentType="application/json",
accept="application/json",
body=json.dumps({
"inputText": "Say hello",
"textGenerationConfig": {"maxTokenCount": 20}
}),
)
body = json.loads(response["body"].read())
print("Success:", body["results"][0]["outputText"])
except Exception as e:
print("Error:", e)
If it prints Success: with text, you're done. Amazon Titan Text is a good test model since it requires no special approval.
You can also verify IAM permissions directly with the policy simulator:
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/dev \
--action-names bedrock:InvokeModel \
--resource-arns "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
Look for "EvalDecision": "allowed" in the output.
Common Mistakes
- Wrong region: Bedrock is not available in all regions. Use
us-east-1orus-west-2to start. The region in your boto3 client must match where model access is enabled. - Using
bedrockclient instead ofbedrock-runtime:invoke_modellives on thebedrock-runtimeclient. Thebedrockclient is for management operations like listing models. - SCP blocking permissions: In AWS Organizations, Service Control Policies (SCPs) can block IAM permissions even when the policy is correctly attached. Check with your AWS admin if the IAM policy looks right but the error persists.
- Stale credentials in environment: If you recently updated the IAM policy but still see the error, check that
AWS_ACCESS_KEY_IDenv vars aren't overriding the updated credentials.

