- 1 1. この記事について — セキュリティ本番運用シリーズ Vol2
- 2 2. 前提・環境・準備
- 3 3. IAM Identity Center vs IAM User/Role 比較 + 移行戦略
- 4 4. Permission Sets 設計パターン + Inline / Customer Managed Policy 使い分け
- 5 5. ABAC + タグ戦略 + Session Tags Terraform 完全実装
- 6 6. External IdP 連携 (Entra ID / Okta) + SAML / SCIM 自動プロビジョニング Terraform 完全実装
- 7 7. 監査 + CloudTrail 連携 + Permission Boundary 完全実装
- 8 8. まとめ + Vol3予告 + 落とし穴 10 選
1. この記事について — セキュリティ本番運用シリーズ Vol2

- Lambda Vol1-3 (WP:2186/2196/2207): コンテナ/Powertools/EventBridge 完全実装
- EKS Vol1-3 (WP:2217/2228/2241): Fargate/IRSA/ALB+ArgoCD 完全実装
- 観測性 Vol1-3 (WP:2252/2304/2315): Logs/X-Ray+ADOT/Application Signals+SLO
- セキュリティ Vol1 (WP:2331): GuardDuty+Security Hub Terraform 本番運用
- セキュリティ Vol2 (本記事): IAM Identity Center+Permission Sets+ABAC ← 今ここ
- セキュリティ Vol3 (WP:2364): AWS Config+Conformance Pack+Auto Remediation 完全運用編
- IAM Identity Center vs IAM User/Role 採用判断 5 軸マトリクス + 移行戦略
- Permission Sets 6 種テンプレ + Inline/Customer Managed Policy 設計パターン
- ABAC + Session Tags + Department/Project/Environment 3 軸タグ戦略 Terraform
- Entra ID / Okta SAML + SCIM 自動プロビジョニング Terraform 完全実装
- Permission Boundary 併用 + CloudTrail × Athena 監査クエリ 5 例
1-1. セキュリティ本番運用シリーズ Vol2 起ち上げ
本記事はセキュリティ本番運用シリーズ第 2 巻として、Lambda 3 部作・EKS 3 部作・観測性 3 部作・セキュリティ Vol1 の計 10 巻に続く 11 巻目です。
Vol1 で構築した GuardDuty + Security Hub の「検知層」に続く「IAM 統制層」を本 Vol2 で確立し、Vol3 の AWS Config + Conformance Pack「コンプライアンス自動化層」へ繋げます。
10 巻公開済 → 12 巻完結 ロードマップ
| シリーズ | 巻 | テーマ | WP ID | ステータス |
|---|---|---|---|---|
| Lambda 本番運用 | Vol1 | コンテナ + Blue/Green デプロイ | 2186 | 公開済 |
| Lambda 本番運用 | Vol2 | SnapStart + Provisioned Concurrency | 2196 | 公開済 |
| Lambda 本番運用 | Vol3 | Powertools + Layers + コスト最適化 | 2207 | 公開済 |
| EKS 本番運用 | Vol1 | Karpenter + クラスターオートスケーリング | 2217 | 公開済 |
| EKS 本番運用 | Vol2 | IRSA + IAM 最小権限設計 | 2228 | 公開済 |
| EKS 本番運用 | Vol3 | ALB + ArgoCD GitOps | 2241 | 公開済 |
| 観測性本番運用 | Vol1 | CloudWatch Logs Insights | 2252 | 公開済 |
| 観測性本番運用 | Vol2 | X-Ray + ADOT 分散トレーシング | 2304 | 公開済 |
| 観測性本番運用 | Vol3 | Application Signals + SLO | 2315 | 公開済 |
| セキュリティ本番運用 | Vol1 | GuardDuty + Security Hub | 2331 | 公開済 |
| セキュリティ本番運用 | Vol2 | IAM Identity Center + Permission Sets + ABAC (本記事) | 2352 | 今ここ |
| セキュリティ本番運用 | Vol3 | AWS Config + Conformance Pack + Auto Remediation | 2364 | 公開済 |
セキュリティ Vol2 は EKS 3 部作・観測性 3 部作と直接連携します。EKS Vol2 (IRSA / WP:2228) で設計した IAM 最小権限を Identity Center + Permission Sets で一元管理し、観測性 Vol1 (WP:2252) の CloudWatch Logs Insights で Identity Center 操作ログを相関分析する構成を §7 で解説します。
既存 10 巻との連携ポイント
- 観測性 Vol1 (WP:2252): CloudWatch Logs Insights で Identity Center アクセスログを相関分析 (§7)
- EKS Vol2 (WP:2228): IRSA + Identity Center の統合で EKS ワークロードの IAM 最小権限を一元化 (§3/§6)
- EKS Vol3 (WP:2241): ArgoCD で Permission Sets Terraform 設定を GitOps 管理し、設定ドリフトを検知 (§6)
- Lambda Vol3 (WP:2207): EventBridge + Identity Center 操作ログを組み合わせた通知パイプライン設計 (§6)
- 観測性 Vol3 (WP:2315): Application Signals SLO ダッシュボードへの Identity Center ロールベースアクセス制御適用 (§4)
- セキュリティ Vol1 (WP:2331): GuardDuty 検知 × Identity Center ユーザー操作の時系列相関分析 (§7)
1-2. 本記事のゴール
本記事を完了すると、以下の成果物が手元に揃います。
- IAM Identity Center + Permission Sets 本番導入:
aws_ssoadmin_permission_setリソースで Permission Sets 6 種 (AdminAccess / PowerUser / DeveloperAccess / ReadOnly / Billing / Security) を Terraform 管理し、Organizations 全 Member Account へ一括展開できる - ABAC + Session Tags によるタグベース権限制御: Department / Project / Environment の 3 軸タグ戦略と Session Tags (
aws:PrincipalTag) を組み合わせ、Condition: StringEquals/StringLikeで属性ベースのアクセス制御を実装できる - Entra ID / Okta SAML/SCIM 自動プロビジョニング: External IdP との SAML 2.0 統合と SCIM v2.0 自動プロビジョニングを
aws_identitystore_group+aws_identitystore_userで Terraform 化し、ユーザー/グループ同期を自動化できる - Permission Boundary + CloudTrail 監査基盤:
aws_iam_policy(Permission Boundary) で Identity Center が付与する権限の上限を設定しつつ、CloudTrail Identity Center イベント × Athena 監査クエリ 5 例でアクセス操作ログを分析できる - セキュリティ 3 部作の IAM 統制軸確立: Vol1 GuardDuty 検知層 + 本 Vol2 IAM 統制層 + Vol3 Config コンプライアンス層で 12 巻 AWS 本番運用シリーズのセキュリティ基盤を完成させる
本記事の構成早見表
| 章 | テーマ | QG | ポイント |
|---|---|---|---|
| §3 | IAM Identity Center vs IAM User/Role 比較 + 移行戦略 | brc-red QG-1 | 採用判断 5 軸マトリクス + 既存 IAM User からの移行ステップ |
| §4 | Permission Sets 設計パターン + Inline/CM Policy 使い分け | brc-red QG-2 | 6 種テンプレ + Inline vs Customer Managed の選定基準 |
| §5 | ABAC + タグ戦略 + Session Tags | brc-yellow QG-3 | タグキー設計 + Session Tags + Policy Condition 評価フロー |
| §6 | External IdP 連携 (Entra ID/Okta) + SAML/SCIM | brc-yellow QG-4 | SAML 統合 + SCIM プロビジョニング + 必須 attribute 5 項目 |
| §7 | 監査 + CloudTrail 連携 + Permission Boundary 併用 | brc-yellow QG-5 | CloudTrail イベント + Permission Boundary + Athena クエリ 5 例 |
| §8 | まとめ + Vol3 予告 + 落とし穴 10 選 | — | セキュリティ 3 部作起点 + 10 巻クロスリンク |
1-3. 読者像
本記事は以下の読者を想定しています。
- AWS Organizations でマルチアカウント環境を運用中で、各アカウントの IAM 権限管理の一元化に課題を感じているインフラ・SRE エンジニア
- IAM User / Access Key 運用からの Identity Center への移行を検討しているが、Permission Sets 設計や ABAC 実装の具体的な手順が分からない方
- ABAC によるタグベース権限制御を実装したい方(Session Tags + Department/Project/Environment 3 軸タグ戦略)
- Entra ID / Okta などの External IdP と AWS を SAML/SCIM で統合し、Terraform で IaC 管理したい方
- セキュリティ Vol1 (GuardDuty + Security Hub) を読了し、検知層に続く IAM 統制層を構築したい方
- 既存の Lambda / EKS ワークロードに対して Permission Sets を整備し、IRSA + Identity Center の組み合わせで IAM 最小権限を完成させたい方
Terraform の基本的な HCL 記述 (resource / variable / output / module) と AWS Organizations の基本概念 (Management Account / Member Account / SCP) を把握していることを前提とします。
EKS Vol2 (IRSA / WP:2228) で IAM 最小権限設計を学んでいる方は、§3・§6 で Identity Center + IRSA 統合パターンとの対比が参考になります。
Identity Center や Permission Sets が初めての方は §3 の採用判断マトリクスから順に読み進めることで、本番導入に必要な設計判断を自分で行えるようになります。
1-4. なぜ今これを書くか
競合記事 10 件を調査した結果、以下の空白地帯を確認しました。
- IAM Identity Center + Permission Sets + ABAC + External IdP の 1 本完結 Terraform 記事が競合 10 件中 0 件
- Session Tags + ABAC の日本語 Terraform 実装記事(Department/Project/Environment 3 軸)が存在しない
- Permission Sets 6 種テンプレ + Inline/Customer Managed Policy 使い分けを選定基準マトリクス付きで解説した記事が競合 0 件
- Entra ID + Okta 両方を並列解説して SAML/SCIM Terraform 自動化まで踏み込んだ記事が存在しない
本記事は Lambda 3 部作・EKS 3 部作・観測性 3 部作・セキュリティ Vol1 の既存 10 巻読者へ、IAM 統制層を提供する Vol2 起点として設計されています。IAM User 移行判断 (§3)・Permission Sets 設計 (§4)・ABAC 実装 (§5)・External IdP 連携 (§6)・監査基盤 (§7) を 1 記事で完結させているため、分散した複数資料を参照せずに実装を完了できます。
既存 IAM User / Access Key 運用が続いている環境では §3 の移行判断マトリクスから着手し、Permission Sets の段階的展開で既存ロールへの影響を最小化しながら移行できます。
セキュリティ Vol3 (AWS Config + Conformance Pack) では本記事の IAM 統制基盤を前提に、コンプライアンス自動評価層を構築します。
AWS Organizations の SCP (Service Control Policy) と Identity Center の Permission Sets を組み合わせることで、組織全体の権限制御の多層防御を実現します。
1-5. 読み進め方ガイド
本記事は通読を基本としますが、目的に応じて以下の読み進め方を推奨します。
| 背景 | 推奨読み進め方 |
|---|---|
| IAM Identity Center が初めて | §2 前提確認 → §3 → §4 → §5 → §6 → §7 の順に通読 |
| Identity Center 導入済み・Permission Sets 設計見直し | §4 から開始し §5 → §6 → §7 |
| ABAC / Session Tags の実装が優先 | §5 から直接着手し必要に応じて §3・§4 を参照 |
| Entra ID / Okta 連携が目的 | §6 の SAML/SCIM 設定から開始 |
| 監査・Permission Boundary 強化が目的 | §7 の CloudTrail + Athena クエリを先読み |
§3・§4 は「Identity Center 採用判断と Permission Sets 設計」を扱う意思決定層で、移行可否の判断に最適です。§5〜§7 は「Terraform でどう実装するか」の実践層で、コードをそのまま活用できます。
前提シリーズ: セキュリティVol1 GuardDuty+Security Hub本番運用を読む
2. 前提・環境・準備
2-1. 前提環境
本記事では以下の環境が整備済みであることを前提とします。
- AWS Organizations 設定済み: Management Account と Member Account が Organizations で管理されていること
- IAM Identity Center 有効化: Management Account または委任管理アカウントで Identity Center が有効化済みであること (本記事の §3 で確認手順を解説)
- Terraform >= 1.7:
terraform versionで 1.7 以上であることを確認 - AWS Provider v5.x:
aws_ssoadmin_permission_set/aws_ssoadmin_account_assignment/aws_identitystore_group等を使用するため v5.x 以上が必要 - AWS CLI v2:
aws --versionで v2.x 以上であることを確認 - IAM 権限:
sso-admin:*/identitystore:*/organizations:*/iam:CreatePolicy/iam:AttachRolePolicy/cloudtrail:*を Management Account または委任管理アカウントに付与済み - External IdP (§6 でオプション設定): Entra ID (旧 Azure AD) または Okta — SAML/SCIM 連携は §6 で Terraform 実装
# 前提環境の確認コマンド
aws --version
terraform version
aws sts get-caller-identity
# Organizations の有効化確認
aws organizations describe-organization \
--query 'Organization.{Id:Id,MasterAccountId:MasterAccountId}' \
--output table
# IAM Identity Center インスタンス確認 (us-east-1 固定)
aws sso-admin list-instances --region us-east-1
# Permission Sets 一覧確認 (既存環境)
INSTANCE_ARN=$(aws sso-admin list-instances --region us-east-1 \
--query 'Instances[0].InstanceArn' --output text)
aws sso-admin list-permission-sets --instance-arn "$INSTANCE_ARN" --region us-east-1
2-2. 使用技術スタック
| カテゴリ | 技術 / サービス | バージョン / 備考 |
|---|---|---|
| IaC | Terraform (AWS Provider) | >= 1.7 / AWS Provider v5.x |
| ID 管理 | AWS IAM Identity Center | 最新 (ssoadmin API / us-east-1 グローバル) |
| 権限制御 | Permission Sets + ABAC | 最新 (Session Tags / aws:PrincipalTag) |
| IdP 統合 | Entra ID (旧 Azure AD) / Okta | 最新 (SAML 2.0 / SCIM v2.0) |
| 監査 | AWS CloudTrail + Amazon Athena | 最新 (Identity Center 操作イベント) |
| マルチアカウント | AWS Organizations | 最新 (Management + Member Accounts) |
| AWS CLI | AWS CLI v2 | v2.x 以上 |
Terraform 主要リソース一覧
| Terraform リソース | 役割 |
|---|---|
aws_ssoadmin_permission_set | Permission Set 定義 (セッション有効期限・説明) |
aws_ssoadmin_managed_policy_attachment | AWS 管理ポリシーを Permission Set にアタッチ |
aws_ssoadmin_customer_managed_policy_attachment | カスタマー管理ポリシーをアタッチ |
aws_ssoadmin_account_assignment | Permission Set を Member Account + プリンシパルに割り当て |
aws_identitystore_group | Identity Store グループ管理 |
aws_identitystore_user | Identity Store ユーザー管理 |
aws_ssoadmin_instance_access_control_attributes | ABAC 用アクセス制御属性設定 |
aws_iam_policy (Permission Boundary) | 権限上限を設定する Permission Boundary ポリシー |
2-3. ゴール状態の定義
本記事の完了時点で、以下の状態が AWS マネジメントコンソールおよび terraform state で確認できることをゴールとします。
- IAM Identity Center: Organizations 全アカウントで有効化済み。Permission Sets 6 種 (AdminAccess / PowerUser / DeveloperAccess / ReadOnly / Billing / Security) が定義され、指定 Member Account へ割り当て済み
- ABAC + Session Tags: アクセス制御属性 (Department / Project / Environment) が有効化済み。Session Tags と Policy Condition によるタグベース権限制御が
terraform planで検証済み - External IdP 連携: SAML 2.0 アプリケーション設定完了。SCIM 自動プロビジョニングでユーザー/グループが Identity Store に同期されている (§6 でオプション実装)
- 監査基盤: CloudTrail で Identity Center 操作ログが S3 に蓄積中。Athena クエリ 5 例が実行可能で、Permission Boundary が全 Permission Set に適用済み
確認コマンドチートシート
# Permission Sets 一覧確認
INSTANCE_ARN=$(aws sso-admin list-instances --region us-east-1 \
--query 'Instances[0].InstanceArn' --output text)
aws sso-admin list-permission-sets --instance-arn "$INSTANCE_ARN" \
--region us-east-1 --query 'PermissionSets[]' --output table
# ABAC アクセス制御属性の確認
aws sso-admin describe-instance-access-control-attribute-configuration \
--instance-arn "$INSTANCE_ARN" --region us-east-1
# Identity Store ユーザー確認
IDENTITY_STORE_ID=$(aws sso-admin list-instances --region us-east-1 \
--query 'Instances[0].IdentityStoreId' --output text)
aws identitystore list-users --identity-store-id "$IDENTITY_STORE_ID"
# アカウント割り当て確認 (Member Account ID を指定)
aws sso-admin list-account-assignments \
--instance-arn "$INSTANCE_ARN" \
--account-id <MEMBER_ACCOUNT_ID> \
--permission-set-arn <PERMISSION_SET_ARN> \
--region us-east-1
2-4. コスト概算
本記事の実装によって発生する費用の目安を示します。
| サービス | 課金単位 | 目安月額 |
|---|---|---|
| IAM Identity Center | 追加料金なし (Organizations 利用前提) | $0 |
| SCIM API 自動プロビジョニング | 追加料金なし | $0 |
| CloudTrail | $2.00/100 万管理イベント + S3 ストレージ | 月数百円程度 |
| Amazon Athena | $5.00/1 TB スキャン | 月数十円程度 (監査クエリのみ) |
| External IdP ライセンス | AWS 外部費用 (既存ライセンス確認要) | Entra ID P1: $6/user/月 / Okta Workforce Identity: $2~/user/月 |
IAM Identity Center 本体と SCIM プロビジョニングは無料で利用できます。費用が発生するのは CloudTrail ログの保管と Athena での分析、および External IdP のライセンス費用のみです。External IdP を新規導入する場合はライセンス費用が最大のコスト要因となるため、既存の Entra ID / Okta ライセンス保有状況を事前に確認してください。
3. IAM Identity Center vs IAM User/Role 比較 + 移行戦略

