mcpField
T
terraform-security-audit

terraform-security-audit

github.com/c0x12cセキュリティ109109 回インストール19 週間前に更新
リポジトリ

terraform-security-audit について

terraform-security-audit は、Terraform のコードベースを IAM、ネットワーク、暗号化など 6 つの領域で監査するスキルです。領域ごとの合否を報告し、不合格項目には修正コードを提示します。

主な機能

  1. 016 つのセキュリティ領域を確認
  2. 02すべての .tf ファイルをスキャン
  3. 03重大度順に問題を提示
  4. 04不合格項目の修正コードを提示
  5. 05領域別の監査レポートを生成

活用シーン

  1. 01本番デプロイ前のインフラ確認
  2. 02インフラの定期的な監査
  3. 03新サービス設定の検証
  4. 04インシデント後のセキュリティ強化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/c0x12c/ai-toolkit --skill terraform-security-audit

インストール後、Claude Code で/terraform-security-auditを入力して読み込まれたか確認します。

詳細

Terraform セキュリティ監査

Terraform のコードベースに対して、6 領域のセキュリティ監査を実行します。各領域の合格/不合格レポートを生成します。

使用するタイミング

  • 本番環境へのデプロイ前のセキュリティレビュー
  • 定期的なインフラストラクチャのセキュリティ監査
  • 新しいサービスのセットアップ検証
  • インシデント後のセキュリティ強化チェック

プロセス

1. IAM — アイデンティティとアクセス管理
  • CI/CD で OIDC を使用している(長期間有効なアクセスキーを使用していない)
  • EKS ワークロードに IRSA を使用している(ノードレベルの IAM を使用していない)
  • ECS タスクロールがサービスごとに適切に制限されている(共有ロールを使用していない)
  • IAM ポリシーが最小権限の原則に従っている
  • * リソースに対する * アクションがない
  • インラインポリシーを使用していない(マネージドポリシーまたはカスタマーポリシーを使用する)
  • Assume role の条件に ExternalId または sts:SourceIdentity が含まれている
# INSECURE — overly broad permissions
resource "aws_iam_policy" "bad" {
  policy = jsonencode({
    Statement = [{
      Effect   = "Allow"
      Action   = "*"
      Resource = "*"
    }]
  })
}

# SECURE — scoped to specific actions and resources
resource "aws_iam_policy" "good" {
  policy = jsonencode({
    Statement = [{
      Effect   = "Allow"
      Action   = ["s3:GetObject", "s3:PutObject"]
      Resource = "${aws_s3_bucket.assets.arn}/*"
    }]
  })
}
# SECURE — IRSA for EKS pods
module "irsa" {
  source = "git::https://github.com/{project}/terraform-modules.git//irsa?ref=v1.0.0"

  name              = "${local.name_prefix}-irsa"
  oidc_provider_arn = var.oidc_provider_arn
  namespace         = var.service
  service_account   = var.service
  policy_arns       = [aws_iam_policy.service.arn]
}
2. ネットワーク — VPC とセキュリティグループ
  • データベースがプライベートサブネットのみに配置されている
  • ALB の 443 番ポートを除き、0.0.0.0/0 からのインバウンド通信がない
  • セキュリティグループで CIDR ではなく source_security_group_id を使用している
  • 可能な範囲でエグレスが制限されている
  • VPC フローログが有効になっている
  • 踏み台インスタンス以外にパブリック IP が割り当てられていない
# INSECURE — database accessible from anywhere
resource "aws_security_group_rule" "rds_bad" {
  type        = "ingress"
  from_port   = 5432
  to_port     = 5432
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.rds.id
}

# SECURE — database only from app security group
resource "aws_security_group_rule" "rds_good" {
  type                     = "ingress"
  from_port                = 5432
  to_port                  = 5432
  protocol                 = "tcp"
  source_security_group_id = aws_security_group.app.id
  security_group_id        = aws_security_group.rds.id
  description              = "PostgreSQL access from application"
}
3. 暗号化 — 保存データと転送中のデータ
  • S3:SSE が有効になっている(KMS または AES-256)
  • RDS:storage_encrypted = true に設定されている
  • RDS:パラメータグループで ssl_enforcement を設定している
  • Redis:transit_encryption_enabled = true に設定されている
  • Redis:at_rest_encryption_enabled = true に設定されている
  • EBS ボリュームが暗号化されている
  • Terraform のステートバケットが SSE-KMS で暗号化されている
  • ALB が TLS 1.2 以降のみを使用している
# INSECURE — no encryption
resource "aws_db_instance" "bad" {
  storage_encrypted = false  # default
}

# SECURE — encryption enabled
resource "aws_db_instance" "good" {
  storage_encrypted = true
  kms_key_id        = var.rds_kms_key_arn
}
# SECURE — Redis encryption
module "redis" {
  source = "git::https://github.com/{project}/terraform-modules.git//elasticache?ref=v1.0.0"

