The situation
A company has standardised on Amazon Bedrock and the demand is now organisation-wide. A dozen product teams, spread across separate AWS accounts under one AWS Organization, all want to invoke foundation models. Some teams have a genuine need for the most capable and most expensive models; most do not. One team handles regulated data and must be pinned to an approved shortlist. Finance wants a monthly figure per team, not one undifferentiated Bedrock line on the consolidated bill.
The platform team owns the problem. They have been fielding a ticket per team asking for model access, hand-writing IAM policies, and guessing at who spent what when the bill arrives. It does not scale, and it is not safe: nothing today stops a team from invoking a model nobody signed off on, and nothing attributes the cost of that call to the team that made it.
What they want is three things at once. Least privilege at the level of an individual model, so a team can reach exactly the models it was approved for and no others. An organisation-wide policy floor that holds even if a team account is misconfigured. And cost that is visible per team without reading tea leaves. These pull on different controls, and the account structure is the frame that holds them together.
What actually matters
The first thing that matters is that Bedrock is open by default. Access to all foundation models is enabled in commercial Regions for a principal holding the AWS Marketplace permissions, and the first invocation of a third-party model starts the Marketplace subscription in the background. Two controls people reach for do not stop that. Deleting a model agreement lasts only until the next invocation recreates it, and denying aws-marketplace:Subscribe still lets the first call through, because Bedrock initiates the subscription itself. What does stop it is a Deny on the Bedrock invocation actions, scoped to foundation model ARNs, in IAM or a service control policy. AWS’s own guidance for an organisation that has to review a licence before anyone uses a model is to block invocation first, read the terms, and lift the deny afterwards.
The second thing is granularity. Invocation permissions can be scoped to a specific foundation model ARN, and that ARN carries no account and no Region, so arn:aws:bedrock:*::foundation-model/<model-id> covers every Region at once. A policy can also name an Inference profileA Bedrock resource wrapping a model so calls to it can be tagged, routed across regions, or repointed without changing app code. ARN, which is account-scoped and Regional, and that becomes the hook for cost attribution and cross-Region routing. One detail catches people writing these by hand: denying bedrock:InvokeModel also blocks Converse and StartAsyncInvoke, and bedrock:InvokeModel* covers the streaming variants.
The third thing is that in a multi-account organisation you have a control the individual account does not: the organisation itself. AWS Organizations service control policies set the maximum available permissions for the accounts beneath them. An SCP does not grant anything; it draws the ceiling. A well-placed SCP can deny Bedrock actions the organisation never sanctions, or deny invocation of specific models everywhere, or deny it except under a stated condition, and no IAM policy in a member account can climb over that ceiling. One exception matters here. SCPs reach only member accounts, so the management account the platform team works from sits outside the ceiling it wrote and needs its own controls.
The fourth thing is that cost attribution has to be built. Bedrock spend does not arrive split by team. An application inference profile carries cost allocation tags: a team passes the profile ARN where the model ID would go, and the profile’s tags attach to the billing record for each request. Two details shape the design. Each profile references one model, so the count is teams multiplied by models rather than one per team. And the tags have to be activated in the Billing console, take up to 24 hours to appear, and are not retroactive, so activation has to precede the period finance needs to report on. What lands is aggregated dollars per usage type per day rather than a per-request figure.
The fifth thing is that runtime policy and the audit trail both belong at the organisation level, and only one of them can actually live there. A guardrail can be enforced across accounts: create it in the management account, cut a numeric version, and name that version in an AWS Organizations Amazon Bedrock policy attached to the root, an OU, or a single account. Every invocation beneath it then carries the safeguards, with no team referencing anything. Invocation logging works differently. Its destination has to sit in the same account and Region as the configuration, so each account logs locally and the trail is centralised afterwards.
Hold these together and a pattern falls out. The platform team stops answering tickets and starts operating a shared configuration: the organisation ceiling, the enforced guardrail, the logging standard, and a self-service route to a scoped role and a tagged inference profile that nobody writes by hand.
What we’ll filter on
- Closing the default: since every model is reachable unless denied, is there a Deny on the invocation actions covering everything outside the approved list?
- Least privilege at model granularity: does the identity-based policy scope invocation to specific foundation model or inference-profile ARNs rather than the whole Bedrock service?
- Organisation-wide floor: is there a service control policy that denies unwanted Bedrock actions or specific models across all member accounts, that no member-account IAM can override?
- Per-team cost visibility: are application inference profiles tagged per team, and are those tags activated in the Billing console ahead of the period finance needs to report on?
- Central policy and audit: is one guardrail version enforced from the organisation rather than referenced team by team, and is invocation logging configured in every account and Region with the trail aggregated afterwards?
The landscape
Model access is the layer people expect to be a gate and is not one. In commercial Regions every foundation model is available to an account whose principals hold the Marketplace permissions, and Bedrock subscribes on first use. A console page for enabling models by hand survives in GovCloud, where the step is still manual. Everywhere else the shortlist is expressed as a deny covering the invocation actions for every model ARN outside the approved set. Write a regulated OU that way round, denying everything outside its list, because a policy that names only today’s expensive models leaves every model released after it allowed.
IAM identity-based policies are where the fine-grained decision lives. A role gets a policy allowing the invocation actions on the specific foundation model ARNs, or inference-profile ARNs, the team is approved for, and nothing broader. Permission boundaries are the companion control for a self-service organisation. A boundary caps the maximum permissions a role can hold, so each team can create and manage its own Bedrock roles without those roles exceeding the boundary the platform team set. Where a boundary and an SCP are both present, the boundary, the SCP and the identity policy must all allow an action before it succeeds.
Service control policies are the organisation-level lever. Attached to the organisation root or to an organisational unit, an SCP denies actions across every member account beneath it and cannot be overridden from inside one. The governance uses are direct: deny Bedrock actions the organisation does not sanction anywhere, deny invocation of named model ARNs so an expensive model is off-limits, or fence a regulated OU by denying everything outside its approved set. Because an SCP only ever removes permission and never grants it, it is a ceiling, and member-account IAM operates in the space below.
Cost allocation tags plus application inference profiles are the attribution layer. A system-defined inference profile, in one Region or across several, defines how a call is routed; an application inference profile references one model and adds tags you set. Give each team a profile per model it uses, tag it with the team identifier, and have the team pass that profile ARN in place of the model ID. Once the tags are activated in the Billing console, Cost Explorer and the Cost and Usage Report slice Bedrock spend by team. Coverage stops short in one place: application inference profiles work with InvokeModel and Converse on the bedrock-runtime endpoint, and a Responses or Chat Completions request naming one is rejected with a 400. The profile ARN is also an IAM resource, so the object that attributes cost is one a policy can pin a team to.
Guardrail enforcement and invocation logging are the shared policy and the audit. Enforcement runs through a policy type in AWS Organizations. Enable Amazon Bedrock policies, create the guardrail in the management account, cut a numeric version so member accounts cannot alter it, attach a resource-based policy granting bedrock:ApplyGuardrail to the organisation, and name that guardrail ARN and version in a policy attached to the root or an OU. Member-account roles need bedrock:ApplyGuardrail on the guardrail. A guardrail is Regional, so enforcement in three Regions means three guardrails. Where an organisation guardrail, an account-level enforced guardrail and one named in the request all apply, all three run and the most restrictive control wins. Logging is per account and Region to a local S3 bucket or log group, and the organisation-wide view is assembled afterwards.
The self-service vending pattern ties the landscape into something operable. The platform team owns the organisation ceiling, the enforced guardrail, the logging standard, the permission boundary, and a template that stamps out a scoped role plus tagged application inference profiles for a new team. A team requesting access gets the shared configuration applied rather than a hand-built one, which is how governance scales past the dozen teams to the next dozen.
Evaluation
Side by side
| Control | Scope | Restricts which model a principal invokes | Holds even if an account is misconfigured | Attributes cost per team | Central policy and audit |
|---|---|---|---|---|---|
| IAM identity-based policy + permission boundary | Per principal in an account | ✓ | ✗ | ✗ | ✗ |
| Service control policy | Organisation or OU, member accounts only | ✓ (as a deny ceiling) | ✓ | ✗ | ✗ |
| Organizations Amazon Bedrock policy | Organisation, OU or account | ✗ | ✓ | ✗ | ✓ (enforced guardrail) |
| Cost allocation tags + application inference profiles | Per team, per model | ✗ (but scopable by ARN) | ✗ | ✓ | ✗ |
| Model invocation logging | Per account, per Region | ✗ | ✗ | ✗ | ✓ (once aggregated) |
| Service Catalog product + Config custom rules | Vended into every account, checked from the centre | ✗ | ✗ (detects drift, does not prevent it) | ✗ (stamps the tagged profile) | ✓ |
Marketplace model access has no row, because it is no longer something to select: models are on unless a policy denies them. Of the rows that are left, no single one governs the organisation. IAM is fine-grained but lives inside one account and can be misconfigured there. The SCP holds regardless but only ever denies, so it cannot attribute a cost, and it does not reach the management account. The inference profile attributes spend without stopping a wrong call. The Bedrock policy applies one guardrail everywhere and says nothing about who may invoke what. Logging evidences the calls and prevents none of them. The vended product and its Config rules distribute and re-check the other rows without granting or denying anything themselves.
The solution
Least privilege starts from a deny, because the service is open underneath. An SCP on each OU denies the invocation actions for every foundation model ARN outside the approved set, and each team’s role then allows those actions only on the model and inference-profile ARNs the team was approved for. The permission boundary caps the delegation: whatever role a team creates for itself, that role cannot exceed the boundary the platform team attached. Boundary, SCP and identity policy all have to allow an action for it to succeed, so the three compose into one answer rather than three overlapping ones.
The organisation-wide floor is the SCP, and it holds whatever happens inside a member account. Deny statements at the root or an OU take the most expensive models off the table, or fence a regulated OU to an approved set, and because an SCP only removes permission there is no IAM policy a team can write to climb back over it. Two edges are worth knowing. SCPs do not reach the management account, so the platform team’s own account sits outside the ceiling it wrote. And a cross-Region inference profile routes to several destination Regions: if an SCP blocks any one of them, the call fails even where the others are allowed, so a Region-restricting SCP has to allow every destination the chosen profile can reach.
Per-team cost visibility pairs cost allocation tags with application inference profiles. Each team invokes through profiles tagged with its identifier, one per model, and those tags attach to the billing record for each request. Activate the tags in the Billing console ahead of the period finance needs to report on, because tagging is not retroactive and takes up to a day to appear. Cost Explorer and the Cost and Usage Report then break Bedrock spend out by team instead of showing one lump. The profile does double duty: it is the cost-attribution object and, because a policy can be scoped to its ARN, a natural place to pin a team’s access.
Policy and audit are inherited rather than rebuilt, and they arrive by different routes. The guardrail is enforced from the organisation: one versioned guardrail per Region, named in an Amazon Bedrock policy on the root or an OU, applied to every invocation beneath it whether or not a team’s code mentions it. Deleting a guardrail under an enforcement is blocked, so the policy cannot be dropped from below by accident. Logging cannot be centralised the same way, because a logging configuration writes only to a bucket or log group in its own account and Region. Each account logs locally, and the central trail is assembled by replicating those buckets into a log archive account.
The self-service vending pattern is the operating model that carries the rest. The platform team owns the ceiling, the enforced guardrail, the logging standard, the boundary, and a template that stamps out a scoped role and tagged inference profiles per team. Onboarding is then applying the shared configuration rather than hand-building a bespoke one, and the governance holds its shape as the number of teams grows.
From access controls to a governance system
The template deserves a service rather than a wiki page. AWS Service Catalog is where the vetted GenAI blueprint becomes something a team launches: a product holding an inference path, a knowledge base with logging already switched on, and application inference profiles carrying the team’s cost tags. A team launches a governed stack instead of assembling one and hoping it matched the standard. Drift is then caught by re-reading the configuration rather than trusting the launch. GetModelInvocationLoggingConfiguration reports each account’s logging destination, DescribeEffectivePolicy called from a member account shows which guardrail is actually enforced there, and a tag check catches an inference profile recreated without its cost tag. Run those as AWS Config custom rules in a conformance pack and the answer arrives per account instead of on request. The SCP caps what any of those accounts can reach whatever the product deploys.
Regulatory compliance for FM deployments starts by naming what the internal policy answers to. An access control becomes a governance system when it sits inside a framework the organisation has committed to. Each of those frameworks asks for a particular artefact. The EU AI Act sorts a system into a risk tier and wants technical documentation proportionate to that tier. ISO/IEC 42001 is the AI management-system standard an organisation certifies against, 27001’s sibling, and it asks for a management system that runs rather than a document that sits. The NIST AI Risk Management Framework arranges the same ground into govern, map, measure and manage. GDPR and HIPAA apply the moment personal or health data reaches the prompts. Map each ask onto something the platform already produces: the model card for intended use and limitations, the evaluation report for measured behaviour, the invocation log for what was asked and answered, and an Audit Manager assessment for the assembled evidence. That mapping is worth more than the framework text, because it lands a regulator’s request on a service somebody can go and look at. AWS Artifact is the other side of the line and the easiest thing here to mix up. It is where the provider-side attestations come from, AWS’s own SOC reports and ISO certificates, and it evidences nothing about how this organisation used a model.
Ownership is what stops the whole thing becoming a document. Every approved model and every guardrail version carries a named approver and a review date, so adding a model or loosening a filter is a decision somebody signed, and the shortlist and the guardrail get re-read on that cadence rather than when an incident forces the reading.
Worked example
A new team asks for Bedrock access to build a summarisation feature, and requests one of the pricier models for it.
The organisation ceiling is checked first. The SCP on the root already denies the invocation actions for the most expensive models except in named accounts, so the request is either for an already-sanctioned model or for the account to be added to the exception. The platform team judges the standard model sufficient, the deny stays, and no IAM anyone writes in that account undoes it.
Identity comes next through the template. Because every model is reachable by default, the account gets a deny covering everything outside its approved set, plus a role whose policy allows the invocation actions on exactly those model ARNs. The permission boundary lets the team manage its own roles without exceeding that reach. The pricier model is out of range twice over: the root SCP denies it, and so does the account’s own policy.
Cost attribution is wired at the same time. The template creates an application inference profile per approved model, each tagged with the new team’s identifier, and hands over the profile ARNs to invoke through. The tag was activated in the Billing console when the scheme was built, which matters because activation is not retroactive. Within a day the team’s spend appears as its own figure in Cost Explorer rather than blurring into the total.
Policy and audit are inherited. The organisation’s Amazon Bedrock policy already covers the new account, so the enforced guardrail applies from the first call without the team’s code naming it. Invocation logging is switched on in the account, writing to a local bucket that replicates into the log archive. The team is productive in an afternoon, and no governance property depended on a hand-written exception.
What’s worth remembering
- Bedrock is open by default. Models are reachable in commercial Regions; only a Deny on invocation actions, scoped to model ARNs, closes that.
- Scope invocation to model ARNs. Allow specific foundation model or inference-profile ARNs, not the whole service; denying
bedrock:InvokeModelalso blocksConverseandStartAsyncInvoke. - SCPs set the ceiling. They only deny, never grant, no member-account IAM exceeds them, and the management account sits outside.
- Activate cost tags early. Application inference profiles carry the tags, one per model per team; tagging is not retroactive.
- Enforce one guardrail organisation-wide. An AWS Organizations Amazon Bedrock policy names one guardrail version, per Region, for every account beneath it.
- Logging cannot be centralised. Its destination must sit in the same account and Region, so aggregate the logs afterwards.
For the single-application view of these same controls, see securing a Bedrock app across identity, network, keys, and data boundary.