Bedrock Model Access Denied When IAM Already Allows It
A team's request for Claude Sonnet 5 on Amazon Bedrock was headed for IAM changes until an availability check in each Region showed the Marketplace agreement as NOT_AVAILABLE. This is how to read that check and who has to approve the agreement.
By VVV Ops ·
Bedrock reported the Marketplace agreement for Claude Sonnet 5 as NOT_AVAILABLE in both Regions one team's AWS account uses, while that account's IAM policies already allowed bedrock:InvokeModel* and aws-marketplace:Subscribe on *. The team had opened a request for Marketplace access to the model for one workload account, and the obvious next step was another IAM change. One availability check per Region turned it into an approval question instead.
The AccessDeniedException that sends people searching has more causes than IAM. The Amazon Bedrock model access page describes missing AWS Marketplace permissions, condition keys on bedrock:InvokeModel that the first call does not satisfy, a missing Anthropic First Time Use (FTU) form, an account without a valid payment method, an agreement still pending, and accounts that need additional account-level access, which it refers to AWS Sales. Only the first two are IAM problems. Before touching either, we ask Bedrock what state the agreement is in.
What IAM already allowed
Our engineer checked IAM first, and the two actions the access page names were already allowed on *. He then ran aws bedrock get-foundation-model-availability for the model in both Regions the account uses. Region and entitlement came back AVAILABLE. The agreement came back NOT_AVAILABLE, twice.
No policy edit would change that answer. He raised who in the company approves the agreement, and the ticket changed hands.
When you run the same IAM check on your own account, look past those two actions. The access page lists three Marketplace actions as prerequisites for the automatic subscription (aws-marketplace:Subscribe, aws-marketplace:Unsubscribe and aws-marketplace:ViewSubscriptions), and it warns that the first invocation is authorized like any other bedrock:InvokeModel request. If a policy scopes that action with condition keys, the first call has to satisfy them or it fails, and the subscription never starts. Its example is an aws:SourceIp condition, a key that is absent from the request context when the call goes through a VPC endpoint.
One call, four status fields
get-foundation-model-availability takes a model ID and returns four status fields for that model in the Region the CLI points at. The CLI reference lists the values each one can take:
| Field | Possible values | |---|---| | regionAvailability | AVAILABLE, NOT_AVAILABLE | | entitlementAvailability | AVAILABLE, NOT_AVAILABLE | | authorizationStatus | AUTHORIZED, NOT_AUTHORIZED | | agreementAvailability.status | AVAILABLE, PENDING, NOT_AVAILABLE, ERROR |
The loop below checks every Region a workload calls. The model ID is the one on the Claude Sonnet 5 model card, and the access page says these Bedrock commands need AWS CLI 2.27.42 or later.
# Set REGIONS to the Regions your workload calls; the values here are placeholders
MODEL_ID="anthropic.claude-sonnet-5"
REGIONS="<region-a> <region-b>"
for region in $REGIONS; do
echo "== $region"
aws bedrock get-foundation-model-availability \
--model-id "$MODEL_ID" \
--region "$region" \
--query '{region: regionAvailability, entitlement: entitlementAvailability, authorization: authorizationStatus, agreement: agreementAvailability.status, error: agreementAvailability.errorMessage}' \
--output json
done
Run it per account as well as per Region. The access page says access is determined separately for each AWS account, so two accounts in the same AWS Organization can return different answers.
Only the agreement status gets a full explanation in the documentation. AVAILABLE means access exists, PENDING means the agreement is still being set up, NOT_AVAILABLE means access does not exist, and ERROR means it could not be completed, with errorMessage describing the problem. A PENDING status can follow an Anthropic use case submission, and invocations keep returning AccessDeniedException until it turns AVAILABLE. AWS sends an email when setup finishes. The references describe the other three fields in a line each, so we read them as routing: a NOT_AVAILABLE Region sends us to the model card's Regional availability table before anything else.
Why the agreement needs an owner
Asking who approves was the right move, and the documentation says why. The model card calls Claude Sonnet 5 "a third-party model offered and billed through AWS Marketplace" and says its charges appear in AWS Cost Explorer under the model provider rather than under Amazon Bedrock. The access page adds that invoking a third-party model for the first time means agreeing to its End User License Agreement. Anthropic models also need the FTU form, which asks for a company name, a company website, the intended users, an industry and the use cases, and the account needs a valid payment method for Marketplace purchases.
So the first call accepts a license and starts a Marketplace subscription that bills under the provider, and for an Anthropic model it follows a form filed in the company's name. We would rather that decision sit with someone who can sign for it than with whichever test call happens to run first.
The organization layer changes who that person can be. The FTU form is required once per account or once at the organization's management account, and a submission at the management account is inherited by the other accounts in the AWS Organization (opt-in Regions need it again). It has the same shape as organization-level support enrolment, which we wrote about in the AWS Support plan migration post: one decision at the management account reaches every member. Model access does not travel that way. It stays per account.
Approval is also where the cost conversation starts. On Bedrock there is no Anthropic-side spend cap, as we covered in what an AI coding assistant costs per developer, so the budget control is yours to build before the model goes into a workload.
Commands for whoever approves
Once the answer is yes, the access page documents a programmatic path for third-party models. The second step applies to Anthropic models only.
# 1. List the offers for the model; the response carries the offerToken
aws bedrock list-foundation-model-agreement-offers --model-id anthropic.claude-sonnet-5
# 2. Anthropic only: once per account, or once at the organization's management account
aws bedrock put-use-case-for-model-access --form-data <Base64EncodedFormData>
# 3. Create the agreement with the token from step 1
aws bedrock create-foundation-model-agreement \
--model-id anthropic.claude-sonnet-5 \
--offer-token <OfferToken>
# 4. Check again; PENDING can follow step 2, and invocations are denied until AVAILABLE
aws bedrock get-foundation-model-availability --model-id anthropic.claude-sonnet-5
The console route is shorter. Open the model from the Model catalog in the playground and Bedrock starts the subscription on the first invocation; for Anthropic models the use case form comes first.
We would run either path from a role that holds the Marketplace permissions and keep those permissions off the workload role. The access page says users do not need Marketplace subscription permissions to invoke a model once it has been enabled, since they are only required the first time a model is used in an account.
Holding a model until the approval lands
Since the first call accepts the license, a company that wants its approval step to mean something has to block that call first. The access page recommends this sequence for organizations that review the EULA before use: block with service control policies or IAM, review the terms, then enable. It also says what falls short. Denying aws-marketplace:Subscribe alone leaves the first invocation open, because Bedrock starts the subscription in the background, so the block has to be a Deny on bedrock:InvokeModel at the organization or account level. Deleting an agreement with delete-foundation-model-agreement does not hold either, since the next invocation creates it again.
When the approver's role gets aws-marketplace:Subscribe, the aws-marketplace:ProductId condition key can narrow it to one model; the model card gives Claude Sonnet 5's product ID as prod-4ezhkeia6k2cs. Scope a deny by Region with care: once an identity has subscribed to a model in one Region, the page says it can request access in every Region where the model is available, even where aws-marketplace:Subscribe is denied.
A triage order for the next blocked model
- Run the availability loop for every account and Region the workload uses before anyone edits a policy.
- Agreement
PENDING: setup is in progress. Poll the status or wait for the AWS email. - Agreement
ERROR: readerrorMessageand fix what it names. - Agreement
NOT_AVAILABLE: find the approver. For an Anthropic model, check the FTU form and the payment method as well, then use one of the two paths above. The access page allows up to 15 minutes for the background subscription to finish, and up to 2 minutes after the Marketplace permissions are granted, so test again before changing more. - Agreement
AVAILABLEand calls still denied: now look at IAM, starting with the invoke actions and any condition keys on them. If the model is supported in the Region and the denial persists, the access page points to AWS Sales for additional account-level access.
When a request for a Bedrock model reaches your queue as an IAM ticket, talk to us. We would start with the availability check in each account and Region the workload uses, then write the approver a short note on what accepting the agreement commits the company to.