投稿

ラベル(セキュリティ)が付いた投稿を表示しています

IAM グループを使うべき理由:ユーザーへの直接ポリシーアタッチとの比較

新しい開発者が入社するたびに、IAM ユーザーを作成してポリシーを一枚一枚アタッチしていた運用が、ある日突然破綻する。10人のユーザーに同じポリシーを直接アタッチしていた環境で権限変更が必要になったとき、10回の手作業が発生する。IAM グループはこの問題を構造的に解決するための仕組みだ。 TL;DR:IAM グループ vs. ユーザーへの直接アタッチ 観点 ユーザーへの直接アタッチ IAM グループ経由 権限変更のコスト 対象ユーザー数分の操作が必要 グループポリシーを1回変更するだけ 新規ユーザーへの権限付与 毎回ポリシーを手動アタッチ グループに追加するだけ 権限の一貫性 ユーザーごとにズレが生じやすい グループ単位で統一される 監査・レビューのしやすさ ユーザーごとに確認が必要 グループのポリシーを見れば全体像が分かる IAM ポリシー上限への影響 ユーザーあたりのアタッチ上限を消費 グループ側で集約できる IAM グループの仕組みを理解する IAM グループはユーザーの集合体であり、それ自体がプリンシパルとして AWS リソースにアクセスするわけではない。グループにアタッチされたポリシーは、そのグループに所属するすべての IAM ユーザーに対して有効になる。ユーザーが複数のグループに所属している場合、各グループのポリシーはすべて評価される。 重要な点として、IAM グループは IAM ロールとは異なり、フェデレーションユーザーや AWS サービスに対してアタッチすることはできない。また、グループをネストする(グループの中にグループを入れる)ことも IAM ではサポートされていない。 graph TD GroupDev["IAM グループ: Developers"] GroupOps["IAM グループ: Operators"] PolicyS3["ポリシー: S3ReadOnly"] PolicyEC2["ポリシー: EC2FullAccess"] ...

AWS KMS完全ガイド:S3暗号化にAWS管理キーとCMKのどちらを選ぶべきか

S3バケットの暗号化設定を検討していると、必ずぶつかるのが「AWS管理キーで十分か、それともCustomer Managed Key(CMK)が必要か」という判断だ。コスト、制御レベル、監査要件——どれを優先するかによって答えが変わる。この記事では、AWS KMSの仕組みを実際の運用視点で整理し、S3暗号化における選択基準とコスト計算の考え方を具体的に解説する。 TL;DR:AWS管理キー vs Customer Managed Key(CMK) 比較項目 AWS管理キー(aws/s3) Customer Managed Key(CMK) キーポリシーの制御 不可(AWSが管理) 可能(完全制御) キーローテーション 1年(約365日)自動・変更不可 有効化すると1年ごとに自動(設定可能) クロスアカウントアクセス 不可 可能(キーポリシーで制御) キーの無効化・削除 不可 可能(削除は7〜30日の待機期間あり) CloudTrail監査 KMS API呼び出しはログに記録される KMS API呼び出しはログに記録される KMSキー料金 無料 月額料金あり(最新料金はAWS公式参照) APIリクエスト料金 発生する 発生する 主なユースケース シンプルな暗号化、コスト優先 コンプライアンス、クロスアカウント、アクセス制御 AWS KMSの仕組み:S3暗号化のデータフロー KMSを理解する上で最も重要な概念は、KMSが直接データを暗号化するわけではないという点だ。KMSはデータキー(Data K...

なぜSecretsManagerを使うのか?ハードコーディングが招く本当のリスク

「リポジトリはプライベートだからDBパスワードをコードに書いても大丈夫」——この判断が、本番インシデントの引き金になるケースを何度も見てきた。AWS Secrets Managerを使った自動ローテーションの仕組みを理解すれば、なぜハードコーディングが構造的なリスクなのかが明確になる。 TL;DR:Secrets Managerとハードコーディングの比較 観点 ハードコーディング Secrets Manager 認証情報の漏洩経路 Gitログ、CI/CDログ、コアダンプ IAMポリシーで制御、監査ログあり パスワードローテーション 手動。デプロイが必要 自動。アプリ再起動不要 アクセス制御 コードを読める人全員 IAMロール単位で最小権限 監査証跡 なし CloudTrailに全API呼び出しを記録 複数環境管理 環境ごとに別ファイル管理が必要 シークレット名のパスで分離可能 なぜ「プライベートリポジトリだから安全」は成立しないのか プライベートリポジトリはアクセス制御の一層に過ぎない。問題はそこではなく、認証情報がコードに埋め込まれた瞬間に複数の経路で漏洩リスクが生まれる点にある。 Gitの履歴は削除できない :一度コミットされたパスワードは、後からファイルを修正しても git log -p で復元できる。 git filter-repo で履歴を書き換えても、フォークやローカルクローンには残る。 CI/CDパイプラインのログ :環境変数として渡した場合でも、デバッグログやエラートレースに平文で出力されることがある。 コアダンプとヒープダンプ :アプリケーションがクラッシュした際、メモリ上の文字列がダンプファイルに含まれる。 内部脅威 :リポジトリへのアクセス権を持つ開発者が退職した後も、その認証情報は有効なまま残る。 ハードコーディングされたパスワードは、金庫の鍵を金庫の扉に貼り付けているようなものだ。扉が閉まっていても、鍵が見えていれば意味がない。 Secrets Managerはこれらの問題を、認証情報をコードから完全に分離することで解...

EC2インスタンスが突然消えた — CloudTrail Event Historyで削除者を特定する方法

月曜の朝、本番EC2インスタンスが消えていた。Slackに通知が飛んで、誰もやっていないと言う。こういう状況で最初に開くべきツールが CloudTrail Event History だ。 TerminateInstances アクションは必ずCloudTrailに記録されており、どのIAMユーザーまたはロールが実行したかを数分で特定できる。 TL;DR — CloudTrailでEC2削除者を特定する ステップ 操作 確認ポイント 1 Event Historyを開く リージョンが正しいか確認 2 イベント名で TerminateInstances をフィルタ 削除時刻の前後30分を絞り込む 3 イベント詳細を展開 userIdentity フィールドを確認 4 CLIで同じクエリを実行 インスタンスIDで絞り込み精度を上げる 5 再発防止策を実施 Termination ProtectionまたはSCP適用 CloudTrail Event Historyの仕組みを理解する CloudTrailはAWSアカウント内のAPI呼び出しを記録するサービスだ。EC2の TerminateInstances も例外ではなく、マネジメントコンソール、CLI、SDK、Auto Scalingなど、どの経路で実行されても同じイベントとして記録される。 Event Historyは追加設定なしで有効になっており、過去90日間のマネジメントイベントを保持する。S3バケットへの長期保存にはTrailの設定が必要だが、90日以内の調査であればEvent Historyだけで完結する。 graph LR A["コンソール操作"] --> CT["CloudTrail"] B["AWS CLI"] --> CT C["SDK / アプリ"] --> CT D["Auto Scaling"] --> CT CT --> EH[...

IAM ポリシーの基本構造:Effect・Action・Resource・Condition の違いを完全解説

IAM ポリシーの JSON を初めて読んだとき、 Effect ・ Action ・ Resource ・ Condition の四つの要素が何を制御しているのか、それぞれの境界がどこにあるのかが掴みにくい。本記事では、IAM ポリシーの基本構造を実際の運用経験をもとに解説し、よくある誤解と正しいモデルを整理する。 TL;DR:IAM ポリシー基本構造の早見表 要素 役割 必須 典型的な値の例 Effect 許可か拒否かを決定する ✅ Allow / Deny Action 対象の API アクションを指定する ✅ s3:GetObject Resource アクションを適用するリソースを限定する ✅ arn:aws:s3:::my-bucket/* Condition 追加の条件が満たされた場合のみ Statement を有効化する ❌ aws:SourceIp など IAM ポリシーの仕組み:評価モデルを理解する IAM ポリシーは、AWS がリクエストを受け取ったときに評価される一連のルールセットだ。ポリシーは一つ以上の Statement で構成され、各 Statement が「誰が・何を・どのリソースに・どんな条件で・許可または拒否するか」を定義する。AWS はリクエストを評価する際、すべての適用可能なポリシーを収集し、以下の優先順位で判定する。 graph TD A["リクエスト受信"] --> B{"明示的 Deny (いずれかのポリシー)"} B -- "あり" --> C["拒否 (Explicit Deny)"] B -- "なし" --> D{"明示的 Allow (いずれかのポリシー)"} D -- "あり" --> E["許可"] D -- "なし" --> F["拒否 (Implicit De...

S3 署名付きURL(Presigned URL)の生成方法:1時間の有効期限で非公開ファイルへの一時アクセスを付与する

非公開のS3バケットに保存されたファイルを、認証なしのユーザーに一時的にダウンロードさせたい場面は頻繁に発生する。IAMユーザーを発行するわけにもいかず、バケットをパブリックにするのは論外だ。そこで使うのがS3署名付きURL(Presigned URL)で、これはAWS SDKを使って1時間などの有効期限付きで発行できる。 TL;DR:S3署名付きURLの要点 項目 内容 目的 非公開S3オブジェクトへの一時的なHTTPアクセスを付与する 有効期限 生成時に指定(例:3600秒 = 1時間) 認証情報 生成者のIAM認証情報がURLに埋め込まれる 主な用途 ファイルダウンロードリンク、アップロード委譲 バケットポリシー パブリックアクセス設定の変更は不要 SDK Python(boto3)、JavaScript(AWS SDK v3)など主要言語対応 S3署名付きURLの仕組み 署名付きURLは、IAM認証情報(アクセスキーまたはIAMロール)を使ってリクエストに署名したURLを事前に生成する仕組みだ。URLを受け取ったユーザーは、AWSの認証情報を持っていなくても、そのURLにHTTP GETリクエストを送るだけでオブジェクトを取得できる。有効期限が切れるか、署名に使った認証情報が無効になれば、URLも機能しなくなる。 ホテルのルームキーに近い。フロントが発行した一時的なカードで、チェックアウト後は使えなくなる。マスターキーを渡しているわけではない。 重要な点として、署名付きURLの有効性は 生成時に使用したIAM認証情報の有効性に依存する 。IAMロールの一時的な認証情報(例:EC2インスタンスプロファイルやAssumeRoleで取得したトークン)を使って生成した場合、そのトークンの有効期限が署名付きURLの有効期限より先に切れると、URLも無効になる。これは見落としやすい落とし穴だ。 sequenceDiagram participant App as アプリケーションサーバー participant SDK as AWS SDK ...

EC2インスタンスIDをメタデータから取得する方法 — IMDSv2が安全な理由

サーバー上で動作するスクリプトから自分のインスタンスIDを取得したい場面は多い。デプロイスクリプト、ログ集約、Auto Scalingグループのインベントリ管理など、用途は様々だ。ただし、EC2インスタンスメタデータサービス(IMDS)には2つのバージョンが存在し、 IMDSv1とIMDSv2の選択はセキュリティ上の重大な差異 を生む。本番環境でIMDSv1を使い続けることは、SSRF(Server-Side Request Forgery)攻撃の踏み台になるリスクを放置することと同義だ。 TL;DR — IMDSv1 vs IMDSv2 早見表 観点 IMDSv1 IMDSv2 認証方式 なし(直接GETのみ) セッショントークン必須(PUT → GET) SSRF耐性 なし あり(PUT不可なSSRFはトークン取得不可) TTL制御 なし X-aws-ec2-metadata-token-ttl-secondsで指定 デフォルト状態 新規インスタンスでも有効(設定次第) IMDSv2-onlyに変更可能 推奨度 非推奨 AWS公式推奨 IMDSの仕組み — なぜインスタンス内からだけ到達できるのか EC2インスタンスメタデータサービスは、リンクローカルアドレス 169.254.169.254 で提供される。このアドレスはRFC 3927で定義されたリンクローカル範囲であり、インスタンスのネットワークインターフェース外には到達できない。つまり、インターネット経由や他のインスタンスから直接アクセスすることは原理的に不可能だ。 ただし、 SSRF脆弱性があるアプリケーションが動作している場合は話が変わる 。攻撃者がアプリケーションを経由して http://169.254.169.254/latest/meta-data/iam/security-credentials/ へリクエストを誘導できれば、インスタンスにアタッチされたIAMロールの一時クレデンシャルを盗める。IMDSv1はこのシナリオに対して無防備だ。 graph TD subgraph v1[...