sequenceDiagram
participant Dev as 開発者
participant IAMU as IAM User (Access Key)
participant API as AWS API
participant IC as IAM Identity Center
participant STS as AWS STS
participant IdP as External IdP<br/>(Entra ID / Okta)
Note over Dev,API: 【従来方式】IAM User + 長期 Access Key
Dev->>IAMU: プログラムアクセス (AKID + SecretKey)
IAMU->>API: API リクエスト (長期認証情報)
API-->>Dev: レスポンス
Note over IAMU: ⚠ 長期 Access Key が永続<br/>漏洩リスク / ローテーション負荷大
Note over Dev,STS: 【Identity Center 方式】SAML + STS 一時認証情報
Dev->>IC: アクセスポータルへ SSO ログイン
IC->>IdP: SAML 認証リクエスト
IdP-->>IC: SAML アサーション (ユーザー属性)
IC->>STS: AssumeRoleWithSAML (Permission Set → IAM Role)
STS-->>IC: 一時認証情報 (TTL=1h / 自動失効)
IC-->>Dev: AWS CLI / SDK 向け一時 credentials
Dev->>API: API リクエスト (一時認証情報)
API-->>Dev: レスポンス
Note over STS: ✅ 一時認証情報 (TTL=1h)<br/>自動失効 / 漏洩影響を最小化
3-1. IAM Identity Center とは
IAM Identity Center (旧称: AWS SSO / 2022 年 7 月改称) は、AWS Organizations 配下の全アカウントに一元的なシングルサインオン (SSO) を提供するマネージドサービスです。従来の IAM User に依存したアカウント単位の権限管理から脱却し、組織全体の ID・権限管理を一元化できます。追加料金は発生しません。
IAM Identity Center を有効化すると、Identity Center が Organizations 管理アカウントの IAM ロールを自動作成し、Permission Sets の内容をそのロールのポリシーとして管理する。開発者は長期 Access Key を持たず、STS から発行された一時認証情報 (TTL=1h) のみで AWS リソースを操作する。
主要コンポーネント:
| コンポーネント | 役割 |
|---|---|
| Identity Store | AWS 内蔵のユーザー/グループ管理ストア。External IdP (Entra ID/Okta) を使わない場合はここで直接管理 |
| Permission Sets | IAM ポリシーのテンプレート。各 AWS アカウントへのアクセス権限を一元定義 (§4 で詳述) |
| アカウント割り当て | Permission Sets を特定のユーザー/グループ + AWS アカウントに紐付ける |
| アクセスポータル | 開発者がブラウザから各 AWS アカウントへ SSO でログインするエントリポイント |
| SAML/SCIM 連携 | External IdP との統合。ユーザー/グループの自動プロビジョニングを実現 (§6 で詳述) |
3-2. IAM User/Role vs IAM Identity Center 比較マトリクス
IAM Identity Center への移行を判断する際は、以下の 7 軸で評価する。
| 比較軸 | IAM User / Access Key | IAM Identity Center |
|---|---|---|
| 認証方式 | 長期 Access Key (AKID + SecretKey) 漏洩リスク・ローテーション負荷大 | 短期 STS 一時認証情報 (TTL=1h) 自動失効・ローテーション不要 |
| 権限管理 | アカウント単位で IAM User を個別作成・管理 100 アカウント × 10 人 = 1,000 IAM User | Organizations 全アカウントを Permission Sets で一元管理 グループ単位で割り当て・変更が即時反映 |
| MFA 強制 | IAM ポリシーで aws:MultiFactorAuthPresent 条件付与が必要アカウント毎に設定・見落としリスクあり | Identity Center の Session Policy で組織全体に一括強制 設定漏れをアーキテクチャ的に排除 |
| 監査 | CloudTrail (各 AWS アカウント個別) IAM User 名のみで実在ユーザーのトレースが困難 | CloudTrail + Identity Center アクセスポータルログ 外部 IdP の実在ユーザー名まで追跡可能 |
| IdP 統合 | 非対応 (IAM User は AWS 内部 ID) | Entra ID / Okta の SAML 2.0 + SCIM v2.0 対応 ユーザー/グループの自動プロビジョニング可 |
| マルチアカウント | アカウント毎に IAM User 作成・権限付与が必要 スケールが困難 | Organizations 配下の全アカウントに一元適用 新規アカウント追加時も Permission Sets を割り当てるだけ |
| コスト | 追加料金なし | 追加料金なし |
判断基準:
– Organizations を使ったマルチアカウント環境 → Identity Center 一択
– 単一アカウント + CI/CD パイプラインのみ → IAM Role (OIDC) で対応可
– 長期 Access Key が存在する → 早期に Identity Center へ移行して Access Key を廃止
3-3. 移行戦略: IAM User → Identity Center
既存 IAM User 環境から Identity Center へ移行する場合、4 フェーズの段階移行を推奨する。既存システムへの影響を最小化しながら、組織全体の Identity Center 移行を安全に完了できる。
Phase 1: Identity Center 有効化 + Permission Sets 作成
Organizations 管理アカウントで Identity Center を有効化し、既存 IAM ポリシーと同等の Permission Sets を作成する。この時点では既存 IAM User には影響が生じない。
# Identity Center の有効化 (管理アカウントで実行)
aws organizations enable-aws-service-access \
--service-principal sso.amazonaws.com
Phase 2: 既存ユーザーへのアクセスポータル招待 (並行稼働)
既存 IAM User を Identity Center のユーザーとして招待し、アクセスポータルからの SSO ログインを有効化する。IAM User / Identity Center の両方が使える「並行稼働」期間を 2〜4 週間設け、開発者がアクセスポータルの操作に習熟する時間を確保する。
Phase 3: Access Key 無効化 + Identity Center へ完全移行
aws iam get-access-key-last-used で最終使用日を確認し、未使用 Access Key から順に無効化する。全 Access Key の無効化後に IAM User を削除する。
# Access Key の最終使用日を確認
aws iam list-access-keys --user-name <username>
aws iam get-access-key-last-used --access-key-id <AKID>
# Access Key の無効化
aws iam update-access-key \
--user-name <username> \
--access-key-id <AKID> \
--status Inactive
Phase 4: External IdP 統合 + SCIM 自動プロビジョニング有効化
社内ディレクトリ (Entra ID/Okta) を Identity Center の External IdP として統合し、ユーザー/グループの SCIM 自動プロビジョニングを有効化する (§6 で詳述)。以降、入退社・異動に応じたアクセス権限の付与・剥奪が自動化される。
3-4. IAM Identity Center 有効化 + 基本設定 Terraform
IAM Identity Center の有効化と Identity Store のユーザー/グループ管理を Terraform で実装する。data "aws_ssoadmin_instances" で Identity Center の ARN と Identity Store ID を取得するのが起点となる。
# Identity Center インスタンス情報の取得
data "aws_ssoadmin_instances" "main" {}
locals {
sso_instance_arn = tolist(data.aws_ssoadmin_instances.main.arns)[0]
identity_store_id = tolist(data.aws_ssoadmin_instances.main.identity_store_ids)[0]
}
# グループの作成 (開発チーム)
resource "aws_identitystore_group" "developers" {
identity_store_id = local.identity_store_id
display_name= "Developers"
description = "開発チーム - DeveloperAccess Permission Set を割り当て"
}
# グループの作成 (管理者)
resource "aws_identitystore_group" "admins" {
identity_store_id = local.identity_store_id
display_name= "Admins"
description = "管理者チーム - AdminAccess Permission Set を割り当て"
}
# ユーザーの作成 (External IdP 未使用の場合)
resource "aws_identitystore_user" "example_user" {
identity_store_id = local.identity_store_id
display_name= "Taro Yamada"
user_name= "taro.yamada"
name {
given_name = "Taro"
family_name = "Yamada"
}
emails {
value= "taro.yamada@example.com"
primary = true
}
}
# ユーザーをグループに追加
resource "aws_identitystore_group_membership" "developer_member" {
identity_store_id = local.identity_store_id
group_id = aws_identitystore_group.developers.group_id
member_id= aws_identitystore_user.example_user.user_id
}
Terraform リソース一覧 (§3 スコープ):
| リソース / データソース | 用途 |
|---|---|
data.aws_ssoadmin_instances | Identity Center ARN / Identity Store ID 取得 |
aws_identitystore_group | Identity Store グループ作成 |
aws_identitystore_user | Identity Store ユーザー作成 (External IdP 未使用時) |
aws_identitystore_group_membership | ユーザー → グループへの割り当て |
Permission Sets の定義と AWS アカウントへの割り当ては §4 で詳述する。
3-5. AWS CLI + コンソール確認
Identity Center 有効化後、以下のコマンドで設定を確認する。
# Identity Center インスタンス一覧 (ARN と Identity Store ID を確認)
aws sso-admin list-instances
# Permission Sets 一覧 (§4 作成後に実行)
aws sso-admin list-permission-sets \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXXXXXXXXXXXXX"
# Identity Store ユーザー一覧
aws identitystore list-users \
--identity-store-id "d-XXXXXXXXXX"
# Identity Store グループ一覧
aws identitystore list-groups \
--identity-store-id "d-XXXXXXXXXX"
# AWS アカウントへの割り当て確認 (§4 作成後に実行)
aws sso-admin list-account-assignments \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXXXXXXXXXXXXX" \
--account-id "123456789012" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXXXXXXXXXXXXX/ps-XXXXXXXXXXXXXXX"
コンソール確認手順:
- AWS コンソール → IAM Identity Center を開く (Organizations 管理アカウントで操作)
- Settings → Identity source (AWS Identity Store / External IdP の確認)
- Users / Groups → ユーザー・グループ一覧と割り当て状況の確認
- Permission sets → 作成済み Permission Sets の一覧 (§4 以降で確認)
- AWS accounts → Organizations 配下のアカウントへの Permission Sets 割り当て状況
関連記事:
– セキュリティ Vol1 (GuardDuty + Security Hub): GuardDuty × Security Hub 本番運用ガイド — Vol1 の検知層と本 Vol の統制層を組み合わせることで多層防御が完成する
– EKS Vol2 (IRSA): EKS IRSA 本番ガイド — IRSA と Identity Center を組み合わせることでマルチアカウントの Pod 権限管理も一元化できる
- マルチアカウント: Organizations 環境ならば Identity Center 一択 — アカウント数が増えるほど管理コストが指数的に減少
- Access Key 廃止: IAM User の長期 Access Key を STS 一時認証情報 (TTL=1h) に置換 — 漏洩リスクをゼロに近づける
- MFA 強制化: Identity Center の Session Policy で MFA 必須を組織全体に一括適用 — アカウント毎の設定漏れをアーキテクチャ的に排除
- External IdP 統合: Entra ID / Okta の既存ディレクトリを SAML 2.0 + SCIM v2.0 で統合 — 入退社対応を自動化
- 監査強化: Identity Center アクセスポータルログ + CloudTrail で外部 IdP の実在ユーザー名まで追跡可能
- 移行計画: Phase1 並行稼働 → Phase2 Access Key 無効化 → Phase3 IAM User 削除 の 3 ステップで安全移行
4. Permission Sets 設計パターン + Inline / Customer Managed Policy 使い分け

