Skip to content

Remove actor-based override gating, improve override UX#61

Merged
Alexanderamiri merged 2 commits into
mainfrom
fix/override-approver-cleanup
Mar 14, 2026
Merged

Remove actor-based override gating, improve override UX#61
Alexanderamiri merged 2 commits into
mainfrom
fix/override-approver-cleanup

Conversation

@Alexanderamiri
Copy link
Copy Markdown
Member

Summary

  • Remove override_approvers variable and ForAnyValue:StringEquals actor condition from the ci-override-approver IAM role. GitHub usernames should not be in AWS trust policies — access control is handled by GitHub repo permissions, CODEOWNERS, and environment protection rules.
  • HIGH risk Slack alert now includes a ready-to-copy gh workflow run command with all parameters pre-filled (plan_key, repo, run_id), so the user doesn't have to dig through CI logs to find these values.

Test plan

  • Apply removes actor condition from trust policy
  • Next HIGH risk plan: Slack message includes the gh override command
  • Override workflow can be triggered by anyone with repo write access

… names

CloudTrail event names include version suffixes (e.g. CreateFunction20150331,
DeleteFunction20150331) which didn't match the hardcoded names. Using prefix
matching (Create*, Delete*, Modify*, etc.) scoped by source service catches
all variants without maintaining explicit lists.

Fixes missing Slack alerts for Lambda creation/deletion and other resources.
- Remove override_approvers variable and actor condition from ci-override-approver
  trust policy. Access control is handled by GitHub (repo permissions + CODEOWNERS
  + environment protection rules), not by AWS IAM username matching.
- Move job_workflow_ref to StringLike (consistent with other conditions)
- HIGH risk Slack alert now includes a ready-to-copy gh CLI command with all
  override parameters pre-filled (plan_key, repo, run_id)
@github-actions
Copy link
Copy Markdown

Terraform Plan

Changes detected — review required.

