diff --git a/scripts/extract-review-risk.sh b/scripts/extract-review-risk.sh index 36b3eb1..286c74e 100644 --- a/scripts/extract-review-risk.sh +++ b/scripts/extract-review-risk.sh @@ -21,3 +21,8 @@ fi echo "risk_level=${RISK}" >> "$GITHUB_OUTPUT" echo "LLM review risk: ${RISK}" + +if [ "$RISK" = "FAILED" ]; then + echo "LLM review failed — blocking pipeline." + exit 1 +fi diff --git a/terraform/platform/iam/main.tf b/terraform/platform/iam/main.tf index 1d7f6b2..99cd8c8 100644 --- a/terraform/platform/iam/main.tf +++ b/terraform/platform/iam/main.tf @@ -94,7 +94,7 @@ resource "aws_iam_role_policy" "ci_infra_plan_extras" { Resource = "arn:aws:s3:::${var.project}-ci-plan-artifacts-${var.aws_account_id}/*" }, { - Sid = "BedrockForReview" + Sid = "BedrockInferenceProfile" Effect = "Allow" Action = [ "bedrock:InvokeModel", @@ -102,6 +102,23 @@ resource "aws_iam_role_policy" "ci_infra_plan_extras" { ] Resource = "arn:aws:bedrock:${var.region}:${var.aws_account_id}:inference-profile/eu.anthropic.*" }, + { + # Cross-region inference profiles route to foundation models in EU + # destination regions. IAM requires access to destination model ARNs. + # Condition scopes this to only work via our inference profiles. + Sid = "BedrockFoundationModels" + Effect = "Allow" + Action = [ + "bedrock:InvokeModel", + "bedrock:Converse", + ] + Resource = "arn:aws:bedrock:eu-*::foundation-model/anthropic.*" + Condition = { + StringLike = { + "bedrock:InferenceProfileArn" = "arn:aws:bedrock:${var.region}:${var.aws_account_id}:inference-profile/eu.anthropic.*" + } + } + }, { Sid = "SSMReadSlackWebhook" Effect = "Allow" diff --git a/terraform/platform/lambdas/main.tf b/terraform/platform/lambdas/main.tf index 354c395..716c61c 100644 --- a/terraform/platform/lambdas/main.tf +++ b/terraform/platform/lambdas/main.tf @@ -6,6 +6,11 @@ locals { lambda_src_path = "${path.module}/../../lambda-src" github_org_url = "https://github.com/javaBin" + + # EU cross-region inference profiles route to any eu-* region. + # IAM requires foundation model access in destination regions. + bedrock_eu_foundation_model_arns = "arn:aws:bedrock:eu-*::foundation-model/anthropic.*" + bedrock_inference_profile_arn = "arn:aws:bedrock:${var.region}:${var.aws_account_id}:inference-profile/eu.anthropic.*" } ################################################################################ @@ -159,13 +164,21 @@ resource "aws_iam_role_policy" "slack_alert" { ] }, { - Sid = "Bedrock" - Effect = "Allow" - Action = [ - "bedrock:InvokeModel", - "bedrock:Converse", - ] - Resource = "arn:aws:bedrock:${var.region}:${var.aws_account_id}:inference-profile/eu.anthropic.*" + Sid = "BedrockInferenceProfile" + Effect = "Allow" + Action = ["bedrock:InvokeModel", "bedrock:Converse"] + Resource = local.bedrock_inference_profile_arn + }, + { + Sid = "BedrockFoundationModels" + Effect = "Allow" + Action = ["bedrock:InvokeModel", "bedrock:Converse"] + Resource = local.bedrock_eu_foundation_model_arns + Condition = { + StringLike = { + "bedrock:InferenceProfileArn" = local.bedrock_inference_profile_arn + } + } }, { Sid = "PricingRead" @@ -236,13 +249,21 @@ resource "aws_iam_role_policy" "cost_report" { Resource = "*" }, { - Sid = "Bedrock" - Effect = "Allow" - Action = [ - "bedrock:InvokeModel", - "bedrock:Converse", - ] - Resource = "arn:aws:bedrock:${var.region}:${var.aws_account_id}:inference-profile/eu.anthropic.*" + Sid = "BedrockInferenceProfile" + Effect = "Allow" + Action = ["bedrock:InvokeModel", "bedrock:Converse"] + Resource = local.bedrock_inference_profile_arn + }, + { + Sid = "BedrockFoundationModels" + Effect = "Allow" + Action = ["bedrock:InvokeModel", "bedrock:Converse"] + Resource = local.bedrock_eu_foundation_model_arns + Condition = { + StringLike = { + "bedrock:InferenceProfileArn" = local.bedrock_inference_profile_arn + } + } }, ] })