4-1. Permission Sets とは
IAM Identity Center における「権限テンプレート」が Permission Sets だ。1 つの Permission Set は AWS Managed Policy・Inline Policy・Customer Managed Policy・Permission Boundary の組み合わせで構成され、各 AWS アカウントとグループ/ユーザーに割り当てる形で機能する。
Permission Sets の最大の強みはスケーラビリティだ。1 つの Permission Set を複数アカウントに適用できるため、100 アカウント規模の Organizations 環境でも権限管理の複雑度が増大しない。IAM User/Role をアカウントごとに個別管理していた従来手法と比べると、ポリシー変更時の反映工数が劇的に削減できる。
従来の IAM Role は各アカウントに個別作成が必要だった。Permission Sets では Identity Center 側で一元定義し、アカウントへの割り当て (Account Assignment) によってプロビジョニングされる。割り当て変更は Identity Center の API 経由で行われ、各アカウントへの同期は自動実行される。プロビジョニングが完了すると、対象アカウント内に対応する IAM Role が自動作成される仕組みだ。
Permission Sets と IAM Role の関係は正確に把握しておく必要がある。Permission Set をアカウントに割り当てると、そのアカウントに AWSReservedSSO_<PermissionSetName>_<Hash> という命名規則の IAM Role が自動作成される。この Role を AWS コンソールや CLI で直接編集してはならない。Identity Center 側で Permission Set を更新すれば、プロビジョニングによって各アカウントの IAM Role へ自動反映される。手動変更はプロビジョニングで上書きされるため、必ず Identity Center を経由した変更を徹底する。
エンドユーザーの体験としては、AWS Access Portal (旧 SSO Portal) にサインインすると、自分に割り当てられた Permission Set × アカウントの組み合わせ一覧が表示される。各エントリをクリックすれば自動的に STS 一時認証情報が発行され、コンソールまたは CLI でそのアカウントへアクセスできる。フェデレーション認証が透過的に行われるため、ユーザーは IAM Access Key を一切管理する必要がない。
Permission Boundary の設定も Permission Sets に含められる。Permission Boundary は「Permission Set で付与できる最大権限の上限」を定義するものであり、誤操作やポリシーの肥大化による権限昇格を防止する重要な防衛ラインとなる。詳細は §7 で解説する。
4-2. Permission Sets 6 種テンプレ
標準的な Organizations 環境で必要な Permission Set の構成パターンを以下に示す。本番環境への AdministratorAccess 割り当ては最小権限の原則に反するため、原則禁止とする。緊急時の Break Glass アカウント運用については §7 で詳解する。
| Permission Set 名 | 用途 | ベース Policy | 付与権限範囲 |
|---|---|---|---|
| AdminAccess | 管理者 | AdministratorAccess | 全権限 (非本番のみ推奨) |
| PowerUserAccess | 上級開発者 | PowerUserAccess | IAM 以外の全権限 |
| DeveloperAccess | 開発者 | カスタム | 担当サービスのみ |
| ReadOnlyAccess | 監査・閲覧 | ReadOnlyAccess | 読み取り専用 |
| BillingAccess | コスト管理 | Billing | コスト・予算管理のみ |
| SecurityAudit | セキュリティ | SecurityAudit | GuardDuty/Security Hub 読み取り |
各 Permission Set の設計意図を補足する。AdminAccess は Organizations 管理アカウントや非本番アカウントに限定し、本番アカウントへの割り当ては原則禁止だ。PowerUserAccess は IAM を除く全 AWS サービスを操作できるため上級開発者向けに有効だが、本番環境では Customer Managed Policy による追加制限を必ず付加する。DeveloperAccess はチームが担当するサービス (例: ECS・ECR・CloudWatch・S3) のみをホワイトリスト形式で許可するカスタム構成となり、最も維持管理コストが高い代わりに最小権限を実現できる。ReadOnlyAccess は監査・コスト分析・インシデント調査に有用で、Billing を除く全サービスの読み取り権限を持つ。BillingAccess はコスト管理部門専用とし、アプリケーション開発者には付与しない。SecurityAudit は Security Hub・GuardDuty・Config・CloudTrail の読み取りに特化し、セキュリティ部門のオンコール担当に割り当てる。
session_duration の設定は権限管理において重要な要素だ。本番アカウントは PT4H(4 時間)、開発アカウントなら PT8H(8 時間)を基準とする。長時間セッションは認証情報の漏洩リスクを高めるため、業務が完結する最短時間に設定することを徹底する。AdminAccess など高権限の Permission Set は PT1H または PT2H にまで短縮することを検討する。
MFA 再認証の要求設定も高権限 Permission Set に適用すべきだ。AdminAccess などの高権限 Permission Set には「Per session MFA」を設定することで、セッションハイジャック時の被害を限定できる。IAM Identity Center の「Authentication settings」から MFA ポリシーをアカウント横断で一元適用できる。FIDO2 セキュリティキー (YubiKey 等) や Authenticator アプリの利用を強制することで、フィッシング耐性のある MFA 体制を構築できる。
Permission Set の設計では最小権限の原則 (Principle of Least Privilege) が基本方針となる。開発者が必要なサービスのみをホワイトリスト形式で許可する DeveloperAccess は、AWS Managed Policy の PowerUserAccess よりも粒度の細かい制御が可能だ。ただし、カスタムポリシーの維持管理コストが高いため、チームの成熟度に応じて段階的に移行することを推奨する。初期は PowerUserAccess + Permission Boundary の組み合わせで開始し、インシデント・監査ログを分析しながら段階的に絞り込む手法が現実的だ。
Permission Set 命名規則は組織全体で統一する。<役割>Access (例: AdminAccess) や <チーム>-<環境>-Access (例: Backend-Prod-ReadOnly) のような体系的な命名が推奨される。
4-3. Inline Policy vs Customer Managed Policy 使い分け
Permission Set にカスタムポリシーを追加する方法は Inline Policy と Customer Managed Policy の 2 種類がある。それぞれの特性を理解して適切に使い分けることが、運用品質の鍵を握る。
Inline Policy を選ぶ場合:
– 特定の Permission Set 専用であり、他の Permission Set では再利用しない
– 単純な Allow/Deny ルールで構成される短いポリシー
– バージョン管理が不要な一時的・短期的な権限設定
– Permission Set を削除する際にポリシーも同時に廃棄したい
Customer Managed Policy を選ぶ場合:
– 複数の Permission Set に同一ポリシーを適用する
– ポリシーのバージョン管理 (Policy Version) と変更履歴の追跡が必要
– セキュリティチームによる集中管理が必要な重要ポリシー
– ロールバック可能にしたい本番環境向けポリシー
Customer Managed Policy を Permission Set で使用する際の注意点がある。Identity Center 側で参照するポリシーの name と path を指定するが、実際のポリシーリソース自体は割り当て先の各アカウントに存在する必要がある。Permission Boundary と同様、プロビジョニング対象アカウント全てに同名・同パスのポリシーを事前作成しておくことが前提条件だ。Terraform では aws_iam_policy リソースを各アカウントに展開するモジュール設計が有効で、Organizations の SCP と組み合わせることで全アカウントへの自動展開も実現できる。
Inline Policy と Customer Managed Policy の特性をまとめると以下の通りだ。
| 観点 | Inline Policy | Customer Managed Policy |
|---|---|---|
| 再利用性 | Permission Set 専用 (再利用不可) | 複数の Permission Set で共有可能 |
| バージョン管理 | 不可 | 最大 5 バージョン管理可能 |
| 変更適用範囲 | 対象 Permission Set のみ | 全アタッチ先に一括反映 |
| Terraform リソース | aws_ssoadmin_permission_set_inline_policy | aws_ssoadmin_customer_managed_policy_attachment |
| 削除時の挙動 | Permission Set 削除で自動廃棄 | ポリシー自体は残存 (デタッチのみ) |
| 推奨ユースケース | 一時的・単純な制御 | 組織横断ポリシー・本番重要ポリシー |
4-4. Permission Sets Terraform 完全実装
# Permission Set 作成 (DeveloperAccess 例)
resource "aws_ssoadmin_permission_set" "developer" {
name = "DeveloperAccess"
instance_arn = local.identity_center_arn
session_duration = "PT8H"
description= "開発者向け Permission Set"
}
# AWS Managed Policy アタッチ
resource "aws_ssoadmin_managed_policy_attachment" "developer_poweruser" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
managed_policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess"
}
# Customer Managed Policy アタッチ
resource "aws_ssoadmin_customer_managed_policy_attachment" "developer_custom" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
customer_managed_policy_reference {
name = aws_iam_policy.developer_custom.name
path = "/"
}
}
# アカウント割り当て (グループへの Permission Set 割り当て)
resource "aws_ssoadmin_account_assignment" "developer_dev_account" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
principal_id = aws_identitystore_group.developers.group_id
principal_type = "GROUP"
target_id = var.dev_account_id
target_type = "AWS_ACCOUNT"
}
Permission Set の変更後はプロビジョニングが必要だ。aws sso-admin provision-permission-set コマンドで同期を起動でき、list-permission-set-provisioning-status で完了を確認できる。Terraform で変更した際は terraform apply 後に自動でプロビジョニングが走るが、大規模アカウント構成では反映完了まで数分かかることがある。CI/CD パイプラインでは完了を待機するポーリング処理を組み込み、プロビジョニング失敗時にアラートを送出する設計を推奨する。
複数アカウントへの一括割り当てには for_each を活用する。アカウント × グループ × Permission Set の組み合わせをローカル変数で管理すると、変更差分の把握が容易になり、レビュー品質が向上する。
locals {
account_assignments = {
"dev_developers" = { account_id = var.dev_account_id, group = aws_identitystore_group.developers.group_id, permission_set = aws_ssoadmin_permission_set.developer.arn }
"stg_developers" = { account_id = var.stg_account_id, group = aws_identitystore_group.developers.group_id, permission_set = aws_ssoadmin_permission_set.developer.arn }
"prod_readonly"= { account_id = var.prod_account_id, group = aws_identitystore_group.developers.group_id, permission_set = aws_ssoadmin_permission_set.readonly.arn }
"prod_admin"= { account_id = var.prod_account_id, group = aws_identitystore_group.admins.group_id, permission_set = aws_ssoadmin_permission_set.admin.arn }
}
}
resource "aws_ssoadmin_account_assignment" "all" {
for_each = local.account_assignments
instance_arn = local.identity_center_arn
permission_set_arn = each.value.permission_set
principal_id = each.value.group
principal_type = "GROUP"
target_id = each.value.account_id
target_type = "AWS_ACCOUNT"
}
Inline Policy の追加も Terraform で管理できる。Permission Set 専用の単純なポリシーは jsonencode で直接記述する。
resource "aws_ssoadmin_permission_set_inline_policy" "developer_s3_readonly" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
inline_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect= "Allow"
Action= ["s3:GetObject", "s3:ListBucket"]
Resource = [
"arn:aws:s3:::${var.artifact_bucket_name}",
"arn:aws:s3:::${var.artifact_bucket_name}/*"
]
}
]
})
}
4-5. AWS CLI + コンソール確認
# Permission Set 詳細確認
aws sso-admin describe-permission-set \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX"
# アカウント割り当て一覧
aws sso-admin list-account-assignments \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--account-id "123456789012" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX"
# Permission Set のプロビジョニング状態確認
aws sso-admin list-permission-set-provisioning-status \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX"
# アタッチ済 Managed Policy 一覧
aws sso-admin list-managed-policies-in-permission-set \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX"
# 全 Permission Set 一覧
aws sso-admin list-permission-sets \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX"
# Permission Set を全アカウントへ手動プロビジョニング
aws sso-admin provision-permission-set \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX" \
--target-type ALL_PROVISIONED_ACCOUNTS
コンソールでの確認は「IAM Identity Center」→「Permission sets」から行う。各 Permission Set の詳細画面で割り当て済みアカウント・アタッチ済みポリシー・セッション時間を一覧確認できる。変更後のプロビジョニング状態も「Provisioning status」タブで追跡可能だ。CI/CD パイプラインと組み合わせる場合は、CloudTrail の ProvisionPermissionSet イベントを監視して完了を検知する実装が有効だ。
AWS CLI での日常的な権限確認では、aws sso-admin list-permission-set-provisioning-status のレスポンスにある Status フィールドが SUCCEEDED になるまで待機する処理を自動化スクリプトに組み込むと、大量アカウントへのプロビジョニング完了を確実に検知できる。
4-6. Permission Sets ライフサイクル管理
Permission Sets の変更管理は Infrastructure as Code で一元化することが鉄則だ。Terraform の state ファイルに Permission Sets の割り当て状態を保持することで、誰がいつ変更したかを git log で追跡できる。変更は PR レビューを必須とし、本番環境への Permission Set 変更は2名以上の承認を得てから terraform apply を実行する運用フローを整備する。
Permission Set の名前変更には注意が必要だ。name を変更すると、Terraform は既存の Permission Set を削除して新規作成するため、一時的にアクセス不能となる可能性もある。名前変更が必要な場合は新しい Permission Set を先に作成し、割り当てを新しい Permission Set に移行してから旧 Permission Set を削除する「ブルーグリーン方式」を採用する。
定期的な棚卸しも重要な運用タスクだ。aws sso-admin list-accounts-for-provisioned-permission-set で割り当て済みアカウントを一覧確認し、不要な割り当てを定期的に削除する。また、aws iam get-role で AWSReservedSSO_ prefix の Role が実際に利用されているか CloudTrail ログで確認し、長期間未使用の Permission Set 割り当ては削除を検討する。
新機能の段階的適用にも Permission Sets は柔軟に対応できる。新しい Permission Set をまず開発アカウント 1 件に割り当てて検証し、問題がなければ Terraform の account_assignments マップにアカウントを追加して段階的に展開する「カナリア方式」が有効だ。大規模変更は一括適用を避け、影響範囲を制限しながらロールアウトすることで、権限ミスによる広範囲インシデントを予防できる。また、Permission Set の削除前には必ず全アカウントの割り当てを外してからリソースを削除する手順を CI/CD パイプラインに組み込み、削除漏れによる Terraform エラーを防止する。
セキュリティ Vol1 の GuardDuty/Security Hub との連携についてはこちらを参照。EKS IRSA との権限設計比較は EKS Vol2 で詳解している。
- session_duration: 本番 PT4H / 開発 PT8H で最小権限の原則を適用
- AWS Managed Policy: AdministratorAccess は本番アカウントへの割り当て禁止
- Inline Policy: Permission Set 専用の単純な許可/拒否に限定
- Customer Managed Policy: 複数 Permission Set 共通ポリシーはバージョン管理付きで管理
- Permission Boundary: 最大権限の上限設定で誤操作による権限昇格を防止 (§7 で詳解)
- Account Assignment: Terraform で全アカウント × グループ × Permission Set を一元管理
5. ABAC + タグ戦略 + Session Tags Terraform 完全実装

