0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

最小権限の原則を実現するIAMポリシー設計パターン集

0
Posted at

この記事でわかること

  • IAMポリシーの最小権限設計で「使いやすさ」と「セキュリティ」を両立する方法
  • 条件キー(Condition)を使った細粒度のアクセス制御パターン
  • Permission Boundaryを使って開発者に安全にIAM権限を委任する方法
  • IAM Access Analyzerでポリシーの問題を自動検出する方法

実務での背景

IAMポリシーの設計でよくある失敗パターンがあります。

よくある失敗パターン:

  • "Action": "*""Resource": "*" を安易に使ってしまう
  • 「とりあえずAdministratorAccess」を付けてしまう
  • 開発者にIAMフル権限を与えてしまい、意図しないリソース作成が起きる
  • 手作業でポリシーを作るたびに過剰な権限になる

最小権限の原則は「理想論」ではなく、実際にインシデントを防ぐための実践的な設計です。


解決方法

設計の基本3原則

  1. 最小権限(Least Privilege): 必要最低限のアクションのみ許可
  2. タグベース制御: 自分が作ったリソースだけ操作可能
  3. Permission Boundary: 開発者が作れるIAMロールに上限を設ける

具体的な手順

Step 1: よく使うポリシーパターン集

パターン1: 特定のS3バケットにのみアクセス

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3BucketListAccess",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::my-app-prod-data"
    },
    {
      "Sid": "S3ObjectAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::my-app-prod-data/*"
    }
  ]
}

パターン2: 自分が作ったリソースのみ操作可能(タグ制御)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowEC2DescribeAll",
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowEC2ManageOwnedResources",
      "Effect": "Allow",
      "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Owner": "${aws:username}"
        }
      }
    },
    {
      "Sid": "RequireOwnerTagOnCreate",
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/Owner": "${aws:username}"
        }
      }
    }
  ]
}

⚠️ ${aws:username}IAMユーザーでのみ展開される変数です。AssumeRoleで操作する運用(推奨構成)では空文字列になり機能しません。ロールで同等の制御をしたい場合は後述の「ハマりポイント」を参照してください。

パターン3: MFA認証済みの場合のみ許可

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyWithoutMFA",
      "Effect": "Deny",
      "NotAction": [
        "iam:CreateVirtualMFADevice",
        "iam:EnableMFADevice",
        "iam:GetUser",
        "iam:ListMFADevices",
        "iam:ListVirtualMFADevices",
        "iam:ResyncMFADevice",
        "sts:GetSessionToken"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

Step 2: Permission Boundary の実装

開発者にIAMロールの作成権限を与えつつ、過剰な権限を付与できないように制限します。

// permission-boundary.json(開発者が作成するロールの上限)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:*",
        "dynamodb:*",
        "lambda:*",
        "cloudwatch:*",
        "logs:*"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": [
        "iam:*",
        "organizations:*",
        "account:*"
      ],
      "Resource": "*"
    }
  ]
}
// developer-policy.json(開発者に与えるポリシー:Boundary強制部分の抜粋)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:PutRolePolicy",
        "iam:AttachRolePolicy"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT_ID:policy/DeveloperBoundary"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:GetRole",
        "iam:ListRoles",
        "iam:DeleteRole",
        "iam:DetachRolePolicy",
        "iam:DeleteRolePolicy"
      ],
      "Resource": "*"
    }
  ]
}

💡 ポイント:iam:PutRolePolicy / iam:AttachRolePolicy 側にも iam:PermissionsBoundary 条件を付けることで、開発者が「Boundary無しのロールを後から作り替える」抜け道を塞げます。iam:DeleteRole などのライフサイクル系は Boundary 条件を付けると失敗するので別Statementに分けています。

Step 3: IAM Access Analyzer で問題を自動検出

# アナライザーの作成
# ※ --type ORGANIZATION は AWS Organizations の管理アカウント(または委任管理アカウント)でのみ実行可能。
#    単一アカウントで使う場合は --type ACCOUNT に変更してください。
aws accessanalyzer create-analyzer \
  --analyzer-name "my-org-analyzer" \
  --type ORGANIZATION

# 検出結果の確認
aws accessanalyzer list-findings \
  --analyzer-arn arn:aws:access-analyzer:ap-northeast-1:123456789:analyzer/my-org-analyzer \
  --filter '{"status": {"eq": ["ACTIVE"]}}' \
  --query 'findings[*].[id,resourceType,resource,isPublic]' \
  --output table

# ポリシーの検証(作成前にチェック)
aws accessanalyzer validate-policy \
  --policy-type IDENTITY_POLICY \
  --policy-document file://my-policy.json \
  --query 'findings[*].[findingType,issueCode,learnMoreLink]' \
  --output table

構成図

[組織管理者]
     |
     v
+------------------------+
| SCP (Service Control   |
| Policy)                |
| - 全アカウント共通制限  |
| - root操作の禁止など   |
+------------------------+
     |
     v
[開発者アカウント]
     |
     +---> Permission Boundary(上限制限)
     |         |
     v         v
+------------------------+
| 開発者IAMユーザー/ロール|
| - developer-policy     |
| - PermBoundary強制付与 |
+------------------------+
     |
     v
+------------------------+
| 開発者が作成するロール  |
| - Permission Boundary  |
|   の範囲内に自動制限   |
+------------------------+

[IAM Access Analyzer]
定期スキャン → 外部公開リソース・過剰権限を検出 → SNS通知

ハマりポイント

❌ Denyポリシーの順序を誤解する

IAMポリシーの評価順序は「Explicit Deny > Allow > Default Deny」です。どこかで Deny があれば、どんなに Allow があっても拒否されます。

評価順序:
1. 明示的Deny (Explicit Deny) → 即座に拒否(他のポリシーは無視)
2. 明示的Allow             → 許可
3. 暗黙のDeny (Default Deny) → デフォルト拒否

aws:username はIAMロールでは使えない

"${aws:username}" の変数はIAMユーザーにのみ有効です。IAMロール(AssumeRole)では aws:userid を使います。IAMロールの aws:useridAROAXXXXXXXXXX:session-name の形式になるため、セッション名を規則化(例:ユーザー名をセッション名にする)した上で照合します。

// IAMロール向け(roleセッション名で照合する例)
//  AssumeRole時に --role-session-name にユーザー名を指定する運用が前提
"StringLike": {
  "aws:userid": "*:targeted-session-name"
}

iam:PassRole を忘れる

EC2インスタンスにIAMロールをアタッチするには、実行者に iam:PassRole が必要です。「EC2の起動権限があるのにロールがアタッチできない」というときはこれが原因です。

{
  "Effect": "Allow",
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::*:role/ec2-*"
}

まとめ

手法 効果 対象
リソースARN指定 対象リソースを明示的に限定 全ユーザー
タグベース制御 自分のリソースのみ操作可能 開発者
MFA Condition 重要操作にMFA必須化 管理者
Permission Boundary 開発者のIAM権限に上限を設定 組織
Access Analyzer 過剰権限の自動検出 運用チーム

IAMは「とりあえず動けばいい」ではなく、設計の良し悪しがセキュリティインシデントに直結します。Permission Boundary + Access Analyzer の組み合わせが最も効果的な防御策です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?