0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPressからS3を安全に使う — Access Keyを保存せずIAM Roleを使う理由

0
Last updated at Posted at 2026-08-16

はじめに

WordPressからAmazon S3を利用するプラグインを作ることにしました。
この記事で説明した設計を実装したWordPressプラグインをGitHubで公開しています。

作ろうと思ったきっかけは、単に「WordPressのバックアップをS3へ保存したい」と考えたからではありません。

以前、AWSを利用している中で、Access Keyの漏洩を疑う出来事を経験しました。

実際に何が起きたのかを完全に特定できたわけではありません。しかし、その経験を通して、

Access Keyは、できるだけアプリケーションに持たせない方がよいのではないか

と強く考えるようになりました。

WordPressからS3を使う方法を調べると、Access Key IDとSecret Access Keyを設定画面へ入力する方式を目にすることがあります。

確かにこれは分かりやすい方法です。

AWS Access Key ID
AWS Secret Access Key
S3 Bucket
AWS Region

これらをWordPressの管理画面で設定すれば、AWS SDKからS3へ接続できます。

しかし、EC2上でWordPressを動かしているのであれば、本当にAccess KeyをWordPressへ保存する必要があるのでしょうか。

調べていくと、AWSにはそのための仕組みがすでに用意されていました。

それが IAM Role と AWS SDKのDefault Credential Provider Chain です。

この記事では、

  1. なぜ長期Access Keyを避けたいのか
  2. IAM Roleとは何か
  3. Credential Provider Chainとは何か
  4. WordPressからS3を安全に利用するにはどう設計するか

という順番で整理します。

最後に、この考え方を実際に試すために作成したWordPressプラグインも紹介します。

1. なぜAccess Keyを避けたいのか

AWSのAccess Keyは、プログラムからAWS APIへアクセスするための認証情報です。

一般的には、

Access Key ID
Secret Access Key

の組み合わせで使用します。

IAM Userに発行したAccess Keyは長期的な認証情報です。自分で無効化・削除しない限り有効であり続けます。AWSも、可能であれば長期Access KeyではなくIAM Roleなどによる一時的な認証情報を利用することを推奨しています。

これは重要な違いです。

例えばWordPressプラグインが次のように認証情報を保存するとします。

$client = new S3Client([
    'region'  => 'ap-northeast-1',
    'version' => 'latest',
    'credentials' => [
        'key'    => $accessKey,
        'secret' => $secretKey,
    ],
]);

当然ながら、$accessKey と $secretKey をどこかから取得しなければなりません。

例えば、

WordPressデータベース
wp-config.php
環境変数
設定ファイル

などです。

問題は、秘密情報を保存した瞬間から、その秘密情報を守るという仕事が発生することです。

データベースのバックアップに入るかもしれません。

設定ファイルを誤ってGitへcommitするかもしれません。

ログへ出してしまうかもしれません。

何らかの脆弱性によってWordPress内部の情報が読み取られる可能性もあります。

Access Keyそのものが危険なのではありません。

問題は、

長期間有効な秘密情報を、アプリケーション側で管理し続けなければならない

ことです。

ならば、そもそもWordPressにAccess Keyを保存しなければよいのではないか。

そこでIAM Roleが出てきます。

2. IAM Roleとは何か

EC2上で動作するアプリケーションには、IAM Roleを使ってAWSへの権限を与えることができます。

例えば、

EC2
  ↓
IAM Role
  ↓
S3 Bucketへの必要な権限

という構成です。

EC2にはInstance Profileを通じてIAM Roleを関連付けることができ、そのRoleに基づく一時的な認証情報をEC2上のアプリケーションから利用できます。認証情報は自動的に更新されるため、アプリケーション側で長期Access Keyを管理する必要がありません。

例えばWordPressのバックアップだけを行うなら、IAM Roleには必要なS3 Bucketに対する必要最小限の操作だけを許可します。

概念的には、

WordPress
      ↓
AWS SDK
      ↓
EC2 Instance Profile
      ↓
IAM Role
      ↓
一時認証情報
      ↓
S3

となります。

ここで重要なのは、

WordPressはSecret Access Keyを保存していない

という点です。

WordPressが侵害された場合の影響を完全になくせるわけではありません。

WordPress上で任意コードを実行されれば、そのEC2に付与されたRoleの権限を悪用される可能性はあります。

だからこそIAM Roleにも、

必要なBucketの、必要な操作だけ

という最小権限を与える必要があります。

それでも、長期間有効なAccess KeyをWordPressのDBなどへ保存する方式とは、認証情報の管理方法が大きく違います。

3. Credential Provider Chainとは何か

ここで一つ疑問が出ます。