  transit_encryption = true
  at_rest_encryption = true
  auth_token         = var.redis_auth_token
}
4. シークレット — シークレット管理
  • .tf ファイルやコミット済みの .tfvars にシークレットが含まれていない
  • secrets.tfvars が .gitignore に含まれている
  • 機密変数に sensitive = true が指定されている
  • CI/CD の環境変数を介してシークレットが注入されている
  • ステートに平文のパスワードがない(sensitive 出力を使用する)
  • git-secret-protector または pre-commit フックで、誤ったコミットを防いでいる
# INSECURE — password in code
resource "aws_db_instance" "bad" {
  password = "SuperSecret123!"
}

# SECURE — from variable, marked sensitive
variable "db_password" {
  description = "Database master password"
  type        = string
  sensitive   = true
}

resource "aws_db_instance" "good" {
  password = var.db_password
}
# SECURE — sensitive output
output "connection_string" {
  value     = "postgresql://${var.db_user}:${var.db_password}@${aws_db_instance.main.endpoint}/${var.db_name}"
  sensitive = true
}
5. アクセス — クラスターとコンソールへのアクセス
  • EKS の aws-auth ConfigMap で、必要なロールのみにアクセスを制限している
  • コンソールへのアクセスに SSO を使用している(パスワードを持つ IAM ユーザーを使用していない)
  • Session Manager を使用するプライベートサブネット内の踏み台ホストがある(SSH キーを使用していない)
  • API 監査ログ用に CloudTrail が有効になっている
  • 人間のアカウントで MFA が強制されている
# EKS access control
resource "kubernetes_config_map" "aws_auth" {
  metadata {
    name      = "aws-auth"
    namespace = "kube-system"
  }

  data = {
    mapRoles = yamlencode([
      {
        rolearn  = var.admin_role_arn
        username = "admin"
        groups   = ["system:masters"]
      },
      {
        rolearn  = var.node_role_arn
        username = "system:node:{{EC2PrivateDNSName}}"
        groups   = ["system:bootstrappers", "system:nodes"]
      }
    ])
  }
}
6. コンプライアンス — タグ、命名、バックアップ
  • すべてのリソースに Project、Service、Environment、ManagedBy のタグが付いている
  • {project}-{service}-{env} の規則に従って命名している
  • RDS の自動バックアップが有効になっている(保持期間は 7 日以上、本番環境では 30 日)
  • データバケットで S3 のバージョニングが有効になっている
  • DynamoDB のポイントインタイムリカバリが有効になっている
  • 重要なメトリクスに CloudWatch アラームが設定されている
  • コスト配分タグが設定されている
# CORRECT — default tags at provider level
provider "aws" {
  default_tags {
    tags = {
      Project     = var.project
      Service     = var.service
      Environment = var.env
      ManagedBy   = "terraform"
    }
  }
}

# CORRECT — backup retention
resource "aws_db_instance" "main" {
  backup_retention_period = var.env == "prod" ? 30 : 7
  backup_window           = "03:00-04:00"
}

対話スタイル

  • コードベース内のすべての .tf ファイルをスキャンします
  • すべての領域を確認し、セクションを省略しません
  • 重大な指摘事項(IAM のワイルドカード、パブリックアクセス、暗号化の欠如)を最初に強調します
  • 不合格となった各チェックについて、修正用のコードを提示します

ルール

  • 重大:IAM の */*、データベースへのパブリックアクセス、ストレージの暗号化なし、コード内のシークレット
  • 警告:タグの欠如、バックアップ保持期間の不足、フローログの未設定
  • 情報:説明の欠如、任意のセキュリティ強化が未適用

出力

セキュリティ監査レポートを生成します:

## Terraform Security Audit: {service}

### Overall: Pass | Fail

| Area       | Status   | Critical | Warnings | Info |
|------------|----------|----------|----------|------|
| IAM        | Pass     | 0        | 0        | 1    |
| Network    | Fail     | 1        | 0        | 0    |
| Encryption | Pass     | 0        | 1        | 0    |
| Secrets    | Pass     | 0        | 0        | 0    |
| Access     | Pass     | 0        | 0        | 1    |
| Compliance | Warning  | 0        | 2        | 0    |

### Critical Findings
- **[Network]** Security group `rds_main` allows ingress from 0.0.0.0/0 on port 5432
  - File: `modules/{service}/sg.tf:15`
  - Fix: Replace `cidr_blocks` with `source_security_group_id`

### Warnings
- **[Encryption]** Redis `at_rest_encryption` not enabled
  - File: `modules/{service}/redis.tf:8`
  - Fix: Add `at_rest_encryption = true`

### Remediation Priority
1. Fix critical findings before any deployment
2. Address warnings before production promotion
3. Info items for next sprint

コメント