レポートの読み取り役に最小権限を与える

AWSBeginner
オンラインで実践に進む

はじめに

レポートの読み取り役には今日のレポートが必要ですが、他のレポートと給与情報は非公開のままにする必要があります。読み取りを許可して対象範囲を狭め、権限の境界をテストして、削除前に権限を取り消します。

AWS Foundations で学んだ呼び出し元のアイデンティティと ARN、および S3 のオブジェクトダウンロードの知識を使ってください。この新しい VM には CLI と二つのアイデンティティが準備されています。default は演習を管理し、reader は処理を実行する役を表します。/home/labex/project で作業し、上部の AWS View とリクエストを比較します。

認定試験との関連

認定資格 試験タスク 演習内容
Cloud Practitioner (CLF-C02) タスク 2.3 IAM ポリシー、アクションとリソースの範囲、最小権限。
Solutions Architect – Associate (SAA-C03) タスク 1.1 IAM ポリシー、アクションとリソースの範囲、最小権限。
Developer – Associate (DVA-C02) タスク 2.1 IAM ポリシー、アクションとリソースの範囲、最小権限。
CloudOps Engineer – Associate (SOA-C03) タスク 4.1 IAM ポリシー、アクションとリソースの範囲、最小権限。
Security – Specialty (SCS-C03) タスク 4.2 基礎演習:IAM ポリシー、アクションとリソースの範囲、最小権限。
Data Engineer – Associate (DEA-C01) タスク 4.2 基礎演習:IAM ポリシー、アクションとリソースの範囲、最小権限。
DevOps Engineer – Professional (DOP-C02) タスク 6.1 基礎演習:IAM ポリシー、アクションとリソースの範囲、最小権限。
Solutions Architect – Professional (SAP-C02) タスク 2.3 基礎演習:IAM ポリシー、アクションとリソースの範囲、最小権限。

ラボの概要

概念図:IAM アイデンティティポリシーで S3 の今日のレポートだけを読み取り可能にし、他のレポートと給与情報を保護します。

読み取り役にレポートへのアクセスを与える

このステップでは、レポートの読み取りを許可するアイデンティティポリシーを記述して関連付けます。アイデンティティポリシーは、ユーザー、グループ、ロールに関連付けられます。許可または拒否する操作を記述し、アクセスキーは含みません。

S3 では、すでにオブジェクトの内容をダウンロードしました。ここでは、レポート処理が独自の制限されたアイデンティティで同じダウンロードを行う必要があります。操作担当者が権限を変更し、読み取り担当者が結果を確認します。データは用意されているため、認可に集中できます。

AWS Identity and Access Management(IAM)は、どのアイデンティティがどのリソースに対して操作を実行できるかを制御します。最小権限は、処理に必要なものだけを許可する考え方です。

AWS CLI のプロファイルは認証情報と設定を選びますが、権限を与えるものではありません。ここでは default が演習の操作担当者で、reader は report-reader を選びます。まず両方のアイデンティティを確認します。--profile reader は、一つのコマンドに対して処理を実行する役を選びます。get-caller-identity は、認証情報を表示せず、呼び出し元のアイデンティティを報告します。

cd /home/labex/project
aws sts get-caller-identity --query Arn --output text

デフォルトの ARN の末尾は user/iam01-operator です。ポリシー管理にはこの操作担当者のプロファイルを使い、処理のテストには reader プロファイルを使ってください。この実験の操作担当者は管理用に準備されています。本番のレポートアプリケーションは、後で練習する制限されたロールを使います。

aws sts get-caller-identity --profile reader --query Arn --output text

読み取り役の ARN の末尾は user/report-reader です。ARN、つまり Amazon Resource Name は、リソースを識別します。S3 オブジェクトの場合はバケットと完全なオブジェクトキーを含みます。バケット ARN だけでは、その中のオブジェクトを識別しません。

読み取り役には最初、ポリシーがありません。何かを許可する前に、読み取りをテストします。

aws s3api get-object --profile reader --bucket labex-iam01-reports --key reports/today.txt before.txt || true

レポートのダウンロードではなく、AccessDenied を想定します。|| true は、意図的に失敗するコマンドによって、貼り付けたコマンド列が停止しないようにします。エラーを読んでください。接続エラーは IAM による拒否の証拠ではありません。

JSON ポリシーには、重要な三つのフィールドがあります。Effect は Allow または Deny、Action はサービス操作の名前、Resource は操作が影響できる ARN を制限します。s3:GetObject はオブジェクトのバイト列の読み取りを許可します。次の * は、今日と昨日を含む reports/ プレフィックスのオブジェクトキーに一致します。private/ や別のバケットには一致しません。Version はレポートのバージョンではなく、ポリシー言語を選びます。

次のヒアドキュメントは、JSON マーカー間の行を report-policy.json に書き込みます。> はそのローカルファイルを置き換え、引用符で囲んだマーカーはシェルが内容を展開しないようにします。

cat > report-policy.json <<'JSON'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::labex-iam01-reports/reports/*"
    }
  ]
}
JSON

ファイルを書くだけでは読み取り役に認可は与えられません。put-user-policy は、このユーザーに直接保存されるポリシーであるインラインポリシーを関連付けます。--policy-name はそのポリシーを識別し、後で同じ名前を使うと更新します。file:// は、ローカルファイルから文書を読むよう CLI に指定します。

aws iam put-user-policy \
  --user-name report-reader \
  --policy-name ReportRead \
  --policy-document file://report-policy.json

更新が成功しても通常は何も表示されません。次に読み取り役の認証情報を使って、レポートを要求します。最後の引数はローカルの保存先ファイルです。

aws s3api get-object \
  --profile reader \
  --bucket labex-iam01-reports \
  --key reports/today.txt today.txt
cat today.txt

Daily orders: 145 を想定します。ETag などの S3 応答フィールドは、ダウンロードしたオブジェクトを識別します。ファイル自体にはレポートのバイト列が入っています。

aws s3api get-object \
  --profile reader \
  --bucket labex-iam01-reports \
  --key reports/yesterday.txt yesterday.txt

ポリシーは reports プレフィックス全体を対象にするため、昨日の取得も成功します。業務に必要なのは今日のレポートだけなので、次に対象範囲を狭めます。

リソースを今日のレポートに限定する

このステップでは、プレフィックスへの許可を一つのオブジェクト ARN に置き換え、他のリソースには引き続きアクセスできないことを証明します。暗黙的な拒否は、適用されるポリシーのどれもリクエストを許可していないことを意味します。無関係なオブジェクトごとに、別の Deny は必要ありません。

ポリシーを限定すると、読み取り役は今日のレポートをダウンロードできますが、他のオブジェクトの読み取りや変更のアップロードはできません。

ローカルのポリシーを置き換えます。変更するのは Resource だけです。reports/* を正確なキー reports/today.txt に置き換えます。

cat > report-policy.json <<'JSON'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::labex-iam01-reports/reports/today.txt"
    }
  ]
}
JSON

同じ読み取り役の同じインラインポリシーを更新します。ファイルを編集しても、このコマンドを送るまでは IAM は更新されません。

aws iam put-user-policy \
  --user-name report-reader \
  --policy-name ReportRead \
  --policy-document file://report-policy.json

保存されたポリシーを読み取ります。--query PolicyDocument は応答から文書を選びますが、権限を変更するものではありません。

aws iam get-user-policy \
  --user-name report-reader \
  --policy-name ReportRead \
  --query PolicyDocument

Resource の末尾が reports/today.txt であることを確認してください。次に読み取り役をもう一度テストします。

aws s3api get-object \
  --profile reader \
  --bucket labex-iam01-reports \
  --key reports/today.txt today.txt

必要なレポートは引き続きダウンロードできます。以下の各リクエストは、オブジェクト ARN が許可に一致しないため、AccessDenied で失敗するはずです。

aws s3api get-object --profile reader --bucket labex-iam01-reports --key reports/yesterday.txt yesterday-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam01-reports --key private/payroll.txt payroll-denied.txt || true
aws s3api get-object --profile reader --bucket labex-iam01-reference --key reference.txt reference-denied.txt || true

これらのオブジェクトは存在し、操作担当者は読み取れます。NoSuchKey 応答はオブジェクトがないことを示しますが、これらの権限エラーは読み取り役のリソースの境界を示します。AWS View では今日は Readable、他の三つのオブジェクトは Denied です。この表示は、同じ読み取り役として実際の読み取りリクエストを送っています。

一つのレポートに限定された読み取り役. 例:今日だけが読み取れ、他の既存オブジェクトは拒否されます。左側の文書は、保存された IAM ポリシーです。

明示的な拒否と Allow がない状態を区別する

このステップでは、private プレフィックスを明示的に保護し、操作の境界をテストします。明示的な拒否は、一致する Deny ステートメントです。他の適用されるアイデンティティポリシーからの Allow より優先されます。ステートメントの順序を変えても、Allow がそれを上書きすることはありません。

正確な読み取り許可を保持しながら、二つ目のステートメントを追加します。s3:* はすべての S3 操作に一致しますが、この Deny はこのバケットの private/ プレフィックスの下のオブジェクトに限定されています。今日のレポートへのアクセスは拒否しません。

cat > report-policy.json <<'JSON'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::labex-iam01-reports/reports/today.txt"
    },
    {
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::labex-iam01-reports/private/*"
    }
  ]
}
JSON
aws iam put-user-policy \
  --user-name report-reader \
  --policy-name ReportRead \
  --policy-document file://report-policy.json

Deny は非公開領域の境界を強化します。その優先を観察するため、一時的にこのバケットの二つ目の読み取り許可を関連付けます。これは制御されたテストです。直後に取り消してください。

cat > temporary-read.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam01-reports/*"}]}
JSON
aws iam put-user-policy \
  --user-name report-reader \
  --policy-name TemporaryRead \
  --policy-document file://temporary-read.json
aws s3api get-object --profile reader --bucket labex-iam01-reports --key private/payroll.txt payroll-denied.txt || true

TemporaryRead がこのキーを許可していても、AccessDenied を想定します。一致する明示的な Deny が優先されます。一時的な許可を取り消し、最小権限に戻します。

aws iam delete-user-policy --user-name report-reader --policy-name TemporaryRead

読み取り許可は書き込みを許可しません。upload.txt は提供された未承認の置き換えファイルです。put-object はそのバイト列を今日のキーに保存しようとしますが、読み取り役は拒否される必要があります。

aws s3api put-object --profile reader --bucket labex-iam01-reports --key reports/today.txt --body upload.txt || true

PutObject の AccessDenied を想定します。ファイルがないことやサービス障害を、この結果として扱わないでください。今日のレポートをもう一度読み、失敗した書き込みが変更していないことを確認します。

aws s3api get-object \
  --profile reader \
  --bucket labex-iam01-reports \
  --key reports/today.txt today.txt
cat today.txt

引き続き Daily orders: 145 を含む必要があります。最終的なポリシーを読み取り、限定された Allow と private の Deny を確認します。

aws iam get-user-policy \
  --user-name report-reader \
  --policy-name ReportRead \
  --query PolicyDocument

アクセスを取り消し、自分のリソースを削除する

このステップでは、読み取り役のポリシーを取り消し、この演習のレポート用バケットだけを削除します。IAM ポリシーの削除とデータの削除は別のものです。ポリシーを削除してもオブジェクトは削除されず、オブジェクトを削除しても認証情報は取り消されません。

デフォルトの操作担当者で ReportRead を削除します。delete-user-policy は、名前でインラインポリシーを削除します。

aws iam delete-user-policy --user-name report-reader --policy-name ReportRead
aws iam list-user-policies --user-name report-reader

PolicyNames は空の想定です。レポートがまだ存在する間に、読み取り役がアクセスを失ったことをテストします。

aws s3api get-object --profile reader --bucket labex-iam01-reports --key reports/today.txt revoked.txt || true

AccessDenied を想定します。次に、操作担当者として三つの正確な演習用キーを削除します。参照用バケットは準備済みのプラットフォーム用データなので、そのまま保持する必要があります。

aws s3api delete-object --bucket labex-iam01-reports --key reports/today.txt
aws s3api delete-object --bucket labex-iam01-reports --key reports/yesterday.txt
aws s3api delete-object --bucket labex-iam01-reports --key private/payroll.txt
aws s3api list-objects-v2 --bucket labex-iam01-reports

KeyCount が 0 で、Contents にオブジェクトがないことを確認してください。この認証された正常な応答は、削除前に演習用バケットが空であることを示します。

aws s3api delete-bucket --bucket labex-iam01-reports
aws s3api list-buckets --query 'Buckets[].Name'

labex-iam01-reference だけが残ります。元のバイト列を確認します。

aws s3api get-object --bucket labex-iam01-reference --key reference.txt reference.txt
cat reference.txt

Platform reference: keep を想定します。AWS View は No inline policy と Reports bucket removed を表示します。サービス停止は、削除成功ではなく利用不可として表示されます。使い捨ての準備済みアイデンティティは、実験環境の終了時に回収されます。ここでは、無関係な準備用データを保持しながら、学習者が作成した権限と演習のデータを削除しました。

まとめ

IAM アイデンティティポリシーを関連付けて更新し、Action と Resource でレポート処理を制限しました。暗黙的な拒否と明示的な拒否を比較し、読み取り権限では書き込みが認可されないことを証明しました。ポリシーを取り消し、演習用データだけを削除しました。アクセスをレビューするときは、意図した成功と禁止される操作の両方をテストしてください。保存されたポリシーだけでは、アプリケーションが正しく認可されている証拠にはなりません。

詳しくは、AWS 公式ドキュメントを参照してください:IAM ポリシーの種類と権限ステートメント.