Bedrock is off by default. Opening the console does not give you models — you have to request access per model, grant the right IAM permissions, pick a Region, accept the providers' terms, and then make a call. This is the complete, in-order setup reference: enabling model access in the console, the exact IAM actions and a least-privilege policy, choosing a Region, requesting access to specific models (Claude, Llama, Nova, and the rest), verifying with a first Converse call, and every common access error with its fix.
Unlike a public model API where a key is all it takes, Amazon Bedrock gives you nothing until you deliberately enable it. That is by design: AWS treats every model your organization can call as an auditable, governed decision, and several models carry provider license terms you must accept. So "getting access" is really five separate things that all have to be true at once.
It helps to hold two ideas apart from the start, because conflating them causes most access failures. The first is model access — an account-and-Region-level grant, made in the Bedrock console, that says "this AWS account is allowed to use this specific model in this Region." The second is IAM permission — an identity-level grant that says "this user/role is allowed to perform the Bedrock API actions." You need both. A developer can have full bedrock:InvokeModel IAM permission and still fail, because the account never enabled the model; equally, the account can have a model enabled and a developer still fails, because their IAM policy omits the action. They are independent gates.
Layered on top are three more requirements that are easy to miss. Region: model access and inference are per-Region, so you must be operating in a Region where the model is both available and enabled. Provider terms: some models (notably certain third-party ones) require accepting an end-user license agreement before access is granted; until you click through it, the request stays pending. And credentials/SDK wiring: your code has to be authenticated to the right account and pointed at the right Region endpoint (the runtime client is bedrock-runtime, which is distinct from the control-plane bedrock client used to manage access).
Put those together and the checklist for "I can call a Bedrock model" is: the model is available in your chosen Region, your account has been granted access to it there, you have accepted any provider terms, your identity has the IAM actions, and your client is authenticated and pointed at that Region. The rest of this guide is each of those five, in the order you should do them, followed by how to verify and how to debug when one is missing.
Model access (account + Region, enabled in the Bedrock console) and IAM permission (identity-level, e.g. bedrock:InvokeModel / bedrock:Converse) are independent. You need both, in the same Region, with any provider EULA accepted. If a call returns AccessDeniedException, the missing piece is almost always one of these two — or you are in the wrong Region.
The first real action is requesting model access. This is done once per account, per Region, in the Bedrock console — and it is the step most first-time users skip, then wonder why every call returns access-denied.
Sign in to the AWS Management Console, switch to the Region you intend to build in (top-right Region selector — this matters; see Step 3), and open Amazon Bedrock. In the left navigation, find Model access (sometimes surfaced as part of a "Get started" or "Configure" flow). You will see the full catalog of providers and models with a status against each: Available to request, Access granted, or Access pending.
Select the specific models you plan to use — for example Anthropic Claude Sonnet for reasoning and Amazon Titan Text Embeddings for retrieval — and submit the access request. For most models the grant is effectively immediate (seconds to a couple of minutes) and the status flips to Access granted. For models that require it, you will first be prompted to review and accept the provider's end-user license agreement; some third-party models also ask for brief use-case details. Until those terms are accepted, the model stays pending and calls to it fail.
Two console behaviours are worth knowing. First, access is requested at the model level, so enabling Claude Sonnet does not enable Claude Opus or Claude Haiku — request each variant you will call. Second, the toggle is per Region: the Model access page only reflects the Region currently selected in the console, so if you switch Regions you will see a different set of granted/pending states and must enable models again there. Granting access has no cost; you are only billed when you actually invoke a model.
In organizations that centralize cloud governance, model access is often managed for you — a platform or security team enables an approved subset of models account-wide (sometimes enforced with Service Control Policies so teams can only use vetted models). If you are in that situation and a model you need shows as unavailable, the request goes to that team rather than to a self-serve toggle.
Writing code before visiting Model access. The SDK is installed, the credentials work, the call still returns AccessDeniedException — because the account never enabled that model in that Region. Enable the model in the console first; everything else is downstream of this step.
Model access says the account may use a model. IAM says which identities may make the calls. Bedrock is a standard AWS service governed by IAM, so the principal making the request — an IAM user, an assumed role, a Lambda execution role, an ECS task role — needs a policy that allows the Bedrock actions.
The core runtime actions you grant are bedrock:InvokeModel (synchronous inference), bedrock:InvokeModelWithResponseStream (streaming responses), and bedrock:Converse / bedrock:ConverseStream (the modern Converse API). If your application lists models or reads model metadata at runtime you may also need read actions such as bedrock:ListFoundationModels and bedrock:GetFoundationModel; those live on the control-plane bedrock service rather than bedrock-runtime, but both share the bedrock: IAM namespace.
You can scope permission down to specific models. The Resource in the policy is the foundation-model ARN (for example an ARN ending in foundation-model/anthropic.claude-sonnet), so least-privilege means a service can call exactly the models it needs and nothing else. Granting Resource: "*" works for a quick start but allows any enabled model; tighten it to named ARNs for production. Note that cross-region inference profiles and provisioned-throughput endpoints have their own ARNs, so if you use those you grant the action on the profile/endpoint ARN, not only the base model ARN.
For prototyping, AWS publishes managed policies (for example an Amazon Bedrock full-access policy) you can attach to get moving quickly; for anything beyond a sandbox, prefer a hand-scoped policy. Whatever you attach, remember the governance backstop: every Bedrock API call is recorded in CloudTrail, and you can additionally turn on model-invocation logging to capture full request/response payloads to S3 or CloudWatch for audit and debugging.
The following grants only the runtime actions, only on the two models this hypothetical service uses (a Claude model for chat and a Titan embeddings model for retrieval), in a single Region. Replace the account ID, Region, and model IDs with your own values, and copy exact model IDs from the Bedrock console.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "BedrockInvokeScopedModels",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", "bedrock:Converse", "bedrock:ConverseStream"],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-sonnet",
"arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2"
]
}]
}
Model IDs and ARNs are illustrative — copy the exact current values from the Bedrock console. For a fast sandbox you can use Resource: "*", but scope to named ARNs for production. If you call via a cross-region inference profile or a provisioned-throughput endpoint, add that profile/endpoint ARN to Resource.
Bedrock processes your request in the AWS Region you call, and both model availability and model access are per-Region. Choosing the Region is therefore not a detail — it determines which models you can use, where your data is processed, and your latency.
Weigh three factors. Data residency: because prompts and completions are processed in the calling Region, you keep EU data in an EU Region, US data in a US Region, and so on, to satisfy residency and compliance requirements. Latency: pick a Region close to your users or to the rest of your application to minimize round-trip time. Model availability: not every model is in every Region, and frontier models frequently launch in US Regions (such as us-east-1 and us-west-2) before appearing in others — so the Region with the newest Claude or Nova model may not be the one nearest you. When those pull in different directions, availability often decides, because you cannot call a model that is not in your Region at all.
This is also the most common silent failure mode: a developer enables a model in us-east-1, then runs code configured for eu-west-1, and gets access-denied or model-not-found — not because anything is misconfigured, but because the grant and the call are in different Regions. Always confirm that the Region in your SDK client (the region_name you pass to bedrock-runtime) matches the Region where you enabled the model.
When a single Region cannot give you the availability or throughput you need, Bedrock offers cross-region inference profiles. Instead of a plain model ID you call a profile ID (for example a US or EU profile), and Bedrock automatically routes the request to one of several Regions within that geography — improving availability and smoothing capacity without you managing the routing, while keeping the request inside the residency boundary you chose. The practical rule: pick a home Region first; reach for a cross-region inference profile only when you hit availability or throughput limits. Note that profiles have their own ARNs, so your IAM policy must permit the profile, not just the base model.
| Factor | What it controls | Rule of thumb | Gotcha |
|---|---|---|---|
| Data residency | Where prompts/outputs are processed | Match the Region to your compliance boundary (e.g. EU data → EU Region) | Cross-region inference still stays within the geography you pick |
| Latency | Round-trip time to the model | Pick a Region near your users or app tier | Closest Region may lack the newest model |
| Model availability | Which models exist there at all | Frontier models often land in US Regions first | A model in us-east-1 may not be in eu-central-1 yet |
| Access state | Whether you enabled the model there | Enable models in the same Region your code calls | Grants do not carry across Regions — re-enable per Region |
| Throughput / availability | Capacity headroom under load | Use a cross-region inference profile when one Region is constrained | Profiles need their own ARN in your IAM policy |
Access is granted model-by-model, not provider-by-provider and not all-at-once. Step 1 covered the mechanics of the Model access page; this step is about which specific models to enable and the per-provider nuances — because the grant experience differs a little across Anthropic, Meta, Amazon, and the others.
Decide your model set before you click, because each variant is a separate grant. A typical first set is one workhorse chat model (such as Claude Sonnet), optionally one cheap small model for high-volume calls (such as Claude Haiku, Nova Lite, or a small Mistral), and one embeddings model for retrieval (Titan Text Embeddings or Cohere Embed). Enable exactly those; you can always add more later. Remember that within a family the tiers are distinct grants — enabling Claude Sonnet does not enable Claude Opus or Claude Haiku.
The per-provider experience: Anthropic (Claude) models are among the most-requested and are granted through the standard Model access flow, typically quickly, after you accept the applicable terms. Amazon's own models — the Nova family (Micro/Lite/Pro/Premier text, Canvas image, Reel video) and Titan (text + embeddings) — are usually the most frictionless to enable since they are first-party. Meta (Llama), Mistral, Cohere, Stability AI, AI21 (Jamba), and DeepSeek are enabled the same way, with some third-party models prompting you to accept a provider EULA (and occasionally a short use-case description) before the status flips to granted. None of this requires a contract with the provider — AWS serves the models on your behalf inside AWS.
Once granted, you call a model by its model ID (the exact string shown in the console, e.g. an anthropic.*, meta.*, amazon.*, or mistral.* identifier). With the Converse API, switching from one enabled model to another is usually a one-line change to that modelId string — provided the target model is also enabled in the same Region and permitted by your IAM policy. That three-way alignment (enabled + in-Region + IAM-permitted) is the thing to keep in sync as you add models.
| Provider | Example models to enable | EULA / extra step? | Notes |
|---|---|---|---|
| Anthropic | Claude Haiku, Claude Sonnet, Claude Opus | Accept terms | Most-requested for reasoning, coding, agents; enable each tier separately |
| Amazon | Nova Micro/Lite/Pro/Premier; Titan Text + Embeddings | Usually none (first-party) | Lowest-friction grant; Nova for low cost/latency, Titan for embeddings |
| Meta | Llama (instruct + smaller variants) | Accept terms | Open-weight, freely fine-tunable |
| Mistral | Mistral Large + smaller models | Accept terms | Fast, cost-efficient throughput |
| Cohere | Command; Embed; Rerank | Accept terms | Strong for retrieval, embeddings, reranking |
| Stability AI | Stable Diffusion / Stable Image | Accept terms | Image generation; called via InvokeModel |
| AI21 / DeepSeek | Jamba family / DeepSeek reasoning | Accept terms (some) | Long-context and cost-efficient open reasoning |
With a model enabled, IAM permission attached, and the right Region selected, the last step is to prove the path end-to-end with a single call. The fastest, most portable check is a minimal Converse request — it uses one schema across every chat model, so the same snippet verifies Claude, Llama, Nova, Mistral, and more by changing only the model ID.
You can verify three ways. The quickest is the Bedrock console playground (Chat/Text), where you pick an enabled model and type a prompt — if it answers, model access and the model itself are working, independent of any IAM/SDK wiring in your own code. The second is the AWS CLI: a single aws bedrock-runtime converse command exercises your credentials, Region, IAM permission, and the model in one shot. The third is the SDK (boto3 shown below), which is what your application will actually use.
A minimal Converse call in Python (using the AWS SDK, boto3) looks like this — note the client is bedrock-runtime and the region_name must match where you enabled the model:
A successful response confirms the whole chain at once. A failure is diagnostic: an AccessDeniedException means IAM permission or model access is missing (see Step 2 and Step 1); a ValidationException about an unknown model usually means a wrong/misspelled model ID or that the model is not available in this Region; a ResourceNotFoundException points at the wrong Region or an unenabled model; and a credentials error means the SDK is not authenticated to the account where you did the setup. The next section maps each error to its fix.
import boto3
brt = boto3.client("bedrock-runtime", region_name="us-east-1") # must match the Region you enabled the model in
resp = brt.converse(
modelId="anthropic.claude-sonnet", # the exact model ID from the console; swap to switch models
messages=[{"role": "user", "content": [{"text": "Reply with the single word: connected."}]}],
inferenceConfig={"maxTokens": 16, "temperature": 0},
)
print(resp["output"]["message"]["content"][0]["text"])
If this prints a reply, all five gates line up: model enabled, in-Region, IAM-permitted, terms accepted, client authenticated. The same call structure works for Claude, Llama, Mistral, Nova, and Cohere — only modelId changes. Model IDs shown are illustrative; copy the exact current ID from the Bedrock console.
Almost every "I can't access Bedrock" report resolves to one of a handful of causes: the model was never enabled, IAM is missing the action, the call is in the wrong Region, a provider EULA was never accepted, or the credentials point at the wrong account. This table maps the exact error you see to its cause and fix.
Two debugging habits save the most time. First, check the Region in three places at once — the console Region selector (where you enabled the model), the region_name in your client, and the Region in any CLI profile — and make them identical. Second, read the error type, not just the message: AccessDenied vs ValidationException vs ResourceNotFound each point at a different one of the five gates, so the error class alone usually tells you which step to revisit.
| Symptom / error | Most likely cause | Fix |
|---|---|---|
| AccessDeniedException on a model call | IAM policy lacks the action, OR the model was never enabled for the account in this Region | Confirm Model access shows "Access granted" for this model in this Region (Step 1), and that your IAM policy allows bedrock:InvokeModel / bedrock:Converse on the model ARN (Step 2) |
| Access pending never becomes granted | A required provider EULA was not accepted, or an org policy restricts the model | Re-open Model access and complete the EULA / use-case prompt; if it is governed centrally, request it from your platform/security team |
| ValidationException — unknown / invalid model ID | Misspelled model ID, or the model is not available in this Region | Copy the exact model ID from the console; verify the model exists in your Region or use a cross-region inference profile |
| ResourceNotFoundException | Wrong Region, or calling a model/profile that is not enabled | Set region_name to the Region where you enabled the model; confirm the model (or profile) is granted there |
| Works in console playground, fails in code | IAM/SDK identity differs from the console user, or wrong Region in code | Ensure the SDK credentials map to a principal with the Bedrock IAM actions; align region_name with the console Region |
| UnrecognizedClientException / credentials error | SDK not authenticated, or pointed at the wrong AWS account | Configure valid credentials for the account where you enabled the model (env vars, profile, or role) |
| ThrottlingException / rate or quota errors | Hitting on-demand request/throughput limits for the model | Add retries with backoff, spread load, use a cross-region inference profile, or request a quota increase / Provisioned Throughput |
| Cross-region profile call denied | IAM grants the base model ARN but not the inference-profile ARN | Add the inference-profile ARN to the Resource list in your IAM policy (Step 2) |
Enabling Bedrock and making a first call cost nothing. The harder problem starts once the application is real: GenAI is cheap per call and expensive in aggregate, and the bill can climb faster than teams expect. The good news is that AWS funds much of it through credit programs built for exactly this.
Once access works, the cost levers are the same ones every Bedrock guide returns to: route cheap high-volume calls to small models and escalate only hard steps to frontier models, run latency-tolerant work as batch (typically ~50% cheaper), turn on prompt caching so a repeated system prompt or document is not re-billed at full input price every turn, and reserve Provisioned Throughput only once volume is steady and high. The companion pages Bedrock pricing and the Bedrock API go deep on each.
The other lever is not paying for it yourself. AWS runs credit pools designed for teams building generative AI on Bedrock: Activate Portfolio (up to $100K) for institutionally-funded startups, dedicated Bedrock / GenAI proof-of-concept funding ($10K–$50K) for a defined build, and the competitive Generative AI Accelerator (up to $1M) for AI-first companies. These pools are largely partner-filed and invisible on the public AWS Activate page. This is exactly what CloudRoute does: we route you to a vetted AWS partner who files the credit application and, if you want hands, does this very setup — model access, IAM, Region, first call — and builds the workload with you. Because AWS funds both the credits and the partner engagement, you pay $0. See AWS credits for generative-AI startups, AWS PoC / Bedrock POC funding, and $100K AWS credits.
Accessing Bedrock means five independent things being true at once. This is the whole setup on one screen: what each gate is, where you set it, the API/field that proves it, and the error you see when it is missing. If a call fails, find the symptom column and you know which gate to fix.
| Gate | What it is | Where you set it | Proven by | Error if missing |
|---|---|---|---|---|
| 1. Model access | Account-level grant to use a model in a Region | Bedrock console → Model access | "Access granted" status | AccessDeniedException |
| 2. IAM permission | Identity may call the Bedrock API actions | IAM policy on the user/role | bedrock:InvokeModel / bedrock:Converse allowed | AccessDeniedException |
| 3. Region | Where the call is processed; must have the model | Console Region selector + SDK region_name | Model available + enabled in that Region | ResourceNotFoundException |
| 4. Provider terms | Accepted EULA for models that require one | Bedrock console → Model access prompt | Status flips from pending to granted | Access stays pending |
| 5. Credentials | SDK authenticated to the right account | Env vars / profile / role on bedrock-runtime | A successful Converse response | UnrecognizedClientException |
Situation: The engineers had wired up boto3 and were certain their code was correct, but every Converse call returned AccessDeniedException. They had burned two days assuming it was an IAM policy bug. In reality two gates were misaligned at once: they had never opened Model access to enable Claude for the account, and their code was pointed at a Region different from the one in their console session — so even after a partial IAM fix the call still failed. With no senior AWS person on the team, they could not tell which of the five gates was the real problem.
What CloudRoute did: Routed within 18 hours to a US AWS partner with a GenAI track record. On a short working call the partner walked the five gates in order: enabled Claude Sonnet and a Haiku model plus Titan embeddings in the team's chosen Region, attached a least-privilege IAM policy scoped to those model ARNs (replacing the over-broad one they had been guessing at), aligned the SDK region_name to the console Region, and confirmed the first Converse call returned a completion live on the call. In parallel the partner filed a Bedrock/GenAI proof-of-concept credit application and an Activate Portfolio application so the inference would be credit-funded.
Outcome: First successful Bedrock call within the hour; the assistant feature shipped in the same sprint. GenAI POC credits ($25K) approved in under two weeks and Portfolio ($100K) shortly after, so the early inference spend was fully credit-funded. CloudRoute's commission was paid by the partner from AWS engagement funding; the customer paid $0.
time-to-match: < 24h · first call: same day · credits secured: $125K · cost to customer: $0
CloudRoute routes you to a vetted AWS partner who handles the Bedrock setup (model access, IAM, Region, first call), files your GenAI credit application (Activate Portfolio up to $100K, GenAI POC $10K–$50K, GenAI Accelerator up to $1M), and builds the workload with you. AWS funds the credits and the engagement. You pay $0.