aws_bedrock_user_role_arn turns on per-end-user cost attribution, but the module only consumes an ARN: the role itself, its trust policy and its permission policy are the operator's to write. That is the one piece of the feature nothing in the module or the docs hands over, and it is the piece that is easy to get wrong — the trust policy needs both sts:AssumeRole and sts:TagSession for the task role, and the permission policy needs every ARN shape a cross-region inference profile or a Marketplace model endpoint resolves to. Get either wrong and every model request fails AccessDenied, or the feature silently attributes nothing.
The sandbox already carries a hand-written version of exactly this role, which is evidence that the module should own it.
Proposal
Add aws_bedrock_user_role_create (bool, default false), following the aws_bedrock_batch_role_create / aws_bedrock_batch_role_arn pair already in the module:
- when
true, the module creates a fully managed role — trust policy, permission policy, tags — and wires its ARN into AWS_BEDROCK_USER_ROLE_ARN;
aws_bedrock_user_role_arn keeps taking precedence, so an operator with their own role is unaffected;
- the ARN is published as a
bedrock_user_role_arn output, so a caller can reference it (cost allocation tags, an SCP, a permissions boundary);
aws_bedrock_user_role_require_identity is accepted with either source of the role, not only with an explicit ARN.
Permission scope
The session signs exactly four bedrock-runtime operations (Converse, ConverseStream, InvokeModel, InvokeModelWithResponseStream — USER_ROLE_OPERATIONS in stdapi/aws.py), so the created role grants bedrock:InvokeModel / bedrock:InvokeModelWithResponseStream and only what those invocations evaluate under the session's own identity:
- guardrails applied inline by the invocation;
- the built-in web search tool, with
ExternalWebAccess only when aws_bedrock_external_web_access is on;
sagemaker:InvokeEndpoint* conditioned on aws:CalledViaLast = bedrock.amazonaws.com, only when aws_bedrock_marketplace_endpoints_enabled is on.
Bedrock Mantle, SageMaker AI endpoints, batch inference and every supporting service stay out: they are not bedrock-runtime calls, so they never carry the end user session.
Acceptance criteria
aws_bedrock_user_role_arnturns on per-end-user cost attribution, but the module only consumes an ARN: the role itself, its trust policy and its permission policy are the operator's to write. That is the one piece of the feature nothing in the module or the docs hands over, and it is the piece that is easy to get wrong — the trust policy needs bothsts:AssumeRoleandsts:TagSessionfor the task role, and the permission policy needs every ARN shape a cross-region inference profile or a Marketplace model endpoint resolves to. Get either wrong and every model request failsAccessDenied, or the feature silently attributes nothing.The sandbox already carries a hand-written version of exactly this role, which is evidence that the module should own it.
Proposal
Add
aws_bedrock_user_role_create(bool, defaultfalse), following theaws_bedrock_batch_role_create/aws_bedrock_batch_role_arnpair already in the module:true, the module creates a fully managed role — trust policy, permission policy, tags — and wires its ARN intoAWS_BEDROCK_USER_ROLE_ARN;aws_bedrock_user_role_arnkeeps taking precedence, so an operator with their own role is unaffected;bedrock_user_role_arnoutput, so a caller can reference it (cost allocation tags, an SCP, a permissions boundary);aws_bedrock_user_role_require_identityis accepted with either source of the role, not only with an explicit ARN.Permission scope
The session signs exactly four
bedrock-runtimeoperations (Converse,ConverseStream,InvokeModel,InvokeModelWithResponseStream—USER_ROLE_OPERATIONSinstdapi/aws.py), so the created role grantsbedrock:InvokeModel/bedrock:InvokeModelWithResponseStreamand only what those invocations evaluate under the session's own identity:ExternalWebAccessonly whenaws_bedrock_external_web_accessis on;sagemaker:InvokeEndpoint*conditioned onaws:CalledViaLast = bedrock.amazonaws.com, only whenaws_bedrock_marketplace_endpoints_enabledis on.Bedrock Mantle, SageMaker AI endpoints, batch inference and every supporting service stay out: they are not
bedrock-runtimecalls, so they never carry the end user session.Acceptance criteria
aws_bedrock_user_role_create = truealone produces a working deployment: the server assumes the role at startup with no warning, and a model request is attributed to its end user.aws_bedrock_user_role_arnset together withcreate = trueuses the supplied ARN and creates nothing.bedrock_user_role_arnoutput returns the created ARN, the supplied ARN, ornull.terraform validateandterraform fmt -checkpass; the generatedREADME.mdis regenerated.