flowchart TD
A["ユーザーログイン<br/>Identity Center"] --> B{"Session Tags 付与?"}
B -->|"あり"| C["STS AssumeRoleWithSAML<br/>Session Tags 引き継ぎ"]
B -->|"なし"| D["セッション属性なし<br/>ABAC 無効"]
C --> E["Policy Condition 評価<br/>aws:PrincipalTag/*"]
E --> F{"リソース Tags<br/>マッチング"}
F -->|"Department 一致 AND<br/>Project 一致"| G["✅ アクセス許可"]
F -->|"不一致"| H["❌ アクセス拒否"]
D --> I["通常 RBAC ポリシー<br/>で評価"]
5-1. ABAC (Attribute-Based Access Control) とは
ABAC (Attribute-Based Access Control) とは、ユーザーやリソースが持つ「属性 (タグ)」を照合して、アクセス権限を動的に付与するアクセス制御モデルです。従来の RBAC (Role-Based Access Control) では、ロールと権限を静的に定義して管理しますが、組織規模が大きくなるとロール数が爆発的に増加するという課題があります。
ABAC では IAM ポリシーの Condition ブロックに aws:PrincipalTag/* と aws:ResourceTag/* を組み合わせることで、「同じ部門のユーザーが同じ部門タグを持つリソースにアクセスできる」というルールを 1 つのポリシーで表現できます。
AWS IAM Identity Center では、Identity Store のユーザー属性を Session Tags として STS AssumeRole セッションに伝播させる機能があります。これにより、SCIM で同期された Entra ID / Okta のユーザー属性 (Department、Project 等) が Permission Set 経由で AWS セッションに自動的に反映されます。
ABAC の主なメリット:
- ロール数の削減: 部門・プロジェクト・環境の組み合わせごとにロールを作る必要がなくなる
- 動的制御: ユーザーが新規プロジェクトに参加した際、タグ更新のみで権限が即時反映される
- 一貫性: 外部 IdP の属性変更が Identity Center 経由で AWS 権限に自動連携される
- スケーラビリティ: 数千名規模の組織でも単一の ABAC ポリシーで管理可能
5-2. タグキー設計 3 軸
ABAC を機能させるためには、組織全体で統一されたタグキー設計が不可欠です。バラバラなタグキーを使うと ABAC 評価が機能しないため、Organizations の Tag Policy で強制します。
| タグキー | 値例 | 用途 |
|---|---|---|
Department | engineering / finance / security | 部門別リソースアクセス制御 |
Project | project-alpha / project-beta | プロジェクト別リソース分離 |
Environment | production / staging / development | 環境別アクセス制御 |
タグ設計の 4 つのポイント:
大文字小文字の統一:
Engineeringとengineeringは別タグとして扱われます。Organizations Tag Policy で許可値を限定し、小文字統一を強制してください。必須タグの強制: IAM ポリシーの
Deny+aws:RequestTagCondition を組み合わせ、必須タグなしのリソース作成を禁止します。これにより ABAC の網羅性を保証できます。タグ命名規則: AWS 予約プレフィックス
aws:は使用不可。Company:プレフィックスを付与する組織もありますが、ABAC Condition での記述が冗長になるため、シンプルなキー名を推奨します。Organizations Tag Policy との連携: 許可値リストを Tag Policy で管理することで、タイポや非標準値の混入を防ぎます。
# Organizations Tag Policy で Department タグの許可値を強制
resource "aws_organizations_policy" "tag_policy_department" {
name = "tag-policy-department"
type = "TAG_POLICY"
description = "Department タグの標準化"
content = jsonencode({
tags = {
Department = {
tag_value = {
"@@assign" = ["engineering", "finance", "security", "operations", "hr"]
}
enforced_for = {
"@@assign" = ["ec2:instance", "s3:bucket", "rds:db"]
}
}
}
})
}
resource "aws_organizations_policy_attachment" "tag_policy_department_root" {
policy_id = aws_organizations_policy.tag_policy_department.id
target_id = data.aws_organizations_organization.current.roots[0].id
}
5-3. Session Tags Terraform 完全実装
Identity Center の Permission Set に ABAC 対応の Inline Policy を設定し、Session Tags を活用したアクセス制御を実装します。
# ========== ABAC 対応 Permission Set ==========
resource "aws_ssoadmin_permission_set" "developer_abac" {
name = "DeveloperABAC"
instance_arn = local.identity_center_arn
description= "ABAC タグ戦略による Developer 権限 (Session Tags 必須)"
session_duration = "PT8H"
tags = {
ManagedBy = "terraform"
Purpose= "abac-developer"
}
}
# ABAC Inline Policy: Session Tags と Resource Tags を照合
resource "aws_ssoadmin_permission_set_inline_policy" "abac_s3" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer_abac.arn
inline_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "ABACDeveloperS3Access"
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
]
Resource = [
"arn:aws:s3:::*",
"arn:aws:s3:::*/*"
]
Condition = {
StringEquals = {
"aws:ResourceTag/Department" = "$${aws:PrincipalTag/Department}"
"aws:ResourceTag/Project" = "$${aws:PrincipalTag/Project}"
}
}
},
{
Sid = "DenyWithoutRequiredTags"
Effect = "Deny"
Action = [
"s3:CreateBucket",
"ec2:RunInstances"
]
Resource = "*"
Condition = {
StringNotExists = {
"aws:RequestTag/Department" = []
"aws:RequestTag/Project" = []
}
}
}
]
})
}
# Identity Store のユーザー属性マッピング (Session Tags への伝播設定)
# Terraform では aws_ssoadmin_instance_access_control_attributes リソースで管理
resource "aws_ssoadmin_instance_access_control_attributes" "abac_attributes" {
instance_arn = local.identity_center_arn
attribute {
key = "Department"
value {
source = ["$${path:enterprise.department}"]
}
}
attribute {
key = "Project"
value {
source = ["$${path:enterprise.costCenter}"]
}
}
attribute {
key = "Environment"
value {
source = ["$${path:enterprise.organization}"]
}
}
}
aws_ssoadmin_instance_access_control_attributes は Identity Center インスタンス全体の設定であるため、変更すると全ユーザーの Session Tags マッピングが変わります。本番環境ではステージング環境で事前検証を必ず実施してください。
5-4. ABAC Policy Condition パターン
ABAC ポリシーで使用できる Condition 演算子と典型的なユースケースを示します。
| 演算子 | 構文例 | 用途 |
|---|---|---|
StringEquals | "aws:ResourceTag/Department": "$${aws:PrincipalTag/Department}" | 厳密一致: 部門タグが完全一致する場合のみ許可 |
StringLike | "aws:ResourceTag/Project": "project-*" | ワイルドカード: project- プレフィックスを持つ全プロジェクトリソースに許可 |
ArnLike | "aws:ResourceTag/Owner": "$${aws:PrincipalArn}" | ARN パターン: リソースのオーナー ARN がプリンシパル ARN と一致する場合に許可 |
StringNotEquals | "aws:RequestTag/Department": "" | 否定条件: Department タグなしのリソース作成を拒否 |
StringEqualsIgnoreCase | "aws:ResourceTag/Environment": "production" | 大文字小文字無視: タグ正規化前の移行期に有効 |
マルチ条件の組み合わせ (AND 評価):
# 部門・プロジェクト・環境の 3 条件すべてが一致した場合のみ許可
Condition = {
StringEquals = {
"aws:ResourceTag/Department" = "$${aws:PrincipalTag/Department}"
"aws:ResourceTag/Project" = "$${aws:PrincipalTag/Project}"
"aws:ResourceTag/Environment" = "$${aws:PrincipalTag/Environment}"
}
}
同一 StringEquals ブロック内に複数条件を並べると AWS は AND 評価 (すべて一致) として処理します。OR 評価が必要な場合は複数の Statement に分割して記述してください。
5-5. AWS CLI + コンソール確認コマンド
ABAC 設定後の動作確認手順を示します。
# 現在のセッション情報を確認
aws sts get-caller-identity
# IAM Policy Simulator で ABAC 評価をテスト
# Department=engineering / Project=project-alpha のセッションで S3 アクセス可否を確認
aws iam simulate-principal-policy \
--policy-source-arn "arn:aws:iam::123456789012:role/DeveloperAccess" \
--action-names "s3:GetObject" \
--resource-arns "arn:aws:s3:::engineering-project-alpha-data/file.csv" \
--context-entries \
"ContextKeyName=aws:PrincipalTag/Department,ContextKeyValues=engineering,ContextKeyType=string" \
"ContextKeyName=aws:PrincipalTag/Project,ContextKeyValues=project-alpha,ContextKeyType=string" \
"ContextKeyName=aws:ResourceTag/Department,ContextKeyValues=engineering,ContextKeyType=string" \
"ContextKeyName=aws:ResourceTag/Project,ContextKeyValues=project-alpha,ContextKeyType=string"
# S3 バケットのタグを確認
aws s3api get-bucket-tagging --bucket engineering-project-alpha-data
# EC2 インスタンスの ABAC タグを確認
aws ec2 describe-tags \
--filters "Name=resource-id,Values=i-0123456789abcdef0" \
--query 'Tags[?Key==`Department`||Key==`Project`]'
# CloudTrail で AccessDenied イベントを確認 (ABAC 評価失敗の検出)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=GetObject \
--start-time "2026-01-01T00:00:00Z" \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`)]' \
--max-results 20
コンソール確認手順:
- IAM コンソール → Policy Simulator → ロール選択 → コンテキスト変数に
aws:PrincipalTag/Departmentを入力してシミュレーション実行 - Identity Center コンソール → 設定 → 属性ベースのアクセス制御 → 属性マッピングの確認
- CloudTrail コンソール → イベント履歴 →
AssumeRoleWithSAMLイベントでセッションタグ付与を確認
5-6. 関連記事クロスリンク
- セキュリティ本番運用シリーズ Vol1 – GuardDuty + Security Hub 完全活用 (WP:2331): GuardDuty Findings を Security Hub で集約・自動修復する運用設計
- EKS IRSA 本番実装ガイド Vol2 (WP:2228): Kubernetes サービスアカウントと IAM ロールの連携実装
- タグキー設計: Department / Project / Environment の 3 軸を Organization Tag Policy で標準化し、許可値リストを管理
- Session Tags 伝播: Identity Center → STS AssumeRoleWithSAML → 全セッションに自動付与 (aws_ssoadmin_instance_access_control_attributes で設定)
- Policy Condition: StringEquals で「Principal Tag = Resource Tag」の厳密マッチングを実装 (AND 条件で全軸一致を要求)
- タグ強制: aws:RequestTag/… Condition の Deny Statement で必須タグなしのリソース作成を禁止
- テスト: IAM Policy Simulator でコンテキスト変数を指定し ABAC 評価が期待通りか事前検証
- 外部 IdP 連携: Entra ID/Okta の User 属性を SCIM で Identity Store に同期 → Session Tags として自動反映 (§6 参照)
6. External IdP 連携 (Entra ID / Okta) + SAML / SCIM 自動プロビジョニング Terraform 完全実装

6-1. External IdP 連携の概要
IAM Identity Center は デフォルト Identity Store (AWS が管理する内部ディレクトリ) と 外部 IdP (External Identity Provider) の 2 種類のユーザー管理モードを持つ。エンタープライズ環境では既存の Entra ID (旧 Azure AD) や Okta をそのまま活用する構成が一般的で、SAML 2.0 によるシングルサインオン統合と SCIM (System for Cross-domain Identity Management) によるユーザー/グループ自動同期を組み合わせることで、人事異動や退職時のアクセス管理を一元化できる。
SAML 2.0 SSO フロー:
– IdP (Entra ID/Okta) が Identity Provider、Identity Center が Service Provider として動作
– ユーザーはブラウザ経由で IdP にログイン → SAML アサーション発行 → Identity Center が検証
– MFA・条件付きアクセスポリシーは IdP 側で一元管理 (AWS 側の設定を最小化できる)
SCIM による自動プロビジョニング:
– HTTP ベースのプロビジョニングプロトコル (RFC 7643/7644) で IdP ↔ Identity Center を接続
– ユーザー/グループの変更が Identity Center へ数分以内に自動反映
– 退職者アカウントの即時無効化・新入社員の自動プロビジョニングが手動操作なしで実現
Entra ID vs Okta 選択基準:
| 観点 | Entra ID (旧 Azure AD) | Okta |
|---|---|---|
| 適用場面 | Microsoft 365 環境が中心 | ベンダーニュートラルな IdP |
| SCIM サポート | ネイティブ (v2.0) | ネイティブ (v2.0) |
| コスト | M365 ライセンスに含む (P2 推奨) | 別途ライセンス |
| グループ同期 | アプリ割り当て + プロビジョニング | Push Groups 機能 |
6-2. Entra ID (旧 Azure AD) 連携
Step 1: エンタープライズアプリケーション追加
Azure ポータル → Microsoft Entra ID → エンタープライズアプリケーション → 「新しいアプリケーション」 → 「AWS IAM Identity Center」を検索して追加する。
Step 2: SAML 設定
「シングルサインオン」→「SAML」を選択。Identity Center のコンソールから SAML メタデータを取得し、以下を設定する:
| Entra ID 設定項目 | Identity Center 発行値 |
|---|---|
| 識別子 (エンティティ ID) | Identity Center の SAML metadata から取得 |
| 応答 URL (ACS URL) | https://us-east-1.signin.aws.amazon.com/platform/saml/acs/INSTANCE_ID |
| サインオン URL | 空欄可 (IdP 起点 SSO 不使用の場合) |
Step 3: 属性マッピング設定
以下の属性を Entra ID から Identity Center にマッピングする。ABAC 連携には Department/JobTitle が必須:
| Entra ID 属性 | SAML 属性 (Identity Center 側) | 用途 |
|---|---|---|
user.mail | Subject (NameID) | ユーザー識別子 |
user.displayname | https://aws.amazon.com/SAML/Attributes/RoleSessionName | セッション名 |
user.department | https://aws.amazon.com/SAML/Attributes/AccessControl:Department | ABAC タグ |
user.jobtitle | https://aws.amazon.com/SAML/Attributes/AccessControl:JobTitle | ABAC タグ |
Step 4: SCIM 有効化
Identity Center → 設定 → プロビジョニング → 「SCIM の有効化」をクリック:
1. SCIM エンドポイント URL をコピー (https://scim.us-east-1.amazonaws.com/INSTANCE_ID/scim/v2/)
2. アクセストークンを生成してコピー (表示は一度のみ。トークンは Secrets Manager で管理推奨)
Entra ID → エンタープライズアプリケーション → プロビジョニング → 「自動」を選択:
– テナント URL: 上記 SCIM エンドポイント URL
– シークレットトークン: 上記アクセストークン
– 「接続のテスト」→「保存」
Step 5: グループ割り当てと同期確認
Entra ID でアプリケーションに同期対象グループを割り当て → プロビジョニングを開始 → Identity Center のグループ画面に反映されることを確認する。
Entra ID 連携の注意事項:
– SCIM トークンの有効期限は約 90 日 → 期限切れ前に Secrets Manager でローテーション
– ネストされたグループは SCIM 同期対象外 (フラットなグループ構造を設計段階から推奨)
– グループ名にスペース/特殊文字を含めると Identity Center の DisplayName に影響する場合がある
6-3. Okta 連携
Step 1: Okta アプリケーション追加
Okta 管理コンソール → Applications → Browse App Catalog → 「AWS IAM Identity Center」を検索 → Add Integration。
Step 2: SAML 設定
Sign On タブで Identity Center の SAML メタデータを参照して設定:
| Okta 設定項目 | Identity Center 発行値 |
|---|---|
| Single sign-on URL | Identity Center の ACS URL |
| Audience URI (SP Entity ID) | Identity Center の Entity ID |
| Default RelayState | 空欄可 |
Step 3: 属性マッピング (Attribute Statements)
| Okta 属性 | SAML 属性名 (AWS) | 必須 |
|---|---|---|
user.email | Subject (NameID) | ○ |
user.displayName | RoleSessionName | ○ |
user.department | AccessControl:Department | 推奨 (ABAC) |
user.title | AccessControl:JobTitle | 推奨 (ABAC) |
Step 4: SCIM 設定 (Provisioning)
Provisioning タブ → Configure API Integration:
– API Token: Identity Center で生成した SCIM トークン
– Base URL: Identity Center の SCIM エンドポイント URL
– 「Test API Credentials」で疎通確認
Provisioning タブ → To App で以下を有効化:
| 設定項目 | 推奨 |
|---|---|
| Create Users | ✅ 有効 |
| Update User Attributes | ✅ 有効 |
| Deactivate Users | ✅ 有効 |
| Sync Password | ❌ 無効 (SSO のみ使用) |
Step 5: Push Groups 設定
Okta → Push Groups タブ → グループを選択して「Push」。Identity Center の Groups 画面に Okta のグループが反映されることを確認する。
Okta 連携の注意事項:
– Push Groups でグループを紐付け解除すると Identity Center 側のグループも削除される
– SCIM トークンの有効期限は約 90 日 → 定期ローテーションの運用手順を整備
– Reactivation: 「Reactivate users」設定を推奨 (一時停止ユーザーの復活を自動化)
6-4. Terraform 実装
外部 IdP 連携の初期設定 (SAML/SCIM の初回設定) はコンソール/CLI 操作が必要だが、同期後のグループへの Permission Sets 割り当てと ABAC 属性設定は Terraform で完全管理できる。
# --- data sources: 外部IdP同期後のグループを DisplayName で参照 ---
locals {
identity_center_arn= "arn:aws:sso:::instance/ssoins-XXXX"
identity_center_store_id = "d-XXXXXXXXXX"
}
data "aws_identitystore_group" "engineers" {
identity_store_id = local.identity_center_store_id
alternate_identifier {
unique_attribute {
attribute_path = "DisplayName"
attribute_value = "Engineers"
}
}
}
data "aws_identitystore_group" "ops" {
identity_store_id = local.identity_center_store_id
alternate_identifier {
unique_attribute {
attribute_path = "DisplayName"
attribute_value = "Operations"
}
}
}
# --- Permission Set 割り当て (外部IdP同期グループへ) ---
resource "aws_ssoadmin_account_assignment" "engineers_dev" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
principal_id = data.aws_identitystore_group.engineers.group_id
principal_type = "GROUP"
target_id = var.dev_account_id
target_type = "AWS_ACCOUNT"
}
resource "aws_ssoadmin_account_assignment" "engineers_staging" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
principal_id = data.aws_identitystore_group.engineers.group_id
principal_type = "GROUP"
target_id = var.staging_account_id
target_type = "AWS_ACCOUNT"
}
resource "aws_ssoadmin_account_assignment" "ops_prod" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.operations.arn
principal_id = data.aws_identitystore_group.ops.group_id
principal_type = "GROUP"
target_id = var.prod_account_id
target_type = "AWS_ACCOUNT"
}
# --- ABAC 用アクセス制御属性設定 ---
resource "aws_ssoadmin_instance_access_control_attributes" "main" {
instance_arn = local.identity_center_arn
attribute {
key = "Department"
value {
source = ["$${path:enterprise.department}"]
}
}
attribute {
key = "JobTitle"
value {
source = ["$${path:enterprise.title}"]
}
}
}
Terraform 運用ポイント:
– 外部 IdP のグループ名変更後は terraform plan で差分確認してから apply
– aws_identitystore_group data source は DisplayName で検索するため、グループ名変更時はコードも更新
– SCIM 同期完了 (Identity Center のグループ画面に表示されること) を確認してから terraform apply を実行
6-5. 動作確認 + AWS CLI
# 外部IdP 設定状態確認
aws sso-admin describe-instance-access-control-attribute-configuration \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--region us-east-1
# 同期されたユーザー一覧
aws identitystore list-users \
--identity-store-id "d-XXXXXXXXXX" \
--region us-east-1
# グループ一覧 (外部IdP同期グループを含む)
aws identitystore list-groups \
--identity-store-id "d-XXXXXXXXXX" \
--region us-east-1
# グループメンバー確認
aws identitystore list-group-memberships \
--identity-store-id "d-XXXXXXXXXX" \
--group-id "GROUP_ID" \
--region us-east-1
# SCIM プロビジョニングイベントを CloudTrail で確認
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=sso-directory.amazonaws.com \
--start-time "$(date -u -v-1d '+%Y-%m-%dT%H:%M:%SZ')" \
--region us-east-1 \
| jq '.Events[] | {EventName, EventTime, Username: .Username}'
SCIM トラブルシューティング:
| 症状 | 原因 | 対処 |
|---|---|---|
| ユーザーが同期されない | SCIM トークン期限切れ | Identity Center でトークン再生成 → IdP 側更新 |
| SSO ログイン失敗 | SAML 属性マッピング誤り | IdP と Identity Center の属性設定を照合 |
| グループが見当たらない | Push Groups/割り当て設定漏れ | Okta: Push Groups / Entra ID: アプリ割り当て確認 |
| ABAC タグが反映されない | Session Tags 属性マッピング欠如 | IdP 側に Department/JobTitle マッピングを追加 |
| 退職者が無効化されない | Deactivate Users 無効 | Okta/Entra ID のプロビジョニング設定を再確認 |
参考リンク:
– セキュリティ Vol1: GuardDuty/Security Hub 本番運用
– EKS Vol3: ArgoCD × ALB × Permission Sets GitOps
- SAML 設定: Entity ID / ACS URL は Identity Center の SAML メタデータから取得
- 必須属性マッピング: email (Subject) / displayName / Department (Session Tags 用)
- SCIM トークン: 90日で期限切れ → 定期ローテーション または Secrets Manager 保管
- グループ同期: Push Groups 有効化で Identity Center の グループ = IdP のグループが自動同期
- SCIM エラー確認: Identity Center の Provisioning ログ + Entra ID/Okta のプロビジョニングレポート
- テスト: 新規ユーザー追加後 5 分以内に Identity Center に反映されるか動作確認
7. 監査 + CloudTrail 連携 + Permission Boundary 完全実装

7-1. IAM Identity Center 監査の全体像
IAM Identity Center の操作はすべて CloudTrail に記録される。マルチアカウント環境では Organization Trail を活用することで、管理アカウントの CloudTrail が全メンバーアカウントのイベントを S3 に集約し、Amazon Athena でアドホック分析や定期監査レポートの自動生成が可能になる。
Identity Center に関連する CloudTrail イベントソース:
| イベントソース | 記録対象 |
|---|---|
sso-admin.amazonaws.com | Permission Sets 管理・アカウント割り当て・インスタンス設定変更 |
sso-directory.amazonaws.com | ユーザー/グループ管理・SCIM プロビジョニングイベント |
sso.amazonaws.com | アクセスポータルへのログイン・STS AssumeRoleWithSAML 実行 |
監査が特に重要な場面:
– Permission Sets の変更 (誰がいつ権限を追加/削除したか)
– アカウント割り当ての変更 (想定外のアカウントへのアクセス付与)
– 外部 IdP 設定変更 (SCIM トークン再生成・SAML メタデータ更新)
– AdministratorAccess を含む Permission Set の割り当て/解除
– SCIM プロビジョニングによるユーザー作成/削除/無効化
7-2. 重要 CloudTrail イベント + Organization Trail 設定
優先監視イベント一覧:
| イベント名 | イベントソース | 監視優先度 | 理由 |
|---|---|---|---|
CreateAccountAssignment | sso-admin | 🔴 高 | アカウントへの権限付与 |
DeleteAccountAssignment | sso-admin | 🔴 高 | アカウントからの権限剥奪 |
AttachManagedPolicyToPermissionSet | sso-admin | 🔴 高 | 管理ポリシー追加 (AdministratorAccess 含む) |
PutInlinePolicyToPermissionSet | sso-admin | 🟡 中 | Inline Policy 変更 |
CreatePermissionSet | sso-admin | 🟡 中 | 新規 Permission Set 作成 |
DeletePermissionSet | sso-admin | 🟡 中 | Permission Set 削除 |
DeleteUser | sso-directory | 🔴 高 | ユーザー削除 (退職者対応の漏れ検知) |
CreateUser | sso-directory | 🟡 中 | ユーザー作成 (SCIM 経由含む) |
Authenticate | sso | 🟢 低 | ログイン (失敗時は高に昇格) |
Federate | sso | 🟢 低 | STS AssumeRoleWithSAML 実行 |
Organization Trail Terraform 設定 (管理アカウントで作成):
# CloudTrail ログ保存 S3 バケット
resource "aws_s3_bucket" "cloudtrail_org" {
bucket = "org-cloudtrail-${data.aws_caller_identity.current.account_id}"
}
resource "aws_s3_bucket_policy" "cloudtrail_org" {
bucket = aws_s3_bucket.cloudtrail_org.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AWSCloudTrailAclCheck"
Effect = "Allow"
Principal = { Service = "cloudtrail.amazonaws.com" }
Action = "s3:GetBucketAcl"
Resource = aws_s3_bucket.cloudtrail_org.arn
},
{
Sid = "AWSCloudTrailWrite"
Effect = "Allow"
Principal = { Service = "cloudtrail.amazonaws.com" }
Action = "s3:PutObject"
Resource = "${aws_s3_bucket.cloudtrail_org.arn}/AWSLogs/*"
Condition = { StringEquals = { "s3:x-amz-acl" = "bucket-owner-full-control" } }
}
]
})
}
# Organization Trail (全メンバーアカウント + 全リージョンをカバー)
resource "aws_cloudtrail" "organization" {
name = "org-trail"
s3_bucket_name = aws_s3_bucket.cloudtrail_org.id
is_organization_trail= true
is_multi_region_trail= true
include_global_service_events = true
enable_log_file_validation = true
event_selector {
read_write_type = "All"
include_management_events = true
}
tags = {
Environment = "production"
ManagedBy= "terraform"
}
}
7-3. Athena 監査クエリ 5 選
S3 に保存された CloudTrail ログを Athena で直接クエリする。まずテーブルを作成し、以下の監査クエリを活用する。
Athena テーブル作成 (初回のみ):
CREATE EXTERNAL TABLE cloudtrail_logs (
eventversionSTRING,
useridentitySTRUCT<
type: STRING,
principalid: STRING,
arn:STRING,
accountid:STRING,
username: STRING
>,
eventtimeSTRING,
eventsource STRING,
eventnameSTRING,
awsregionSTRING,
sourceipaddressSTRING,
errorcodeSTRING,
errormessageSTRING,
requestparameters STRING,
responseelements STRING
)
PARTITIONED BY (account_id STRING, region STRING, year STRING, month STRING, day STRING)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://YOUR-CLOUDTRAIL-BUCKET/AWSLogs/ORG_ID/';
クエリ 1: Permission Set 変更履歴 (直近 7 日間)
SELECT
eventtime,
useridentity.arn AS operator_arn,
eventname,
errorcode
FROM cloudtrail_logs
WHERE eventsource = 'sso-admin.amazonaws.com'
AND eventname IN (
'CreatePermissionSet', 'DeletePermissionSet',
'AttachManagedPolicyToPermissionSet',
'DetachManagedPolicyFromPermissionSet',
'PutInlinePolicyToPermissionSet'
)
AND eventtime > to_iso8601(current_timestamp - interval '7' day)
ORDER BY eventtime DESC;
クエリ 2: アカウント割り当て変更の完全記録 (直近 30 日間)
SELECT
eventtime,
useridentity.arn AS operator_arn,
eventname,
json_extract_scalar(requestparameters, '$.targetId')AS account_id,
json_extract_scalar(requestparameters, '$.principalType') AS principal_type,
json_extract_scalar(requestparameters, '$.permissionSetArn') AS permission_set_arn
FROM cloudtrail_logs
WHERE eventsource = 'sso-admin.amazonaws.com'
AND eventname IN ('CreateAccountAssignment', 'DeleteAccountAssignment')
AND eventtime > to_iso8601(current_timestamp - interval '30' day)
ORDER BY eventtime DESC;
クエリ 3: SSO ログイン失敗の検出 (不審アクセス検知)
SELECT
eventtime,
sourceipaddress,
useridentity.username AS username,
errorcode,
errormessage,
COUNT(*) AS failure_count
FROM cloudtrail_logs
WHERE eventsource = 'sso.amazonaws.com'
AND eventname = 'Authenticate'
AND errorcode IS NOT NULL
AND eventtime > to_iso8601(current_timestamp - interval '24' hour)
GROUP BY eventtime, sourceipaddress, username, errorcode, errormessage
ORDER BY failure_count DESC;
クエリ 4: SCIM プロビジョニングイベント監査 (ユーザー追加/削除)
SELECT
eventtime,
eventname,
json_extract_scalar(requestparameters, '$.userName') AS user_name,
json_extract_scalar(requestparameters, '$.displayName') AS display_name,
errorcode
FROM cloudtrail_logs
WHERE eventsource = 'sso-directory.amazonaws.com'
AND eventname IN ('CreateUser', 'DeleteUser', 'DisableUser', 'EnableUser')
AND eventtime > to_iso8601(current_timestamp - interval '7' day)
ORDER BY eventtime DESC;
クエリ 5: AdministratorAccess 権限付与の追跡 (高リスク操作)
SELECT
eventtime,
useridentity.arn AS operator_arn,
json_extract_scalar(requestparameters, '$.managedPolicyArn') AS policy_arn,
json_extract_scalar(requestparameters, '$.permissionSetArn') AS permission_set_arn
FROM cloudtrail_logs
WHERE eventsource = 'sso-admin.amazonaws.com'
AND eventname = 'AttachManagedPolicyToPermissionSet'
AND json_extract_scalar(requestparameters, '$.managedPolicyArn')
LIKE '%AdministratorAccess%'
ORDER BY eventtime DESC;
7-4. Permission Boundary 実装
Permission Boundary は IAM エンティティに設定できる「権限の上限」ポリシー。Identity Center の Permission Sets に設定することで、Permission Set が付与する権限の最大範囲を制限できる。
有効権限の計算:
実際に付与される権限 = Permission Set ポリシー ∩ Permission Boundary
Permission Set に AdministratorAccess を追加しても、Permission Boundary が制限している操作は実行できない。IAM 権限昇格 (iam:CreateRole 等) を Boundary で一律 Deny することで、誤設定による権限過剰付与のセーフティネットになる。
Permission Boundary Terraform 実装:
# Permission Boundary ポリシー (開発者向け: 本番リソース破壊・IAM 昇格を防止)
resource "aws_iam_policy" "dev_permission_boundary" {
name = "DevPermissionBoundary"
description = "開発者向け Permission Boundary — 本番リソース破壊・IAM 昇格を防止"
path = "/"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowDevOperations"
Effect = "Allow"
Action = [
"s3:*", "ec2:Describe*", "ecs:*", "lambda:*",
"cloudwatch:*", "logs:*", "xray:*", "ssm:*"
]
Resource = "*"
},
{
Sid = "DenyProductionDestructive"
Effect = "Deny"
Action = [
"s3:DeleteBucket", "ec2:TerminateInstances",
"rds:DeleteDBInstance", "dynamodb:DeleteTable",
"cloudformation:DeleteStack"
]
Resource = "*"
Condition = {
StringEquals = { "aws:ResourceTag/Environment" = "production" }
}
},
{
Sid = "DenyIAMEscalation"
Effect = "Deny"
Action = [
"iam:CreateUser", "iam:CreateRole",
"iam:AttachRolePolicy", "iam:PutRolePolicy",
"iam:PassRole", "iam:CreatePolicyVersion"
]
Resource = "*"
}
]
})
}
# Permission Set に Customer Managed Policy Boundary を適用
resource "aws_ssoadmin_permissions_boundary_attachment" "developer_boundary" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
permissions_boundary {
customer_managed_policy_reference {
name = aws_iam_policy.dev_permission_boundary.name
path = "/"
}
}
}
# AWS Managed Policy を Boundary として使用する例 (セキュリティ監査用)
resource "aws_ssoadmin_permissions_boundary_attachment" "readonly_boundary" {
instance_arn = local.identity_center_arn
permission_set_arn = aws_ssoadmin_permission_set.security_audit.arn
permissions_boundary {
managed_policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
}
Permission Boundary 設計原則:
| パターン | 用途 | 推奨対象 |
|---|---|---|
| AWS Managed Policy を Boundary | シンプルな上限制限 (ReadOnly 等) | セキュリティ監査・読み取り専用用途 |
| Customer Managed Policy を Boundary | タグ条件・環境別の細かい制限 | 開発者向け・マルチ環境 Permission Set |
| SCP + Permission Boundary の多層防御 | 最高レベルのガバナンス | 全本番アカウント (ゼロトラスト) |
7-5. 動作確認 + AWS CLI
# Permission Boundary 設定確認
aws sso-admin get-permissions-boundary-for-permission-set \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX" \
--region us-east-1
# CloudTrail から Identity Center 操作ログを取得 (直近 1 時間)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=sso-admin.amazonaws.com \
--start-time "$(date -u -v-1H '+%Y-%m-%dT%H:%M:%SZ')" \
--region us-east-1 \
| jq '.Events[] | {EventName, EventTime}'
# Permission Set の全ポリシーを一括確認
INSTANCE_ARN="arn:aws:sso:::instance/ssoins-XXXX"
PS_ARN="arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX"
echo "=== Managed Policies ==="
aws sso-admin list-managed-policies-in-permission-set \
--instance-arn "$INSTANCE_ARN" --permission-set-arn "$PS_ARN"
echo "=== Permission Boundary ==="
aws sso-admin get-permissions-boundary-for-permission-set \
--instance-arn "$INSTANCE_ARN" --permission-set-arn "$PS_ARN"
参考リンク:
– セキュリティ Vol1: GuardDuty + Security Hub 本番運用
– 観測性 Vol1: CloudWatch Logs Insights 本番活用
- Organization Trail: 管理アカウントで is_organization_trail = true の Trail を作成し全メンバーアカウントの Identity Center 操作を S3 に集約
- 優先アラート: CreateAccountAssignment / AttachManagedPolicyToPermissionSet / DeleteUser の 3 イベントは EventBridge → SNS でリアルタイム通知を設定
- Athena パーティション: year/month/day でパーティション設定してクエリコストを最小化 (パーティション投影 Partition Projection 推奨)
- Permission Boundary: 全 Permission Set に Customer Managed Policy Boundary を適用し IAM 権限昇格 (iam:CreateRole / iam:PassRole 等) を一律 Deny
- SCP との多層防御: Permission Boundary は Permission Set レベル / SCP は OU/アカウントレベル — 両方を組み合わせてゼロトラストを実現
- 四半期棚卸し: Athena クエリ 5 で AdministratorAccess 付与履歴を定期レビューし不要な Assignment を削除
8. まとめ + Vol3予告 + 落とし穴 10 選
本記事では IAM Identity Center + Permission Sets + ABAC + External IdP 連携 + CloudTrail 監査 + Permission Boundary を Terraform で完全実装する手順を解説した。§3〜§7 の各章で「3 点セット (Terraform + AWS CLI + コンソール確認)」を網羅しており、本記事単独でマルチアカウント環境の IAM 統制層を本番稼働させることができる。
本記事で習得できた主要スキル:
– IAM Identity Center の Organizations 全体への展開と Permission Sets 6 種テンプレートを使った権限設計
– ABAC (Session Tags + Policy Condition) による動的・属性ベースのアクセス制御実装
– Entra ID / Okta との SAML 2.0 + SCIM 自動プロビジョニング統合
– CloudTrail Organization Trail + Athena 監査クエリ 5 選による運用監査基盤の構築
– Permission Boundary による IAM 権限昇格防止の多層防御
次のステップ (Vol3 完結): IAM Identity Center で確立した「統制層」に加え、Vol3 では AWS Config + Conformance Pack による「コンプライアンス自動化層」を実装し、セキュリティ 3 部作が完成した。Permission Sets と Config Rules の組み合わせで、特定の Identity Center グループのみが設定変更できるガバナンス統制が実現できる。(Vol3 を読む)
8-1. 本番運用の落とし穴 10 選
① Permission Set プロビジョニングの遅延
terraform apply 後に Permission Set の変更が各アカウントへ反映されるまで数分かかる。ProvisionPermissionSet API の完了を待たずに動作確認すると古い権限で評価される。aws sso-admin describe-permission-set-provisioning-status でステータスが SUCCEEDED になってから動作テストを実施する。
② SCIM トークン 90 日期限切れの見落とし
SCIM トークンは約 90 日で自動失効し、IdP からの同期が停止する。トークン失効後は新規ユーザーが Identity Center へ同期されなくなり気づきにくい障害となる。Secrets Manager でトークンを管理し、期限 14 日前に自動ローテーションを設定する。
③ ネストされたグループが SCIM 同期対象外
Entra ID / Okta ともにネストされたグループ (グループのメンバーにグループを含む構成) は SCIM で Identity Center に同期されない。組織設計時点でフラットなグループ構造を採用し、階層グループには依存しないアクセス設計にする。
④ Session Tags の大文字小文字区別
ABAC の Policy Condition で StringEquals を使用する場合、タグ値の大文字小文字を完全一致させる必要がある。engineering と Engineering は別の値として扱われ、意図したアクセス制御が機能しなくなる。Organizations Tag Policy でタグ値の正規化ルールを定義し、入力時の表記ゆれを防止する。
⑤ Permission Boundary と Permission Set の権限計算の誤解
「Boundary に含まれていない操作は自動的に Deny」という点を見落とし、Boundary の Allow 範囲を狭くしすぎると業務に必要な操作もできなくなる。最初は ReadOnlyAccess などの広い Boundary から始め、実際に必要な操作を確認しながら段階的に絞り込むアプローチが安全。
⑥ AdministratorAccess を本番アカウントに直接割り当て
運用の便宜上、本番アカウントのグループに AdminAccess の Permission Set を割り当てるケースがある。SCP で本番 OU への AdministratorAccess 付与を Deny し、本番環境では最小権限 Permission Set のみを許可する設計にする。Permission Boundary との組み合わせで多層防御を実現する。
⑦ 外部 IdP 設定変更時のメタデータ更新漏れ
SAML 証明書の更新や ACS URL 変更後、Identity Center 側の SAML メタデータ再インポートを忘れると SSO が全ユーザーで一斉停止する。変更手順書に「メタデータ更新 → SAML テスト (コンソール) → 全グループで動作確認」のチェックリストを組み込む。
⑧ CloudTrail Organization Trail の設定漏れ
is_organization_trail = false (デフォルト) の Trail では、管理アカウントのイベントしか記録されずメンバーアカウントの Identity Center 操作が監査対象外になる。管理アカウントで is_organization_trail = true の Trail を作成し、Organizations の信頼アクセスを有効化してから利用する。
⑨ Permission Sets のマルチリージョン反映確認漏れ
Identity Center はホームリージョンでインスタンスを管理するが、Permission Set の変更後は全対象アカウントで反映確認が必要になる場合がある。重要な変更後は list-account-assignments を実行して権限が期待どおりに反映されているか確認する。
⑩ AWS CLI プロファイルと Identity Center 認証情報の混在
aws configure で設定した長期 Access Key プロファイルと aws sso configure で設定した Identity Center プロファイルが混在すると、予期しない認証情報が使用される。AWS_PROFILE 環境変数で明示的に Identity Center プロファイルを指定し、長期 Access Key プロファイルは無効化を推奨する。
8-2. チートシート — Terraform リソース + AWS CLI クイックリファレンス
Terraform リソース早見表:
| リソース / Data Source | 用途 |
|---|---|
data.aws_ssoadmin_instances | Identity Center ARN / Identity Store ID 取得 |
aws_ssoadmin_permission_set | Permission Set 作成・セッション時間設定 |
aws_ssoadmin_managed_policy_attachment | AWS Managed Policy アタッチ |
aws_ssoadmin_customer_managed_policy_attachment | Customer Managed Policy アタッチ |
aws_ssoadmin_permission_set_inline_policy | Inline Policy 設定 (ABAC 条件等) |
aws_ssoadmin_permissions_boundary_attachment | Permission Boundary 設定 |
aws_ssoadmin_account_assignment | グループ × アカウント × Permission Set 割り当て |
aws_ssoadmin_instance_access_control_attributes | ABAC 用アクセス制御属性設定 |
data.aws_identitystore_group | 外部 IdP 同期グループを DisplayName で参照 |
aws_identitystore_user | 内部 Identity Store ユーザー管理 |
AWS CLI クイックリファレンス:
# Identity Center インスタンス一覧 (ARN + Identity Store ID を取得)
aws sso-admin list-instances --region us-east-1
# Permission Set 一覧
aws sso-admin list-permission-sets \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" --region us-east-1
# 特定アカウントへの全 Assignment 確認
aws sso-admin list-account-assignments \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" \
--account-id "123456789012" \
--permission-set-arn "arn:aws:sso:::permissionSet/ssoins-XXXX/ps-XXXX"
# ユーザー一覧 (外部 IdP 同期確認)
aws identitystore list-users \
--identity-store-id "d-XXXXXXXXXX" --region us-east-1
# グループ一覧 (Entra ID / Okta 同期グループを含む)
aws identitystore list-groups \
--identity-store-id "d-XXXXXXXXXX" --region us-east-1
# ABAC アクセス制御属性設定確認
aws sso-admin describe-instance-access-control-attribute-configuration \
--instance-arn "arn:aws:sso:::instance/ssoins-XXXX" --region us-east-1
- ✅ Vol1: GuardDuty + Security Hub 本番運用 — 検知層: 脅威検知・Findings 自動修復・Runbook 5 種
- 📖 Vol2 (本記事): IAM Identity Center + Permission Sets + ABAC — 統制層: マルチアカウント ID/権限統制
- ✅ Vol3: AWS Config + Conformance Pack + Auto Remediation 完全運用編 — コンプライアンス自動化層: Config Rules・Conformance Pack・自動修復
- Lambda 3 部作: Vol1 基礎構築 / Vol2 高度化 / Vol3 CI/CD + CodePipeline
- EKS 3 部作: Vol1 Cluster 構築 / Vol2 IRSA + Add-ons / Vol3 ArgoCD + ALB
- 観測性 3 部作: Vol1 CloudWatch Logs Insights / Vol2 X-Ray + ADOT / Vol3 Application Signals + SLO
- セキュリティ 3 部作: Vol1 GuardDuty / Vol2 IAM Identity Center (本記事) / Vol3 AWS Config + Conformance Pack ✅
前提シリーズ: セキュリティ Vol1 GuardDuty + Security Hub を読む
次を読む: セキュリティ Vol3 AWS Config + Conformance Pack + Auto Remediation 完全運用編