WordPressにAccess Keyを設定しないのであれば、AWS SDKはどのように認証するのでしょうか。

その仕組みが Default Credential Provider Chain です。

AWS SDK for PHPでは、S3Clientを作るときにcredentialsを明示的に指定しなければ、SDKが複数の認証情報取得方法を順番に調べ、有効な認証情報が見つかったところで利用します。

例えば、

use Aws\S3\S3Client;


$client = new S3Client([
    'version' => 'latest',
    'region'  => 'ap-northeast-1',
]);

です。

ここには、

'credentials' => [
    'key'    => '...',
    'secret' => '...',
],

がありません。

それでもAWS SDKは認証情報を探します。

現在のAWS SDK for PHPのDefault Credential Provider Chainでは、環境変数、共有AWS設定ファイル、ECS用の認証情報、そしてEC2 Instance Profileなど、複数のProviderが順番に評価されます。EC2ではInstance Metadata Serviceを通してInstance Profileに関連付けられたRoleの一時認証情報を取得できます。

大まかに表現すると、

S3Client
   ↓
Credential Provider Chain
   ├─ 環境変数にあるか?
   ├─ AWS credentials/configにあるか?
   ├─ コンテナ用認証情報があるか?
   └─ EC2 Instance Profileがあるか?
              ↓
          IAM Role

という仕組みです。

この方式のよいところは、アプリケーションコードと認証方法を分離できることです。

同じコードでも、

開発PC
→ AWS profile


EC2
→ IAM Role


コンテナ環境
→ 対応する一時認証情報

のように、実行環境に応じて認証方法を変えられます。

WordPressプラグイン側は、

「Access Key IDは何ですか?」

と利用者に尋ねる必要がありません。

4. WordPressからS3を安全に使うにはどう設計するか

ここまでをWordPressプラグインに当てはめます。

従来型の分かりやすい設計は、

WordPress管理画面
    ↓
Access Key ID入力
Secret Access Key入力
    ↓
WordPress DBに保存
    ↓
AWS SDK
    ↓
S3

です。

私が今回採用したのは、こちらです。

WordPress
    ↓
AWS SDK
    ↓
Default Credential Provider Chain
    ↓
EC2 Instance Profile
    ↓
IAM Role
    ↓
S3

WordPress側で設定するのは、例えば、

AWS Region
S3 Bucket
S3 Prefix

です。

認証情報そのものは設定しません。

コードも基本的には、

use Aws\S3\S3Client;


$client = new S3Client([
    'version' => 'latest',
    'region'  => $region,
]);

とします。

AWS SDK for PHPの公式ドキュメントでも、credentialsオプションを省略するとDefault Credential Providerが使用されることが明記されています。

これなら、

Access Key ID
Secret Access Key

をWordPressに保存する必要がありません。

IAM Role側では最小権限にする

もちろん「IAM Roleを使えば安全」というだけでは不十分です。

例えばバックアップ専用のプラグインなら、

バックアップ先Bucket
バックアップ用prefix
必要なS3操作

に権限を限定します。

つまり、

認証情報をWordPressに保存しない
+
IAM Roleを最小権限にする

という二つを組み合わせます。

実際にプラグインを作ってみた

この考え方を実際に動く形で確認するために、

Secure S3 Storage

というWordPressプラグインを作成しました。

主な用途はWordPressデータベースのS3バックアップです。

このプラグインでは、Access Key ID / Secret Access KeyをWordPressの管理画面へ入力する方式を基本設計にしていません。

AWS SDKのCredential Provider Chainを利用することで、EC2上ではIAM Roleから認証情報を取得できます。

つまり、このプラグインそのものが、

WordPressからS3を利用するために、Access KeyをWordPressへ保存する必要はない

ことを確認するための実装例でもあります。

実際にEC2へIAM Roleを割り当て、

WordPress
↓
AWS SDK
↓
IAM Role
↓
S3

の構成でバックアップの保存・取得・削除まで確認しました。

まとめ

WordPressからS3を使う場合、

Access Key ID
Secret Access Key

をWordPressへ設定する方法は分かりやすいものです。

しかし、EC2上でWordPressを運用しているのであれば、それが必ずしも最善とは限りません。

AWSには、

IAM Role
Instance Profile
一時認証情報
Default Credential Provider Chain

という仕組みがあります。AWSも、可能であれば長期Access Keyより一時的な認証情報を使うことを推奨しています。

そのため、EC2上のWordPressからS3へアクセスする場合には、

長期Access KeyをWordPressに保存する前に、IAM Roleを利用できないか検討する

ことを勧めます。

今回作成したSecure S3 Storageは、その考え方を実際のWordPressプラグインとして形にしたものです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?