Plan output
Acquiring state lock. This may take a few moments...
module.lambdas.data.archive_file.apply_gate: Reading...
module.lambdas.data.archive_file.compliance_reporter: Reading...
module.lambdas.data.archive_file.override_cleanup: Reading...
module.lambdas.data.archive_file.cost_report: Reading...
module.lambdas.data.archive_file.daily_cost_check: Reading...
module.lambdas.data.archive_file.apply_gate: Read complete after 0s [id=064e560a455ec8b2a30253cd815a820ad002376f]
module.lambdas.data.archive_file.compliance_reporter: Read complete after 0s [id=323449bf04f46a46a9d9c440212010f551146129]
module.lambdas.data.archive_file.password_set: Reading...
module.lambdas.data.archive_file.team_provisioner: Reading...
module.lambdas.data.archive_file.daily_cost_check: Read complete after 0s [id=da9c5f6e85719534eb3d93b02eca8a30fbbfeb34]
module.lambdas.data.archive_file.override_cleanup: Read complete after 0s [id=08e23a8ca152c50d8321f7b9f15d3ebbdc97849d]
module.lambdas.data.archive_file.slack_alert: Reading...
module.lambdas.data.archive_file.cost_report: Read complete after 0s [id=9844b77d6a3a4efa27510589543ad38c835cc662]
module.lambdas.data.archive_file.password_set: Read complete after 0s [id=e8642f74f5c1054e7105a8b6834ee7508b1f30c1]
module.lambdas.data.archive_file.team_provisioner: Read complete after 0s [id=2c3923c60cf0a4be10a515c74f37b631cb2be676]
module.lambdas.data.archive_file.slack_alert: Read complete after 0s [id=4e0e1617392370ce9f1308884a7e0d9636829292]
module.monitoring.aws_sns_topic.alerts: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-alerts]
module.lambdas.aws_cloudwatch_event_rule.cost_report_schedule: Refreshing state... [id=javabin-cost-report-schedule]
module.lambdas.aws_iam_role.override_cleanup: Refreshing state... [id=javabin-override-cleanup]
module.monitoring.aws_cloudwatch_event_rule.guardduty_findings: Refreshing state... [id=javabin-guardduty-findings]
module.identity.aws_cognito_user_pool.internal: Refreshing state... [id=eu-central-1_Icikv3dtD]
module.lambdas.aws_iam_role.compliance_reporter: Refreshing state... [id=javabin-compliance-reporter]
module.monitoring.aws_sns_topic.security: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-security]
module.monitoring.aws_dynamodb_table.alert_dedup: Refreshing state... [id=javabin-alert-dedup]
module.monitoring.aws_ce_anomaly_monitor.main: Refreshing state... [id=arn:aws:ce::553637109631:anomalymonitor/3609b3f1-c834-444e-a218-02ac6da1cb4d]
module.iam.aws_iam_policy.developer_boundary: Refreshing state... [id=arn:aws:iam::553637109631:policy/javabin-developer-boundary]
module.lambdas.aws_cloudwatch_event_rule.override_cleanup_schedule: Refreshing state... [id=javabin-override-cleanup-schedule]
module.networking.aws_eip.nat: Refreshing state... [id=eipalloc-0764f0a1a3c80dce1]
module.monitoring.aws_cloudwatch_event_rule.console_login: Refreshing state... [id=javabin-console-login]
module.monitoring.aws_cloudwatch_event_rule.config_compliance: Refreshing state... [id=javabin-config-compliance-change]
module.lambdas.aws_iam_role.password_set: Refreshing state... [id=javabin-password-set]
module.lambdas.aws_iam_role.cost_report: Refreshing state... [id=javabin-cost-report]
module.lambdas.aws_iam_role.team_provisioner: Refreshing state... [id=javabin-team-provisioner]
module.monitoring.aws_cloudwatch_event_rule.securityhub_findings: Refreshing state... [id=javabin-securityhub-findings]
module.iam.aws_iam_role.ecs_execution: Refreshing state... [id=javabin-ecs-execution]
module.monitoring.aws_cloudwatch_event_rule.resource_creation: Refreshing state... [id=javabin-resource-creation]
module.monitoring.aws_iam_role.config_role: Refreshing state... [id=javabin-config-role]
module.lambdas.aws_cloudwatch_event_rule.compliance_reporter_trigger: Refreshing state... [id=javabin-compliance-reporter-trigger]
module.ingress.data.aws_route53_zone.main: Reading...
module.identity.aws_cognito_user_pool.external: Refreshing state... [id=eu-central-1_gdFOsE4EM]
module.lambdas.aws_iam_role.daily_cost_check: Refreshing state... [id=javabin-daily-cost-check]
module.ingress.aws_acm_certificate.wildcard: Refreshing state... [id=arn:aws:acm:eu-central-1:553637109631:certificate/9b79f56a-3719-4c62-8970-6f08985a7e5b]
module.lambdas.aws_cloudwatch_event_rule.securityhub_summary_schedule: Refreshing state... [id=javabin-securityhub-summary-schedule]
module.compute.aws_ecr_repository.ci["jvm"]: Refreshing state... [id=javabin-ci-jvm]
module.compute.aws_ecr_repository.ci["platform"]: Refreshing state... [id=javabin-ci-platform]
module.compute.aws_ecr_repository.ci["ts"]: Refreshing state... [id=javabin-ci-ts]
module.networking.aws_vpc.main: Refreshing state... [id=vpc-0cd3502de2527a310]
module.networking.data.aws_availability_zones.available: Reading...
module.iam.data.aws_iam_openid_connect_provider.github: Reading...
module.lambdas.aws_iam_role.slack_alert: Refreshing state... [id=javabin-slack-alert]
module.iam.data.aws_iam_openid_connect_provider.github: Read complete after 0s [id=arn:aws:iam::553637109631:oidc-provider/token.actions.githubusercontent.com]
module.compute.aws_ecs_cluster.main: Refreshing state... [id=arn:aws:ecs:eu-central-1:553637109631:cluster/javabin-platform]
module.networking.data.aws_availability_zones.available: Read complete after 0s [id=eu-central-1]
module.lambdas.aws_cloudwatch_event_rule.daily_cost_check_schedule: Refreshing state... [id=javabin-daily-cost-check-schedule]
module.monitoring.aws_s3_bucket.config_logs: Refreshing state... [id=javabin-config-553637109631]
module.monitoring.aws_cloudwatch_event_rule.resource_modification: Refreshing state... [id=javabin-resource-modification]
module.monitoring.aws_securityhub_account.main: Refreshing state... [id=553637109631]
module.monitoring.aws_cloudwatch_event_rule.iam_changes: Refreshing state... [id=javabin-iam-changes]
module.monitoring.aws_guardduty_detector.main: Refreshing state... [id=f1df02cf279e4b5986ce1e9bcb3af9c5]
module.lambdas.aws_iam_role.apply_gate: Refreshing state... [id=javabin-apply-gate]
module.lambdas.aws_iam_role_policy_attachment.compliance_reporter_logs: Refreshing state... [id=javabin-compliance-reporter-20260307162857302300000005]
module.lambdas.aws_lambda_function.compliance_reporter: Refreshing state... [id=javabin-compliance-reporter]
module.lambdas.aws_iam_role_policy.compliance_reporter: Refreshing state... [id=javabin-compliance-reporter:javabin-compliance-reporter]
module.lambdas.aws_iam_role_policy.override_cleanup: Refreshing state... [id=javabin-override-cleanup:javabin-override-cleanup]
module.ingress.data.aws_route53_zone.main: Read complete after 1s [id=Z09335963LMV0Z5QB9L45]
module.lambdas.aws_lambda_function.override_cleanup: Refreshing state... [id=javabin-override-cleanup]
module.lambdas.aws_iam_role_policy_attachment.override_cleanup_logs: Refreshing state... [id=javabin-override-cleanup-20260307162858005200000007]
module.monitoring.aws_sns_topic_policy.security: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-security]
module.monitoring.aws_ce_anomaly_subscription.alerts: Refreshing state... [id=arn:aws:ce::553637109631:anomalysubscription/f6b079c9-5174-43b7-85f3-dde533995482]
module.monitoring.aws_sns_topic_policy.alerts: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-alerts]
module.identity.aws_cognito_user_pool_domain.internal: Refreshing state... [id=javabin-internal]
module.monitoring.aws_cloudwatch_event_target.guardduty_findings_sns: Refreshing state... [id=javabin-guardduty-findings-send-to-security-sns]
module.lambdas.aws_iam_role_policy_attachment.password_set_logs: Refreshing state... [id=javabin-password-set-20260313225356475100000001]
module.monitoring.aws_cloudwatch_event_target.console_login_sns: Refreshing state... [id=javabin-console-login-send-to-security-sns]
module.lambdas.aws_iam_role_policy_attachment.cost_report_logs: Refreshing state... [id=javabin-cost-report-20260307162857662100000006]
module.lambdas.aws_lambda_function.cost_report: Refreshing state... [id=javabin-cost-report]
module.lambdas.aws_iam_role_policy.cost_report: Refreshing state... [id=javabin-cost-report:javabin-cost-report]
module.monitoring.aws_cloudwatch_event_target.config_compliance_sns: Refreshing state... [id=javabin-config-compliance-change-send-to-security-sns]
module.monitoring.aws_cloudwatch_event_target.securityhub_findings_sns: Refreshing state... [id=javabin-securityhub-findings-send-to-security-sns]
module.lambdas.aws_iam_role_policy_attachment.team_provisioner_logs: Refreshing state... [id=javabin-team-provisioner-20260307162856464600000003]
module.monitoring.aws_cloudwatch_event_target.resource_creation_sns: Refreshing state... [id=javabin-resource-creation-send-to-security-sns]
module.monitoring.aws_config_configuration_recorder.main: Refreshing state... [id=javabin-recorder]
module.monitoring.aws_iam_role_policy_attachment.config_role: Refreshing state... [id=javabin-config-role-20260307162900971300000009]
module.iam.aws_iam_role_policy.ecs_execution_secrets: Refreshing state... [id=javabin-ecs-execution:secrets-read]
module.iam.aws_iam_role_policy_attachment.ecs_execution_base: Refreshing state... [id=javabin-ecs-execution-20260307162856804400000004]
module.lambdas.aws_iam_role_policy_attachment.daily_cost_check_logs: Refreshing state... [id=javabin-daily-cost-check-20260307162856210400000002]
module.lambdas.aws_lambda_function.daily_cost_check: Refreshing state... [id=javabin-daily-cost-check]
module.lambdas.aws_iam_role_policy.daily_cost_check: Refreshing state... [id=javabin-daily-cost-check:javabin-daily-cost-check]
module.iam.aws_iam_role.ci_override_approver: Refreshing state... [id=javabin-ci-override-approver]
module.iam.aws_iam_role.ci_registry: Refreshing state... [id=javabin-ci-registry]
module.iam.aws_iam_role.ci_apply_gate: Refreshing state... [id=javabin-ci-apply-gate]
module.iam.aws_iam_role.ci_infra_plan: Refreshing state... [id=javabin-ci-infra-plan]
module.iam.aws_iam_role.ci_deploy["platform-test-app"]: Refreshing state... [id=javabin-ci-deploy-platform-test-app]
module.iam.aws_iam_role.ci_infra: Refreshing state... [id=javabin-ci-infra]
module.lambdas.aws_iam_role_policy_attachment.slack_alert_logs: Refreshing state... [id=javabin-slack-alert-20260307162858376500000008]
module.compute.aws_ecr_lifecycle_policy.ci["platform"]: Refreshing state... [id=javabin-ci-platform]
module.compute.aws_ecr_lifecycle_policy.ci["jvm"]: Refreshing state... [id=javabin-ci-jvm]
module.compute.aws_ecr_lifecycle_policy.ci["ts"]: Refreshing state... [id=javabin-ci-ts]
module.monitoring.aws_cloudwatch_event_target.resource_modification_sns: Refreshing state... [id=javabin-resource-modification-send-to-security-sns]
module.compute.aws_ecs_cluster_capacity_providers.main: Refreshing state... [id=javabin-platform]
module.ingress.aws_route53_record.acm_validation["*.javazone.no"]: Refreshing state... [id=Z09335963LMV0Z5QB9L45__b68529ef50ff68d6cf320ff0e9c5c80a.javazone.no._CNAME]
module.monitoring.aws_cloudwatch_event_target.iam_changes_sns: Refreshing state... [id=javabin-iam-changes-send-to-security-sns]
module.lambdas.aws_iam_role_policy.apply_gate: Refreshing state... [id=javabin-apply-gate:javabin-apply-gate]
module.lambdas.aws_iam_role_policy_attachment.apply_gate_logs: Refreshing state... [id=javabin-apply-gate-20260310000556680800000001]
module.lambdas.aws_lambda_function.apply_gate: Refreshing state... [id=javabin-apply-gate]
module.monitoring.aws_securityhub_standards_subscription.aws_foundational: Refreshing state... [id=arn:aws:securityhub:eu-central-1:553637109631:subscription/aws-foundational-security-best-practices/v/1.0.0]
module.monitoring.aws_guardduty_detector_feature.runtime_monitoring: Refreshing state... [id=f1df02cf279e4b5986ce1e9bcb3af9c5/RUNTIME_MONITORING]
module.networking.aws_subnet.public_b: Refreshing state... [id=subnet-0eb818326ee94a266]
module.networking.aws_internet_gateway.main: Refreshing state... [id=igw-07b193bea823a7f69]
module.networking.aws_subnet.private_a: Refreshing state... [id=subnet-0329ad20dc025c693]
module.networking.aws_security_group.ecs_tasks: Refreshing state... [id=sg-0df9a0a3a22548c62]
module.networking.aws_subnet.private_b: Refreshing state... [id=subnet-09ee21336f809f3c9]
module.networking.aws_security_group.alb: Refreshing state... [id=sg-061000c0fa68a41b7]
module.networking.aws_subnet.public_a: Refreshing state... [id=subnet-0f6bfec917146b856]
module.lambdas.aws_cloudwatch_event_target.override_cleanup: Refreshing state... [id=javabin-override-cleanup-schedule-invoke-override-cleanup]
module.lambdas.aws_lambda_permission.override_cleanup_schedule: Refreshing state... [id=AllowEventBridge]
module.lambdas.aws_cloudwatch_event_target.compliance_reporter: Refreshing state... [id=javabin-compliance-reporter-trigger-invoke-compliance-reporter]
module.lambdas.aws_lambda_permission.compliance_reporter_eventbridge: Refreshing state... [id=AllowEventBridge]
module.lambdas.aws_cloudwatch_event_target.cost_report: Refreshing state... [id=javabin-cost-report-schedule-invoke-cost-report]
module.lambdas.aws_lambda_permission.cost_report_schedule: Refreshing state... [id=AllowEventBridge]
module.iam.aws_iam_role_policy.ci_override_approver: Refreshing state... [id=javabin-ci-override-approver:invoke-apply-gate]
module.iam.aws_iam_role_policy.ci_registry: Refreshing state... [id=javabin-ci-registry:registry-operations]
module.iam.aws_iam_role_policy.ci_apply_gate: Refreshing state... [id=javabin-ci-apply-gate:invoke-gate-and-read-plans]
module.iam.aws_iam_role_policy_attachment.ci_infra_plan_readonly: Refreshing state... [id=javabin-ci-infra-plan-20260312151931668600000001]
module.iam.aws_iam_role_policy.ci_infra_plan_extras: Refreshing state... [id=javabin-ci-infra-plan:plan-specific-writes]
module.monitoring.aws_config_config_rule.required_tags: Refreshing state... [id=javabin-required-tags]
module.lambdas.aws_lambda_permission.daily_cost_check_schedule: Refreshing state... [id=AllowEventBridge]
module.lambdas.aws_cloudwatch_event_target.daily_cost_check: Refreshing state... [id=javabin-daily-cost-check-schedule-invoke-daily-cost-check]
module.lambdas.aws_iam_role_policy.slack_alert: Refreshing state... [id=javabin-slack-alert:javabin-slack-alert]
module.lambdas.aws_iam_role_policy.team_provisioner: Refreshing state... [id=javabin-team-provisioner:javabin-team-provisioner]
module.lambdas.aws_lambda_function.securityhub_summary: Refreshing state... [id=javabin-securityhub-summary]
module.lambdas.aws_lambda_function.slack_alert: Refreshing state... [id=javabin-slack-alert]
module.lambdas.aws_lambda_function.team_provisioner: Refreshing state... [id=javabin-team-provisioner]
module.iam.aws_iam_role_policy.ci_infra_deny: Refreshing state... [id=javabin-ci-infra:deny-dangerous-operations]
module.iam.aws_iam_role_policy.ci_infra_allow: Refreshing state... [id=javabin-ci-infra:infra-management]
module.iam.aws_iam_role_policy.ci_deploy_ssm["platform-test-app"]: Refreshing state... [id=javabin-ci-deploy-platform-test-app:ssm-read-overrides]
module.iam.aws_iam_role_policy.ci_deploy_ecr["platform-test-app"]: Refreshing state... [id=javabin-ci-deploy-platform-test-app:ecr-push]
module.iam.aws_iam_role_policy.ci_deploy_ecs["platform-test-app"]: Refreshing state... [id=javabin-ci-deploy-platform-test-app:ecs-deploy]
module.iam.aws_iam_role_policy.ci_deploy_logs["platform-test-app"]: Refreshing state... [id=javabin-ci-deploy-platform-test-app:cloudwatch-logs]
module.ingress.aws_acm_certificate_validation.wildcard: Refreshing state... [id=2026-03-07 16:29:14.551 +0000 UTC]
module.networking.aws_route_table.public: Refreshing state... [id=rtb-01c9642f019d36b1f]
module.networking.aws_vpc_security_group_egress_rule.ecs_all: Refreshing state... [id=sgr-0266cfa56e8feab14]
module.networking.aws_vpc_security_group_ingress_rule.alb_https: Refreshing state... [id=sgr-00b490b07c35193b7]
module.networking.aws_vpc_security_group_ingress_rule.ecs_from_alb: Refreshing state... [id=sgr-064d01025000f601e]
module.networking.aws_vpc_security_group_ingress_rule.alb_http: Refreshing state... [id=sgr-07c58f16ef7496031]
module.networking.aws_vpc_security_group_egress_rule.alb_all: Refreshing state... [id=sgr-021faee81305c6e28]
module.networking.aws_nat_gateway.main: Refreshing state... [id=nat-0e9cc9e27cc6598db]
module.iam.aws_iam_role.ci_app["platform-test-app"]: Refreshing state... [id=javabin-ci-app-platform-test-app]
module.monitoring.aws_s3_bucket_policy.config_logs: Refreshing state... [id=javabin-config-553637109631]
module.monitoring.aws_config_delivery_channel.main: Refreshing state... [id=javabin-config-channel]
module.monitoring.aws_s3_bucket_public_access_block.config_logs: Refreshing state... [id=javabin-config-553637109631]
module.monitoring.aws_s3_bucket_server_side_encryption_configuration.config_logs: Refreshing state... [id=javabin-config-553637109631]
module.networking.aws_route_table_association.public_a: Refreshing state... [id=rtbassoc-07ff2e0bfa1578067]
module.networking.aws_route_table_association.public_b: Refreshing state... [id=rtbassoc-0186c3a7f0279e344]
module.monitoring.aws_config_configuration_recorder_status.main: Refreshing state... [id=javabin-recorder]
module.ingress.aws_lb.main: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:553637109631:loadbalancer/app/javabin-platform-alb/bec1dd43ab8341b9]
module.networking.aws_route_table.private: Refreshing state... [id=rtb-0b0b4c643592a7db0]
module.lambdas.aws_cloudwatch_event_target.securityhub_summary: Refreshing state... [id=javabin-securityhub-summary-schedule-invoke-securityhub-summary]
module.lambdas.aws_lambda_permission.securityhub_summary_schedule: Refreshing state... [id=AllowEventBridge]
module.lambdas.aws_lambda_permission.slack_alert_security: Refreshing state... [id=AllowSNSSecurity]
module.lambdas.aws_sns_topic_subscription.slack_alert_alerts: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-alerts:380384a2-0cac-48c9-b2d9-2a0aae6968cd]
module.lambdas.aws_lambda_permission.slack_alert_alerts: Refreshing state... [id=AllowSNSAlerts]
module.lambdas.aws_sns_topic_subscription.slack_alert_security: Refreshing state... [id=arn:aws:sns:eu-central-1:553637109631:javabin-security:0bda8a22-7a50-4a9d-9285-6b1fc1f75376]
module.lambdas.aws_iam_role_policy.password_set: Refreshing state... [id=javabin-password-set:javabin-password-set]
module.lambdas.aws_lambda_function.password_set: Refreshing state... [id=javabin-password-set]
module.networking.aws_route_table_association.private_b: Refreshing state... [id=rtbassoc-005259f36758e089e]
module.networking.aws_route_table_association.private_a: Refreshing state... [id=rtbassoc-0b9248495de9f7316]
module.iam.aws_iam_role_policy.ci_app_allow["platform-test-app"]: Refreshing state... [id=javabin-ci-app-platform-test-app:app-management]
module.iam.aws_iam_role_policy.ci_app_deny["platform-test-app"]: Refreshing state... [id=javabin-ci-app-platform-test-app:deny-platform-operations]
module.lambdas.aws_lambda_function_url.password_set: Refreshing state... [id=javabin-password-set]
module.lambdas.aws_ssm_parameter.password_set_function_url: Refreshing state... [id=/javabin/platform/password-set-function-url]
module.ingress.aws_lb_listener.https: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:553637109631:listener/app/javabin-platform-alb/bec1dd43ab8341b9/500c9c2b4186bf45]
module.ingress.aws_lb_listener.http_redirect: Refreshing state... [id=arn:aws:elasticloadbalancing:eu-central-1:553637109631:listener/app/javabin-platform-alb/bec1dd43ab8341b9/1d92e19ae75aa59b]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the
last "terraform apply" which may have affected this plan:

  # module.lambdas.aws_lambda_function_url.password_set has changed
  ~ resource "aws_lambda_function_url" "password_set" {
      ~ function_url       = "https://hrcuyrxkdzvhl5fxt6nr4plqei0xzjps.lambda-url.eu-central-1.on.aws/" -> "https://6tipbbhnybegaul4jyvyldgm7a0memtj.lambda-url.eu-central-1.on.aws/"
        id                 = "javabin-password-set"
        # (5 unchanged attributes hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the
relevant attributes using ignore_changes, the following plan may include
actions to undo or respond to these changes.

─────────────────────────────────────────────────────────────────────────────

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
  ~ update in-place

Terraform will perform the following actions:

  # module.iam.aws_iam_role.ci_override_approver will be updated in-place
  ~ resource "aws_iam_role" "ci_override_approver" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Condition = {
                          - "ForAnyValue:StringEquals" = {
                              - "token.actions.githubusercontent.com:actor" = [
                                  - "alexander-amiri",
                                ]
                            }
                          ~ StringEquals               = {
                              - "token.actions.githubusercontent.com:job_workflow_ref" = "javaBin/platform/.github/workflows/approve-override.yml@refs/heads/main"
                                # (1 unchanged attribute hidden)
                            }
                          ~ StringLike                 = {
                              + "token.actions.githubusercontent.com:job_workflow_ref" = "javaBin/platform/.github/workflows/approve-override.yml@refs/heads/main"
                                # (1 unchanged attribute hidden)
                            }
                        }
                        # (3 unchanged attributes hidden)
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        id                    = "javabin-ci-override-approver"
        name                  = "javabin-ci-override-approver"
        tags                  = {
            "Name" = "javabin-ci-override-approver"
        }
        # (9 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # module.lambdas.aws_cloudwatch_event_rule.compliance_reporter_trigger will be updated in-place
  ~ resource "aws_cloudwatch_event_rule" "compliance_reporter_trigger" {
      ~ event_pattern  = jsonencode(
          ~ {
              ~ detail      = {
                  ~ eventName = [
                      - "CreateBucket",
                      - "RunInstances",
                      - "CreateDBInstance",
                      - "CreateService",
                      - "CreateFunction20150331",
                      - "CreateLoadBalancer",
                      - "CreateSecurityGroup",
                      - "CreateNatGateway",
                      - "CreateVpc",
                      - "CreateSubnet",
                      - "CreateTargetGroup",
                      + {
                          + prefix = "Create"
                        },
                      + {
                          + prefix = "Run"
                        },
                    ]
                }
                # (2 unchanged attributes hidden)
            }
        )
        id             = "javabin-compliance-reporter-trigger"
        name           = "javabin-compliance-reporter-trigger"
        tags           = {}
        # (7 unchanged attributes hidden)
    }

  # module.lambdas.aws_lambda_permission.password_set_public_invoke will be created
  + resource "aws_lambda_permission" "password_set_public_invoke" {
      + action              = "lambda:InvokeFunction"
      + function_name       = "javabin-password-set"
      + id                  = (known after apply)
      + principal           = "*"
      + statement_id        = "AllowPublicInvoke"
      + statement_id_prefix = (known after apply)
    }

  # module.lambdas.aws_lambda_permission.password_set_public_url will be created
  + resource "aws_lambda_permission" "password_set_public_url" {
      + action                 = "lambda:InvokeFunctionUrl"
      + function_name          = "javabin-password-set"
      + function_url_auth_type = "NONE"
      + id                     = (known after apply)
      + principal              = "*"
      + statement_id           = "FunctionURLAllowPublicAccess"
      + statement_id_prefix    = (known after apply)
    }

  # module.monitoring.aws_cloudwatch_event_rule.iam_changes will be updated in-place
  ~ resource "aws_cloudwatch_event_rule" "iam_changes" {
      ~ event_pattern  = jsonencode(
          ~ {
              ~ detail      = {
                  ~ eventName   = [
                      - "CreateRole",
                      - "DeleteRole",
                      - "PutRolePolicy",
                      - "AttachRolePolicy",
                      - "DetachRolePolicy",
                      - "DeleteRolePolicy",
                      - "CreatePolicy",
                      - "DeletePolicy",
                      + {
                          + prefix = "Create"
                        },
                      + {
                          + prefix = "Delete"
                        },
                      + {
                          + prefix = "Put"
                        },
                      + {
                          + prefix = "Attach"
                        },
                      + {
                          + prefix = "Detach"
                        },
                    ]
                    # (1 unchanged attribute hidden)
                }
                # (2 unchanged attributes hidden)
            }
        )
        id             = "javabin-iam-changes"
        name           = "javabin-iam-changes"
        tags           = {}
        # (7 unchanged attributes hidden)
    }

  # module.monitoring.aws_cloudwatch_event_rule.resource_creation will be updated in-place
  ~ resource "aws_cloudwatch_event_rule" "resource_creation" {
      ~ event_pattern  = jsonencode(
          ~ {
              ~ detail      = {
                  ~ eventName = [
                      - "CreateBucket",
                      - "RunInstances",
                      - "CreateDBInstance",
                      - "CreateService",
                      - "CreateFunction",
                      - "CreateQueue",
                      - "CreateTable",
                      - "CreateLoadBalancer",
                      + {
                          + prefix = "Create"
                        },
                      + {
                          + prefix = "Run"
                        },
                    ]
                }
                # (2 unchanged attributes hidden)
            }
        )
        id             = "javabin-resource-creation"
        name           = "javabin-resource-creation"
        tags           = {}
        # (7 unchanged attributes hidden)
    }

  # module.monitoring.aws_cloudwatch_event_rule.resource_modification will be updated in-place
  ~ resource "aws_cloudwatch_event_rule" "resource_modification" {
      ~ event_pattern  = jsonencode(
          ~ {
              ~ detail      = {
                  ~ eventName = [
                      - "ModifyDBInstance",
                      - "DeleteBucket",
                      - "StopInstances",
                      - "TerminateInstances",
                      - "DeleteService",
                      - "DeleteFunction",
                      + {
                          + prefix = "Modify"
                        },
                      + {
                          + prefix = "Update"
                        },
                      + {
                          + prefix = "Delete"
                        },
                      + {
                          + prefix = "Stop"
                        },
                      + {
                          + prefix = "Terminate"
                        },
                    ]
                }
                # (2 unchanged attributes hidden)
            }
        )
        id             = "javabin-resource-modification"
        name           = "javabin-resource-modification"
        tags           = {}
        # (7 unchanged attributes hidden)
    }

Plan: 2 to add, 5 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

@github-actions
Copy link
Copy Markdown

LLM Plan Review

Risk: 🔴 HIGH

Plan exposes password-set Lambda function to public internet with no authentication, creating a critical security vulnerability.

  • 🔒 [security] Creating aws_lambda_permission.password_set_public_invoke and password_set_public_url with principal='*' and function_url_auth_type='NONE' exposes the password-set Lambda to unauthenticated public access. This is a critical security risk for a sensitive function.
  • 🔒 [security] EventBridge rules are being refactored from explicit event names to prefix-based matching (e.g., 'CreateBucket' → {prefix: 'Create'}). While more flexible, this broadens event capture scope and could trigger on unintended operations if not carefully monitored.
  • 🔒 [security] IAM role ci_override_approver is being modified to change condition logic from ForAnyValue:StringEquals to StringLike for job_workflow_ref. This relaxes the workflow reference matching and could allow unintended GitHub Actions workflows to assume this role.
  • [routine] Lambda function URL for password_set has changed outside Terraform (detected drift). Plan will reconcile this state change.
  • [routine] EventBridge rule updates are configuration-only changes with no resource destruction or data loss.

@Alexanderamiri Alexanderamiri merged commit 5c69c39 into main Mar 14, 2026
3 checks passed
@Alexanderamiri Alexanderamiri deleted the fix/override-approver-cleanup branch March 14, 2026 00:06
Alexanderamiri added a commit that referenced this pull request May 9, 2026
## Summary
- **Remove `override_approvers`** variable and
`ForAnyValue:StringEquals` actor condition from the
`ci-override-approver` IAM role. GitHub usernames should not be in AWS
trust policies — access control is handled by GitHub repo permissions,
CODEOWNERS, and environment protection rules.
- **HIGH risk Slack alert** now includes a ready-to-copy `gh workflow
run` command with all parameters pre-filled (plan_key, repo, run_id), so
the user doesn't have to dig through CI logs to find these values.

## Test plan
- [ ] Apply removes actor condition from trust policy
- [ ] Next HIGH risk plan: Slack message includes the `gh` override
command
- [ ] Override workflow can be triggered by anyone with repo write
access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant