Once you have a VPC interface endpoint for Bedrock, you get a second, network-attached place to enforce access rules. A VPC endpoint policy is a resource policy attached to the endpoint itself: every request passing through must be allowed by the endpoint policy and by the caller's IAM permissions. AWS documents that custom endpoint policies can scope which actions are allowed through each Bedrock endpoint — this article covers how enterprises typically use that.
Why bother, if IAM already controls access?
Because the two layers answer different questions. IAM answers "what may this identity do, from anywhere?" The endpoint policy answers "what may pass through this network path, regardless of identity?" That second control is valuable in three situations: contractors or workloads in the VPC whose IAM policies you do not fully control; defense in depth against over-broad IAM grants; and audit conversations where "only these two actions on these three models can physically transit our network boundary" is a satisfying sentence.
Scope the actions to the endpoint's surface
Each Bedrock endpoint service has its own action namespace, and the policy should match it. AWS's documented examples: for the bedrock-runtime endpoint, allow bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream; for the bedrock-mantle endpoint (the newer "Claude in Amazon Bedrock" surface), the action is bedrock-mantle:CreateInference. If your teams use the Converse APIs on the runtime surface, include bedrock:Converse and bedrock:ConverseStream as well — or use the bedrock:InvokeModel* wildcard pattern deliberately rather than by accident.
Scope the models with resource ARNs
Bedrock exposes foundation models as ARNs (Amazon Resource Names) you can list in the policy's Resource element. The documented format is arn:aws:bedrock:*::foundation-model/{model-id} — for the current Claude generation on Bedrock, model IDs carry the anthropic. prefix, such as anthropic.claude-sonnet-5 or anthropic.claude-opus-4-8. One important subtlety: if callers invoke Claude through a cross-region inference profile rather than a bare model ID, the request needs the inference-profile ARN (arn:aws:bedrock:{region}:{account-id}:inference-profile/*) allowed in addition to the foundation-model ARNs, per AWS's IAM policy examples. Endpoint policies that list only foundation-model ARNs will quietly break profile-based invocation.
A minimal endpoint policy for a runtime endpoint that admits one application role and two Claude models looks like this:
{
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/claims-triage-app"},
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": [
"arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-5",
"arn:aws:bedrock:*::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0"
]
}]
}
Adapt the principal list to your account structure — many teams allow all principals from their own account and rely on IAM for identity-level restriction, using the endpoint policy purely for action and model scoping.
What endpoint policies cannot do
They only govern traffic through that endpoint. A credentialed principal calling Bedrock's public endpoint from outside the VPC is untouched by them — blocking that requires IAM or service control policies (SCPs), for instance an explicit deny on bedrock:InvokeModel for unapproved models. AWS notes specifically that denying Marketplace subscription actions or deleting a model agreement does not reliably block model use; the deny must land on the invocation actions themselves. Also remember the control-plane endpoint (com.amazonaws.{region}.bedrock) is a separate service with separate actions — a runtime endpoint policy says nothing about who can change logging or guardrail configuration.
Where to go next
Combine this with network-layer controls and identity-side rules in Bedrock IAM setup. For organization-wide guardrails, see SCP controls for Bedrock.