Skip to content

🔒 ASH Security Scan - Monthly Report (2026-09-01) #183

Description

@github-actions

ASH Security Scan - Full Repository Report

Scan Date: 2026-09-01T02:26:21+00:00
Trigger: schedule
Type: Monthly scheduled scan

Scanner Results Summary

Scanner S C H M L I Time Action Result Thresh
bandit 0 9 0 0 201 0 7.3s 9 FAILED MED (g)
cdk-nag 0 0 0 0 0 0 1m 2s 0 PASSED MED (g)
cfn-nag 0 0 0 0 0 0 40.8s 0 PASSED MED (g)
checkov 0 39 0 0 0 0 31.3s 39 FAILED MED (g)
detect-s… 0 18 0 0 0 0 53.2s 18 FAILED MED (g)
grype 0 57 0 36 7 0 1m 35s 93 FAILED MED (g)
npm-audit 0 0 0 0 0 0 16.9s 0 PASSED MED (g)
opengrep 40 64 0 0 0 0 58.4s 64 FAILED MED (g)
semgrep 0 0 0 0 0 0 <1ms 0 MISSING MED (g)
syft 0 0 0 0 0 0 4.4s 0 PASSED MED (g)

Status: ⚠️ Security findings detected

Detailed Findings

Detailed Findings

Show 223 actionable findings

Finding 1: B310

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B310
  • Location: samples/anycompany-bank/backend/api/auth.py:66-68

Description:
Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected.

Code Snippet:

# nosec B310 — the URL is built from our own pool ID, not user input.
    with urlopen(url, timeout=5) as response:
        import json

Finding 2: B310

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B310
  • Location: samples/anycompany-bank/scripts/deploy_frontend.py:105-107

Description:
Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected.

Code Snippet:

# nosec B310 — the URL is an AWS-issued presigned S3 URL.
    with urllib.request.urlopen(request, timeout=300) as response:
        if response.status not in (200, 204):

Finding 3: B310

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B310
  • Location: samples/anycompany-bank/scripts/discover_and_invoke_via_oauth.py:121-123

Description:
Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected.

Code Snippet:

try:
        with urllib.request.urlopen(request, timeout=120) as resp:
            return resp.status, resp.read().decode()

Finding 4: B310

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B310
  • Location: samples/anycompany-bank/scripts/discover_via_oauth_registry.py:79-81

Description:
Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected.

Code Snippet:

try:
        with urllib.request.urlopen(request, timeout=60) as resp:
            return resp.status, json.loads(resp.read().decode())

Finding 5: B104

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B104
  • Location: samples/aws-specialist-agent/gateway/tools/ltm_mcp_server/server.py:42-44

Description:
Possible binding to all interfaces.

Code Snippet:

mcp = FastMCP("ltm", host="0.0.0.0", stateless_http=True)

Finding 6: B104

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B104
  • Location: samples/aws-specialist-agent/gateway/tools/strands_mcp_server/server.py:35-37

Description:
Possible binding to all interfaces.

Code Snippet:

# AgentCore Runtime MCP contract.
mcp.settings.host = "0.0.0.0"
mcp.settings.port = 8000

Finding 7: B104

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B104
  • Location: samples/aws-specialist-agent/tests/unit/test_ltm_mcp_server.py:140-142

Description:
Possible binding to all interfaces.

Code Snippet:

_load_server_module()
    assert captured["fastmcp_kwargs"] == {"host": "0.0.0.0", "stateless_http": True}

Finding 8: B104

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B104
  • Location: samples/aws-specialist-agent/tests/unit/test_strands_mcp_server.py:101-103

Description:
Possible binding to all interfaces.

Code Snippet:

mod = _load_server_module()
    assert mod.mcp.settings.host == "0.0.0.0"
    assert mod.mcp.settings.port == 8000

Finding 9: B310

  • Severity: HIGH
  • Scanner: bandit
  • Rule ID: B310
  • Location: samples/llm-council/infra-cdk/lambdas/zip-packager/index.py:62-64

Description:
Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected.

Code Snippet:

)
    urllib.request.urlopen(req)

Finding 10: CKV_AWS_158

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_158
  • Location: samples/anycompany-bank/infra/console_api.tf:57-60

Description:
Ensure that CloudWatch Log Group is encrypted by KMS

Code Snippet:

resource "aws_cloudwatch_log_group" "console_api" {
  name              = "/aws/lambda/${var.stack_name}-console-api"
  retention_in_days = var.log_retention_days
}

Finding 11: CKV_AWS_338

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_338
  • Location: samples/anycompany-bank/infra/console_api.tf:57-60

Description:
Ensure CloudWatch log groups retains logs for at least 1 year

Code Snippet:

resource "aws_cloudwatch_log_group" "console_api" {
  name              = "/aws/lambda/${var.stack_name}-console-api"
  retention_in_days = var.log_retention_days
}

Finding 12: CKV_AWS_173

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_173
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
Check encryption settings for Lambda environmental variable

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 13: CKV_AWS_116

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_116
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 14: CKV_AWS_272

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_272
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
Ensure AWS Lambda function is configured to validate code-signing

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 15: CKV_AWS_115

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_115
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
Ensure that AWS Lambda function is configured for function-level concurrent execution limit

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 16: CKV_AWS_117

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_117
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
Ensure that AWS Lambda function is configured inside a VPC

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 17: CKV_AWS_50

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_50
  • Location: samples/anycompany-bank/infra/console_api.tf:149-200

Description:
X-Ray tracing is enabled for Lambda

Code Snippet:

resource "aws_lambda_function" "console_api" {
  function_name = "${var.stack_name}-console-api"
  role          = aws_iam_role.console_api.arn
  package_type  = "Image"
  image_uri     = module.console_api_image.image_uri
  architectures = ["arm64"]

  # Must exceed the longest assessment; the Runtime call itself is capped at
  # 600s by the boto3 read timeout in main.py.
  timeout     = 300
  memory_size = 1024

  environment {
    variables = {
      RUNTIME_ARN         = aws_bedrockagentcore_agent_runtime.kyc.agent_runtime_arn
      REGISTRY_ID         = aws_bedrockagentcore_registry.fsi.registry_id
      GATEWAY_ID          = aws_bedrockagentcore_gateway.kyc.gateway_id
      GATEWAY_URL         = aws_bedrockagentcore_gateway.kyc.gateway_url
      MEMORY_ID           = aws_bedrockagentcore_memory.kyc.id
      KYC_TOOLS_LAMBDA    = aws_lambda_function.kyc_tools.function_name
      USER_POOL_ID        = aws_cognito_user_pool.console.id
      USER_POOL_CLIENT_ID = aws_cognito_user_pool_client.console.id
      CONSOLE_ORIGIN      = "https://${aws_amplify_branch.console.branch_name}.${aws_amplify_app.console.id}.amplifyapp.com"

      # Model-plane facts, mirrored from the runtime's own environment so
      # /api/config can report which route and guardrail the deployment is
      # configured for. The console API does not invoke models itself; these
      # are descriptive only, which is why the same values are set in two
      # places rather than read back from the runtime at request time.
      INFERENCE_ROUTE   = var.inference_route
      GUARDRAIL_ID      = aws_bedrock_guardrail.kyc.guardrail_id
      GUARDRAIL_VERSION = aws_bedrock_guardrail_version.kyc.version
      POLICY_ENGINE_ID  = aws_bedrockagentcore_policy_engine.kyc.policy_engine_id
      POLICY_MODE       = var.policy_engine_mode

      # AgentCore Harness — the managed agent loop, when deployed. one(...)
      # yields null (→ empty env var) when enable_harness = false.
      HARNESS_ID = one(aws_bedrockagentcore_harness.kyc[*].harness_id)
    }
  }

  # No replace_triggered_by: the image is content-addressed, so image_uri
  # changes on a code edit and Terraform issues an in-place
  # update-function-code. Replacing the function instead would tear down the
  # Function URL (whose hostname is regenerated) and its resource policy — the
  # exact churn that broke the deployed frontend during the refactor.
  depends_on = [
    aws_iam_role_policy.console_api,
    aws_cloudwatch_log_group.console_api,
    module.console_api_image,
  ]
}

Finding 18: CKV_AWS_158

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_158
  • Location: samples/anycompany-bank/infra/gateway.tf:16-19

Description:
Ensure that CloudWatch Log Group is encrypted by KMS

Code Snippet:

resource "aws_cloudwatch_log_group" "kyc_tools" {
  name              = "/aws/lambda/${var.stack_name}-kyc-tools"
  retention_in_days = var.log_retention_days
}

Finding 19: CKV_AWS_338

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_338
  • Location: samples/anycompany-bank/infra/gateway.tf:16-19

Description:
Ensure CloudWatch log groups retains logs for at least 1 year

Code Snippet:

resource "aws_cloudwatch_log_group" "kyc_tools" {
  name              = "/aws/lambda/${var.stack_name}-kyc-tools"
  retention_in_days = var.log_retention_days
}

Finding 20: CKV_AWS_116

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_116
  • Location: samples/anycompany-bank/infra/gateway.tf:75-91

Description:
Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)

Code Snippet:

resource "aws_lambda_function" "kyc_tools" {
  function_name = "${var.stack_name}-kyc-tools"
  role          = aws_iam_role.kyc_tools_lambda.arn
  handler       = "kyc_tools_lambda.handler"
  runtime       = "python3.13"
  architectures = ["arm64"]
  timeout       = 30
  memory_size   = 256

  filename         = data.archive_file.kyc_tools.output_path
  source_code_hash = data.archive_file.kyc_tools.output_base64sha256

  depends_on = [
    aws_cloudwatch_log_group.kyc_tools,
    aws_iam_role_policy.kyc_tools_lambda,
  ]
}

Finding 21: CKV_AWS_272

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_272
  • Location: samples/anycompany-bank/infra/gateway.tf:75-91

Description:
Ensure AWS Lambda function is configured to validate code-signing

Code Snippet:

resource "aws_lambda_function" "kyc_tools" {
  function_name = "${var.stack_name}-kyc-tools"
  role          = aws_iam_role.kyc_tools_lambda.arn
  handler       = "kyc_tools_lambda.handler"
  runtime       = "python3.13"
  architectures = ["arm64"]
  timeout       = 30
  memory_size   = 256

  filename         = data.archive_file.kyc_tools.output_path
  source_code_hash = data.archive_file.kyc_tools.output_base64sha256

  depends_on = [
    aws_cloudwatch_log_group.kyc_tools,
    aws_iam_role_policy.kyc_tools_lambda,
  ]
}

Finding 22: CKV_AWS_115

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_115
  • Location: samples/anycompany-bank/infra/gateway.tf:75-91

Description:
Ensure that AWS Lambda function is configured for function-level concurrent execution limit

Code Snippet:

resource "aws_lambda_function" "kyc_tools" {
  function_name = "${var.stack_name}-kyc-tools"
  role          = aws_iam_role.kyc_tools_lambda.arn
  handler       = "kyc_tools_lambda.handler"
  runtime       = "python3.13"
  architectures = ["arm64"]
  timeout       = 30
  memory_size   = 256

  filename         = data.archive_file.kyc_tools.output_path
  source_code_hash = data.archive_file.kyc_tools.output_base64sha256

  depends_on = [
    aws_cloudwatch_log_group.kyc_tools,
    aws_iam_role_policy.kyc_tools_lambda,
  ]
}

Finding 23: CKV_AWS_117

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_117
  • Location: samples/anycompany-bank/infra/gateway.tf:75-91

Description:
Ensure that AWS Lambda function is configured inside a VPC

Code Snippet:

resource "aws_lambda_function" "kyc_tools" {
  function_name = "${var.stack_name}-kyc-tools"
  role          = aws_iam_role.kyc_tools_lambda.arn
  handler       = "kyc_tools_lambda.handler"
  runtime       = "python3.13"
  architectures = ["arm64"]
  timeout       = 30
  memory_size   = 256

  filename         = data.archive_file.kyc_tools.output_path
  source_code_hash = data.archive_file.kyc_tools.output_base64sha256

  depends_on = [
    aws_cloudwatch_log_group.kyc_tools,
    aws_iam_role_policy.kyc_tools_lambda,
  ]
}

Finding 24: CKV_AWS_50

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_50
  • Location: samples/anycompany-bank/infra/gateway.tf:75-91

Description:
X-Ray tracing is enabled for Lambda

Code Snippet:

resource "aws_lambda_function" "kyc_tools" {
  function_name = "${var.stack_name}-kyc-tools"
  role          = aws_iam_role.kyc_tools_lambda.arn
  handler       = "kyc_tools_lambda.handler"
  runtime       = "python3.13"
  architectures = ["arm64"]
  timeout       = 30
  memory_size   = 256

  filename         = data.archive_file.kyc_tools.output_path
  source_code_hash = data.archive_file.kyc_tools.output_base64sha256

  depends_on = [
    aws_cloudwatch_log_group.kyc_tools,
    aws_iam_role_policy.kyc_tools_lambda,
  ]
}

Finding 25: CKV_AWS_107

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_107
  • Location: samples/anycompany-bank/infra/harness.tf:123-260

Description:
Ensure IAM policies does not allow credentials exposure

Code Snippet:

data "aws_iam_policy_document" "harness" {
  count = var.enable_harness ? 1 : 0

  # Model invocation — the harness calls Bedrock for the agent loop.
  statement {
    sid    = "BedrockModelInvocation"
    effect = "Allow"
    actions = [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream",
    ]
    resources = [
      "arn:aws:bedrock:*::foundation-model/*",
      "arn:aws:bedrock:${local.region}:${local.account_id}:inference-profile/*",
    ]
  }

  # The managed harness image is pulled from ECR Public on the public network.
  statement {
    sid       = "EcrPublicTokenAccess"
    effect    = "Allow"
    actions   = ["ecr-public:GetAuthorizationToken"]
    resources = ["*"]
  }
  statement {
    sid       = "StsForEcrPublicPull"
    effect    = "Allow"
    actions   = ["sts:GetServiceBearerToken"]
    resources = ["*"]
  }

  # Observability — traces to X-Ray, logs and metrics to CloudWatch. Same shape
  # as the Runtime role so both agents land in the unified trace view.
  statement {
    sid    = "Observability"
    effect = "Allow"
    actions = [
      "xray:PutTraceSegments",
      "xray:PutTelemetryRecords",
      "xray:GetSamplingRules",
      "xray:GetSamplingTargets",
    ]
    resources = ["*"]
  }
  statement {
    sid    = "CloudWatchLogs"
    effect = "Allow"
    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents",
      "logs:DescribeLogStreams",
    ]
    resources = ["arn:aws:logs:${local.region}:${local.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*"]
  }
  statement {
    sid       = "CloudWatchLogsDescribeGroups"
    effect    = "Allow"
    actions   = ["logs:DescribeLogGroups"]
    resources = ["arn:aws:logs:${local.region}:${local.account_id}:log-group:*"]
  }
  statement {
    sid       = "CloudWatchLogsResourcePolicy"
    effect    = "Allow"
    actions   = ["logs:PutResourcePolicy"]
    resources = ["*"]
  }
  statement {
    sid       = "CloudWatchMetrics"
    effect    = "Allow"
    actions   = ["cloudwatch:PutMetricData"]
    resources = ["*"]
    condition {
      test     = "StringEquals"
      variable = "cloudwatch:namespace"
      values   = ["bedrock-agentcore"]
    }
  }

  # Workload identity for the managed loop.
  statement {
    sid    = "WorkloadIdentity"
    effect = "Allow"
    actions = [
      "bedrock-agentcore:GetWorkloadAccessToken",
      "bedrock-agentcore:GetWorkloadAccessTokenForJWT",
    ]
    resources = [
      "arn:aws:bedrock-agentcore:${local.region}:${local.account_id}:workload-identity-directory/default",
      "arn:aws:bedrock-agentcore:${local.region}:${local.account_id}:workload-identity-directory/default/workload-identity/*",
    ]
  }

  # This harness's wiring: reach the shared Gateway (its KYC tools) under the
  # same ARN the Runtime role grants.
  statement {
    sid       = "InvokeGateway"
    effect    = "Allow"
    actions   = ["bedrock-agentcore:InvokeGateway"]
    resources = [aws_bedrockagentcore_gateway.kyc.gateway_arn]
  }

  # Fetch the S3 skill bundle at session start. The docs require both GetObject
  # (read the SKILL.md) and ListBucket (enumerate the skill prefix).
  statement {
    sid       = "SkillBucketRead"
    effect    = "Allow"
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.harness_skills[0].arn}/*"]
  }
  statement {
    sid       = "SkillBucketList"
    effect    = "Allow"
    actions   = ["s3:ListBucket"]
    resources = [aws_s3_bucket.harness_skills[0].arn]
  }
  # The harness provisions its OWN managed short/long-term memory (the
  # managedMemoryConfiguration the service creates by default) — a resource
  # distinct from the Runtime's shared KYC memory, and named after the harness
  # (`<harness_name>-<service-assigned-id>`). Its id is not known at plan time,
  # so scope to the harness-name prefix. Without this the loop fails mid-run on
  # `ListEvents` against that managed memory.
  statement {
    sid    = "ManagedMemoryAccess"
    effect = "Allow"
    actions = [
      "bedrock-agentcore:CreateEvent",
      "bedrock-agentcore:GetEvent",
      "bedrock-agentcore:ListEvents",
      "bedrock-agentcore:ListSessions",
      "bedrock-agentcore:RetrieveMemoryRecords",
      "bedrock-agentcore:ListMemoryRecords",
    ]
    resources = [
      "arn:aws:bedrock-agentcore:${local.region}:${local.account_id}:memory/${local.harness_name}-*",
    ]
  }
}

Finding 26: CKV_AWS_136

  • Severity: HIGH
  • Scanner: checkov
  • Rule ID: CKV_AWS_136
  • Location: samples/anycompany-bank/infra/modules/ecr-image/main.tf:30-43

Description:
Ensure that ECR repositories are encrypted using KMS

Code Snippet:

resource "aws_ecr_repository" "this" {
  name                 = var.repository_name
  image_tag_mutability = "MUTABLE"
  # Demo stack: allow `terraform destroy` to remove the repo with images in it.
  force_delete = true

  image_scanning_configuration {
    scan_on_push = true
  }



---
*This issue was automatically created by the monthly security scan workflow.*

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions