結論

EC2 から S3 にアクセスさせるとき、長期 Access Key をインスタンスやアプリケーションに配る設計は避けます。標準形は IAM Role を EC2 に関連付け、一時認証情報で S3 を呼ぶ ことです。

ただし、IAM Role だけを見ていると設計を読み間違えます。実際には「EC2 が S3 に何をできるか」と「誰がその Role を EC2 に渡せるか」は別の論点です。後者を制御するのが iam:PassRole です。

この記事では、EC2 + S3 の権限設計を、IAM Role / Instance Profile / iam:PassRole に分けて整理します。

Access Key 配布が危ない理由

EC2 上のアプリケーションに次のような値を置くと、実装は簡単です。

```env

AWS_ACCESS_KEY_ID=AKIAxxxxxxxxxxxx

AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxx

```

しかし、これは運用上かなり扱いづらい設計です。Access Key は長期認証情報なので、漏れるとそのまま悪用されます。環境変数、ログ、AMI、バックアップ、CI/CD の設定、開発者の手元。置いた場所が増えるほど回収不能になります。

EC2 で AWS SDK を使うなら、Role ベースの一時認証情報を使う方が自然です。SDK は標準の認証プロバイダチェーンで認証情報を探すため、アプリケーションコードに鍵を埋め込む必要はありません。

IAM Role と Instance Profile の関係

EC2 に S3 権限を渡す構成は、ざっくり次の部品で成り立ちます。

| 部品 | 見るべきポイント |

|---|---|

| IAM Policy | S3 のどの API を、どのリソースに許可するか |

| IAM Role | EC2 が引き受ける権限セット |

| Trust Policy | EC2 サービスがその Role を引き受けられるか |

| Instance Profile | Role を EC2 インスタンスに関連付けるための枠 |

S3 の読み取りだけでよいなら、最初から広い権限を付けない方がいいです。

```json

{

"Version": "2012-10-17",

"Statement": [

{

"Effect": "Allow",

"Action": ["s3:GetObject"],

"Resource": "arn:aws:s3:::example-bucket/*"

}

]

}

```

たとえばログアップロードも必要なら `s3:PutObject` を追加します。バケット一覧が必要なら `s3:ListBucket` も検討します。逆に、必要性を説明できない `AmazonS3FullAccess` は疑っていいです。

iam:PassRole を別枠で考える

IAM Role に S3 権限を付けても、それを誰でも EC2 に付けられるわけではありません。EC2 を作成・変更する人や自動化ツールには、その Role を EC2 サービスへ���す権限が必要です。

それが `iam:PassRole` です。

この権限は、S3 を操作する権限ではありません。権限を持った Role をサービスに渡す権限です。だから雑に広げると危険です。

```json

{

"Effect": "Allow",

"Action": "iam:PassRole",

"Resource": "arn:aws:iam::123456789012:role/ec2-s3-readonly-role",

"Condition": {

"StringEquals": {

"iam:PassedToService": "ec2.amazonaws.com"

}

}

}

```

この例では、渡せる Role を 1 つに絞り、渡し先サービスも EC2 に限定しています。Role の権限が強いほど、この制御は重要になります。

責任を分けるとレビューしやすい

レビューでは、次の 2 つを分けて見ると判断しやすくなります。

| レビュー対象 | 質問 |

|---|---|

| EC2 Role のポリシー | この EC2 は S3 に対して何をしてよいのか |

| iam:PassRole の許可 | 誰が、どの Role を、どのサービスに渡してよいのか |

この分離ができていないと、「S3 は読み取りだけだから安全」と思っていたら、実は強い Role を自由に渡せる、という状態になりがちです。

例えばこう確認する

実務では、次のような観点で確認します。

  • アプリケーション設定に Access Key が残っていないか
  • EC2 Role の Resource が対象バケットや prefix に絞られているか
  • `s3:*` や `Resource: *` を説明なしに使っていないか
  • `iam:PassRole` の Resource が特定 Role に限定されているか
  • `iam:PassedToService` で EC2 向けに制限しているか
  • CloudTrail で RunInstances、AssociateIamInstanceProfile、PassRole 相当の操作を追えるか

特に自動化基盤に広い PassRole を渡す場合は注意が必要です。Terraform や CI/CD は便利ですが、便利なものに強い権限を持たせるほど、境界を明確にしておく必要があります。

まとめ

EC2 に S3 権限を渡す設計では、Access Key を配らず IAM Role を使うのが基本です。そのうえで、Role の中身と iam:PassRole を分けてレビューします。

  • EC2 のアプリケーションには長期 Access Key を置かない
  • S3 権限は IAM Role に集約する
  • Instance Profile 経由で EC2 に関連付ける
  • iam:PassRole は対象 Role と渡し先サービスを絞る

IAM は「動くか」だけで見るとすぐ雑になります。誰が、何を、どこへ渡せるのか。そこまで分けて見ると、EC2 と S3 の連携はかなり安全に設計できます。