Claude Platform on AWS in Practice

Copy-Paste IAM Policies for Claude Platform on AWS

Start from AWS's managed policies, then graduate to workspace-scoped custom documents. Here are the templates, with each statement explained.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Claude Platform on AWS authorizes everything through standard IAM policies on the aws-external-anthropic service. IAM JSON doesn't allow comments, so the templates below use Sid fields as labels and prose to explain each statement. Swap in your own region, account ID, and wrkspc_... ID throughout.

Option zero: the five AWS managed policies

Before writing custom JSON, know what's on the shelf. AWS ships five managed policies, all granted on Resource: "*" (every workspace in the account):

Managed policyGrants
AnthropicFullAccessaws-external-anthropic:* — everything, including Console access
AnthropicReadOnlyAccessGet*, List*, CallWithBearerToken
AnthropicInferenceAccessReads + sync/batch inference + CountTokens + CallWithBearerToken
AnthropicLimitedAccessThe inference set + all Claude Managed Agents actions
AnthropicSelfHostedEnvironmentAccessGetEnvironment, ProcessEnvironmentWork, GetSession, UpdateSession, GetSkill, CallWithBearerToken

Two caveats. AnthropicInferenceAccess is the narrowest managed policy that can run inference, but its Get*/List* wildcards read all workspace content — file bytes, skill content, batch results, session conversation history, memory contents (only vault secrets and webhook signing secrets are write-only). And AssumeConsole appears in none of the ReadOnly/Inference/Limited/SelfHostedEnvironment policies — Console access requires AnthropicFullAccess or a custom grant.

Template 1: minimal inference role (production default)

The recommended shape for an application role: exactly the actions inference needs, on exactly one workspace ARN. This is the minimal single-workspace policy from the official reference:

{"Version": "2012-10-17", "Statement": [{
  "Sid": "InferenceOnMyWorkspaceOnly",
  "Effect": "Allow",
  "Action": [
    "aws-external-anthropic:CreateInference",
    "aws-external-anthropic:CountTokens",
    "aws-external-anthropic:GetModel",
    "aws-external-anthropic:ListModels",
    "aws-external-anthropic:GetWorkspace"
  ],
  "Resource": "arn:aws:aws-external-anthropic:us-west-2:123456789012:workspace/wrkspc_01AbCdEf23GhIj"
}]}

Why each action: CreateInference is POST /v1/messages; CountTokens supports pre-flight sizing; GetModel/ListModels let the app discover model capabilities; GetWorkspace lets it verify its own configuration. No files, no batches, no session reads.

Template 2: per-workspace full access (team or tenant isolation)

Full power inside one workspace, nothing outside it. Route-less actions don't bind to workspace ARNs, so they need a second statement on Resource: "*":

{"Version": "2012-10-17", "Statement": [
 {"Sid": "AllActionsOnOneWorkspace",
  "Effect": "Allow",
  "Action": "aws-external-anthropic:*",
  "Resource": "arn:aws:aws-external-anthropic:us-west-2:123456789012:workspace/wrkspc_01AbCdEf23GhIj"},
 {"Sid": "RouteLessAuthActions",
  "Effect": "Allow",
  "Action": ["aws-external-anthropic:CallWithBearerToken",
             "aws-external-anthropic:AssumeConsole"],
  "Resource": "*"}
]}

Why the split: the first statement covers every route-mapped action for that workspace; the second covers API-key auth and the "Open Claude Console" flow, which are authentication-layer actions with no workspace binding.

Template 3: provisioning/admin role (no inference)

For CI/CD or platform teams that create and retire workspaces but should never read their contents or call models. CreateWorkspace and ListWorkspaces are account-scoped, so Resource: "*" is required, not sloppy:

{"Version": "2012-10-17", "Statement": [{
  "Sid": "WorkspaceLifecycleOnly",
  "Effect": "Allow",
  "Action": [
    "aws-external-anthropic:CreateWorkspace",
    "aws-external-anthropic:GetWorkspace",
    "aws-external-anthropic:ListWorkspaces",
    "aws-external-anthropic:UpdateWorkspace",
    "aws-external-anthropic:ArchiveWorkspace"
  ],
  "Resource": "*"
}]}

Template 4: deny statement for stateful features

Organizations with zero-data-retention sensitivities often allow inference but block stateful features. Attach this alongside an Allow policy — an explicit Deny always wins:

{"Version": "2012-10-17", "Statement": [{
  "Sid": "BlockStatefulWrites",
  "Effect": "Deny",
  "Action": ["aws-external-anthropic:CreateBatchInference",
             "aws-external-anthropic:CreateFile"],
  "Resource": "arn:aws:aws-external-anthropic:us-west-2:123456789012:workspace/wrkspc_01AbCdEf23GhIj"
}]}

For a full lockdown, also deny the remaining Get/List/Delete/Cancel file and batch actions. Remember the wildcard traps when extending deny lists: Delete* doesn't catch ArchiveAgent or skill-version deletion via UpdateSkill, and *File accidentally matches the UserProfile actions — enumerate explicitly (details in the actions reference).

Permission boundaries: these documents also work as permission boundaries — attach Template 1 or 2 as the boundary on roles that developers create themselves, capping what any self-service role can ever do regardless of its attached policies.

Verifying a policy actually does what you think

Test from the role itself, not from your admin session. Assume the role, construct an AnthropicAWS() client, and confirm three things: an allowed call (say, messages.create) succeeds, a call you meant to block (say, uploading a file under Template 4) returns a 403, and calls against a different workspace ID also 403. A 403 on this platform means the request authenticated and was refused by authorization — which is exactly the signal you're testing for.

For ongoing assurance, lean on CloudTrail: workspace, vault, and webhook actions are Management events and logged by default, while inference, batch, file, and skill actions are Data events that need explicit (paid) data-event logging enabled. If your security team wants to see denied inference attempts, turn data events on before the audit, not after. Each response's x-amzn-requestid is indexed in CloudTrail, so a support ticket and a log entry can be tied together precisely.

Where to go next

The full action list and its gotchas live in the IAM actions reference. For structuring one workspace per environment so these ARNs stay clean, see multi-workspace strategy; for key-free credentials to pair with these policies, start with EC2 instance roles.

Sources