IAMポリシーは最小限でいい:ABAC×セッションタグで劇的に減らすアクセス制御
はじめに
AWS を利用するメンバーが増えるにつれ、IAM ロール/ポリシー数が雪だるま式に増加しがちです。小〜中規模のワークロードなら ABAC(Attribute‑Based Access Control)とセッションタグを組み合わせることで、ロールとポリシーを 1〜数個 にまで圧縮できます。
さらに、オンプレミスや閉域網で稼働する Linux サーバーのユーザー や JupyterHub の Notebook ユーザー に対しても、IAM ユーザー/アクセスキーを発行せずに AWS リソース権限を動的制御できるのが ABAC の強みです。IdP → STS → セッションタグの流れで CLI や Notebook が最小権限を自動取得できるため、鍵管理の負担と誤操作リスクを同時に削減できます。
※大規模環境では IdP・ワークロード別に複数ロールが残るケースもあるため、あくまで「最小限化」の指針としてお読みください。
ABAC が解決する 3 つの課題
課題 | 従来 (RBAC) | ABAC 導入後 |
---|---|---|
① IAM エンティティ管理 | 新メンバー加入のたびにロール選択・アタッチ | IdP 側で属性 (department / team) を付与するだけ |
② 管理コスト | ロール/ポリシーが組織拡大に比例 | ポリシーは原則 1 つ、ロールも最少構成 |
③ リアルタイム権限制御 | 部署異動時に AWS 側で再割り当て | IdP の属性を書き換えるだけで即時反映 |
モデルケース:削減効果イメージ
(社内検証値、実環境では IdP 分割・サービス別ロールにより増減します)
組織規模 RBACロール+ポリシー ABACロール+ポリシー 削減率 5部署・3チーム 15+15 1+1 97% 10部署・5チーム 50+50 1+1 99% 20部署・10チーム 200+200 1+1 99.5%
RBAC と ABAC の違い(おさらい)
比較項目 | RBAC (従来) | ABAC (属性ベース) |
---|---|---|
制御の基準 | 固定的な役割 | 動的属性 (department / team など) |
管理対象 | ロール × 環境分だけ増殖 | 1ロール+1ポリシーが基本 |
権限変更 | AWS でロール再割り当て | IdP で属性を更新するだけ |
新規参加者 | 適切なロール選定が必要 | ユーザー作成時に属性を付与 |
IdP(アイデンティティプロバイダー)の選択
IdP | 特徴 | 属性の渡し方 | 代表的な用途 |
---|---|---|---|
AWS Identity Center | AWS ネイティブ/GUI が直感的 | Attributes for access control で Key/Value を定義しセッションタグ化 | AWS が中心の環境 |
Okta | SaaS 連携が豊富 | SAML Assertion で PrincipalTag を送信 | マルチクラウド環境 |
AD FS (Active Directory Federation Services) | オンプレ AD と連携 | LDAP 属性 → SAML で転送 | 既存 AD 基盤を活かす場合 |
セッションタグ連携の実装
1. IAM Identity Center の場合
-
Settings → Attributes for access control を開く。
-
Add attribute で次の Key/Value を登録(例):
Key Value department
${enterprise.department}
team
${enterprise.team}
project
${enterprise.project}
→ これらの属性はユーザーが AWS にログインする際、自動的に セッションタグ として渡されます。(docs.aws.amazon.com)
-
Permission Set にインラインポリシーをアタッチ(後述)。
注意: Permission Set が生成するロールの信頼ポリシーは AWS が管理しています。独自ロールを手動で運用する場合のみ
sts:TagSession
を許可してください(例を後述)。sts:TagSession
がないと AssumeRole が失敗します。(docs.aws.amazon.com)
2. Okta から属性を渡す例
<saml:AttributeStatement>
<saml:Attribute Name="https://aws.amazon.com/SAML/Attributes/PrincipalTag:department">
<saml:AttributeValue>engineering</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="https://aws.amazon.com/SAML/Attributes/PrincipalTag:team">
<saml:AttributeValue>backend</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
3. 手動ロールの信頼ポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::ACCOUNT_ID:saml-provider/Okta" },
"Action": ["sts:AssumeRoleWithSAML", "sts:TagSession"]
}
]
}
4. CLI で AssumeRole + セッションタグを付与する例
セッションタグは 「渡されて初めて」 IAM ポリシーの aws:PrincipalTag/*
条件が評価されます。タグを省略したまま AssumeRole すると、条件に一致せずポリシーが implicit Deny となる点にご注意ください。
# department=engineering, team=backend を付与してロールを引き受ける例
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/AbacDemoRole \
--role-session-name cli-demo \
--tags Key=department,Value=engineering Key=team,Value=backend \
--transitive-tag-keys department team
--tags
でキーと値を指定。--transitive-tag-keys
を付けると、このセッションタグは後段のAssumeRole
でも引き継がれます。- タグを一つでも付け忘れると、
aws:PrincipalTag
条件付きのリソースアクセスは即座に拒否されます。
ワンポイント:
aws sso login
→aws sso get-role-credentials
のフローでは Permission Set 側が自動的にセッションタグを付与します。CLI での AssumeRole は 自分で明示的に--tags
を渡す必要がある、という違いを押さえておきましょう。
実践例:チーム別 S3 アクセス制御
ポリシーは 1 つだけ
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3AccessForOwnTeam",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::${aws:PrincipalTag/team}-*",
"arn:aws:s3:::${aws:PrincipalTag/team}-*/*"
],
"Condition": {
"StringLike": { "aws:PrincipalTag/team": "*" }
}
}
]
}
${aws:PrincipalTag/team}
はログインユーザーのチーム名に動的展開されます。- バケット名プレフィクス方式のため、チーム名が変わる場合はバケット名の変更も必要です。
バケット一覧を非表示にしたい場合
ListBucket
を個別バケットに限定し、s3:ListAllMyBuckets
を付けない構成を推奨します。
S3 での ABAC 制限事項
PutObject
/ DeleteObject
では s3:ExistingObjectTag
条件キーを使えません。タグ条件付き制御は GetObject
のみ対応です。(docs.aws.amazon.com)
よくある落とし穴とデバッグ
症状 | 原因 | 対処 |
---|---|---|
User is not authorized to perform: sts:TagSession |
信頼ポリシーに sts:TagSession がない |
例のとおり追加する (docs.aws.amazon.com) |
属性値のタイプミス (frontend → fronted ) |
IdP 属性と IAM ポリシーの値が不一致 | CloudTrail イベントで sessionTags を確認し綴りを修正 |
実装手順(Identity Center 版まとめ)
- ユーザー属性を登録 – Users > Attributes で
department
/team
を設定。 - Attributes for access control – Key/Value を追加しセッションタグ化。
- Permission Set 作成 – 上記ポリシーをインラインで設定。
- 動作確認 – CLI / コンソールから S3 バケットにアクセスし、想定どおり許可/拒否されるかチェック。
追加ユースケース:Linux/Jupyter ユーザー管理の簡素化
オンプレや閉域網で Linux アカウントや JupyterHub ユーザー を多数運用している場合でも、IAM ユーザーを個別に発行せずに AWS リソース権限を細かく制御できます。
シナリオ | 従来 | ABAC + セッションタグ |
---|---|---|
Bastion/踏み台 EC2 に SSH 接続する社内ユーザー | IAM ユーザーを人数分発行し、SSH キーを配布 | IdP(SAML)→EC2 Instance Connect でロールを Assume。department /team タグで S3・DynamoDB へのアクセスを動的制御 |
JupyterHub (コンテナ or EC2) 利用者 | プロジェクトごとに異なる IAM ロールを 事前に用意し、aws_credentials を Notebook にコピー |
JupyterHub OIDC/SAML 認証 → セッションタグ付きで AssumeRole。Notebook 内から Boto3 を使う際にタグ値で自動権限制御 |
社内 Linux サーバーで CLI 実行 | \~/.aws/credentials に個別 IAM ユーザーキーを格納 | SSO Login (aws sso login ) だけでクレデンシャル取得。タグで S3 prefix や Glue データベースへのアクセスを縦割り管理 |
ポイントは 「IAM ユーザーを一切作らず、IdP ⇨ STS ⇨ セッションタグ」という経路ですべてを完結 させること。Linux 側では aws sso login
、JupyterHub 側では OIDC/SAML プラグインを使ってセッションタグを透過的に渡せます。
ベネフィット
- 鍵漏えいリスク削減(IAM Access Key が不要)
- 退職者・異動者は IdP 側でアカウントを Disable/属性更新するだけ
- Notebook 共有時も「タグに基づく最小権限」が自動適用され、誤操作リスクを最小化
まとめ
- ABAC×セッションタグを導入すれば、IAM 運用負荷を 桁違い に削減可能。
- ポリシーは最小限で済むが、
sts:TagSession
付与や S3 のタグ制約など実装上のハマりポイントを押さえることが重要。 - IdP の属性設計を丁寧に行い、タグ値の命名規則を組織で統一すれば、大規模環境でもスケーラブルに運用できます。
参考文献
-
ABAC認証を使用して属性に基づいて権限を定義する ([docs.aws.amazon.com]
(https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)) -
AWS Identity Center – Attributes for access control ((https://docs.aws.amazon.com/singlesignon/latest/userguide/configure-abac-attributes.html?utm_source=chatgpt.com))
-
IAM User Guide – Session Tags &
sts:TagSession
((https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html?utm_source=chatgpt.com)) -
Amazon S3 User Guide – Tagging and Access‑Control Policies (ExistingObjectTag 制限) ((https://docs.aws.amazon.com/AmazonS3/latest/userguide/tagging-and-policies.html?utm_source=chatgpt.com))