03-5211-7750 平日|09:30~18:00

Cloudflare Secrets Store徹底検証!Workersのシークレット管理を一元化

           

サービス資料や
ホワイトペーパーはこちら

           資料を【無料】ダウンロードFREE

はじめに

Cloudflareにて新機能の[Secrets Store]がベータになりましたので検証を行ってみました。

◆Cloudflare公式ドキュメント:https://developers.cloudflare.com/secrets-store/
◆Cloudflare公式ブログ:https://blog.cloudflare.com/secrets-store-beta/

従来、各Cloudflare Workersごとに使用できるSecret機能はありました。

ただ同じ内容のSecretを使用する場合には、各Cloudflare Workersごとで同じ内容のSecretを作成するしかありませんでしたが、Secrets Storeを使用することで一元管理ができるようになります。

※既存のSecret

秘匿情報のため、アクセスできるアカウントに対して権限の指定もできます。

そしてsecret自体はCloudflareに保存される前に暗号化してから保存する仕様になっており、また暗号に使用した鍵も頻繁に更新される仕様になっているためセキュリティも高いです。

Cloudflare公式ドキュメントによると、Secrets Storeは現在、Cloudflare Workersと互換性があるのですが、今後、他の製品との統合も追加される予定とのことです。

【相談無料】Cloudflareの導入や運用について、こちらからご相談いただけます ✉️

Secrets Storeの動作検証

早速ですが検証を行っていきます。

Secrets Storeの設定画面


以下のメニュー一覧の中に新規で追加されています。



Secrets Storeについて


現在のオープンベータでは、Storeは一つしか使用できない制限がかかっています。
wranglerコマンドのドキュメントを確認しますと、Storeの作成や削除などのコマンドが載ってましたので、GAになった際には複数のSecrets Storeが管理できることになりそうです。

◆wranglerドキュメント:https://developers.cloudflare.com/workers/wrangler/commands/#secrets-store-store

Secret作成(GUI)


※現在のオープンベータでは、アカウントごとに20個までSecretの登録が可能となってます。

まずはCloudflare画面から作成を行ってみます。

下記が作成の画面になります。
現状、権限の範囲は「Workers」のみ選択ができます。


下記のように問題なく作成ができました。



Secret作成(wrangler)


wranglerコマンドから作成も可能です。
(ストアIDはCloudflareのSecrets Storeの画面から確認可能です。)

$ npx wrangler secrets-store secret create ストアID --name test-secret-01 --scopes workers --remote

Enter a secret value: … ******

Creating secret... (Name: test-secret-01, Value: REDACTED, Scopes: workers, Comment: undefined)
Select an account › XXXXXX
Created secret! (ID: XXXXXXXXXXXXXXXX)
┌────────────────┬──────────────────────────────────┬─────────────────────────────┬────┐
│ Name │ ID │ StoreID │ Comment │ Scopes │ Status │ Created │ Modified │
├────────────────┼──────────────────────────────────┼─────────────────────────────┼────┤
│ test-secret-01 │ XXXXXXXXXXXXXX │ XXXXXXXXXXXXXX │ │ workers │ pending │ 2025/5/19 7:58:10 │ 2025/5/19 7:58:10 │
└────────────────┴──────────────────────────────────┴─────────────────────────────┴────┘

私の環境だと、上記コマンドだとpermissionエラーが出てしまいました。
wranglerで再ログインを実行したら問題なく動作しましたので、もしpermissionエラーが出ましたら再ログインしてみてください。

$ npx wrangler login
$ npx wrangler whoami

wranglerコマンドで下記のようにアップデート、削除、コピーなども可能ですのでプログラム的に対応させることもできます。

◆Cloudflareドキュメント:https://developers.cloudflare.com/workers/wrangler/commands/#secrets-store-secret

●コマンド例
・list
$ npx wrangler secrets-store secret list ストアID --remote


・update
$ npx wrangler secrets-store secret update ストアID --secret-id シークレットID --scopes workers --comment duplicate-test --remote


・duplicate(copy)
$ npx wrangler secrets-store secret duplicate ストアID --secret-id シークレットID --name test-secret2 --scopes workers --comment duplicate-test --remote


・get
$ npx wrangler secrets-store secret get ストアID --secret-id シークレットID --remote


・delete
$ npx wrangler secrets-store secret delete ストアID --secret-id シークレットID --remote


Cloudflare Workers連携


Cloudflare WorkersからCloudflareのAPIを実行して値を取得して表示してみます。
今回のAPIはAccount IDとAPI Tokenが必要なので、Secrets Storeに両方とも入れておき、2つのWorkersから同じsecretが使えることを確認してみます。

◆実行するAPI:https://developers.cloudflare.com/api/resources/workers/subresources/scripts/methods/list/
※Cloudflare Workersのlistを取得するAPI



API Tokenの作成


まずはCloudflare Workersの読み取り権限をもったAPI Tokenを作成します。


Workersの読み取り権限だけが必要なのでカスタムトークンで作成します。


下記のように権限を指定しました。


概要を確認して問題なければ作成をします。


発行されたTokenは忘れずに保存しておきましょう。


作成したAPI Tokenの権限で問題なく情報が取得できるかcurlで確認をしておきます。
※アカウントIDはCloudflareの画面から確認できます。

$ curl https://api.cloudflare.com/client/v4/accounts/アカウントID/workers/scripts 
-H "Content-Type: application/json"
-H "Authorization: Bearer 作成したAPIトークン"

{
"result": [
{
...
],
"success": true,
"errors": [],
"messages": []
}


Secrets Storeに登録


Secrets StoreにアカウントIDと作成したAPIトークンを登録します。
$ npx wrangler secrets-store secret create ストアID --name test-secrets-store-api-token --scopes workers --remote

...
Enter a secret value: … ****************************************

Creating secret... (Name: test-secrets-store-api-token, Value: REDACTED, Scopes: workers, Comment: undefined)
Created secret! (ID: eef802e1d92349288c767fc3fd285a4e)
...

$ npx wrangler secrets-store secret create ストアID --name test-secrets-store-account-id --scopes workers --remote

...
Enter a secret value: … ********************************

Creating secret... (Name: test-secrets-store-account-id, Value: REDACTED, Scopes: workers, Comment: undefined)
Created secret! (ID: cd2a27f66f1744219ca416ee2232762c)
...

問題なく作成できているか確認します。
$ npx wrangler secrets-store secret list ストアID --remote

...
Listing secrets... (store-id: XXXXXXXXXXX, page: 1, per-page: 10)
┌───────────────────────────────┬──────────────────────────────────┬─────────┬─────────┬─────────┬───────────────────┬───────────────────┐
│ Name │ ID │ Comment │ Scopes │ Status │ Created │ Modified │
├───────────────────────────────┼──────────────────────────────────┼─────────┼─────────┼─────────┼───────────────────┼───────────────────┤
│ test-secret-01 │ XXXXXXXXXXX │ │ workers │ active │ 2025/5/19 7:58:10 │ 2025/5/19 7:58:11 │
├───────────────────────────────┼──────────────────────────────────┼─────────┼─────────┼─────────┼───────────────────┼───────────────────┤
│ test-secrets-store-api-token │ XXXXXXXXXXX │ │ workers │ active │ 2025/5/19 8:56:01 │ 2025/5/19 8:56:07 │
├───────────────────────────────┼──────────────────────────────────┼─────────┼─────────┼─────────┼───────────────────┼───────────────────┤
│ test-secrets-store-account-id │ XXXXXXXXXXX │ │ workers │ active │ 2025/5/19 8:56:42 │ 2025/5/19 8:56:47 │
└───────────────────────────────┴──────────────────────────────────┴─────────┴─────────┴─────────┴───────────────────┴───────────────────┘


Workers作成


2つのCloudflare Workersを作成します。
$ npm create cloudflare@latest -- test-secret-store-01
...
What would you like to start with?
│ category Hello World example

├ Which template would you like to use?
│ type Worker only

├ Which language do you want to use?
│ lang TypeScript
...

$ npm create cloudflare@latest -- test-secret-store-02
...
What would you like to start with?
│ category Hello World example

├ Which template would you like to use?
│ type Worker only

├ Which language do you want to use?
│ lang TypeScript
...

先ほど作成したsecretをbindするように、test-secret-store-01、test-secret-store-02共にwrangler.jsoncを編集します。
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "test-secret-store-01",
"main": "src/index.ts",
"compatibility_date": "2025-05-17",
"observability": {
"enabled": true
},
"secrets_store_secrets": [
{
"binding": "ACCOUNT_ID",
"store_id": "XXXXXXXXXXX",
"secret_name": "test-secrets-store-account-id"
},
{
"binding": "API_TOKEN",
"store_id": "XXXXXXXXXXX",
"secret_name": "test-secrets-store-api-token"
}
]
}

`src/index.ts`にCloudflareのAPIからCloudflare Workersの一覧を取得するコードを書きます。
認証情報はSecrets Storeから取得させるようにしています。
こちらもtest-secret-store-01、test-secret-store-02共に編集します。
export interface Env {
ACCOUNT_ID: String;
API_TOKEN: String;
}

export default {
async fetch(request: Request, env: Env): Promise<Response> {
const accountID = await env.ACCOUNT_ID.get();
const apiToken = await env.API_TOKEN.get();

const resp = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountID}/workers/scripts`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

if (!resp.ok) {
const text = await resp.text();
console.error('Fetch error:', text);
return new Response('Failed to fetch data', { status: resp.status });
}

const data = await resp.json();
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
});
},
};

私のIDEの環境だと下記エラーが出ましたが、そのまま気にせずデプロイをしてしまって大丈夫でした。


Cloudflare WorkersのコードができましたのでCloudflareにデプロイします。
$ npx wrangler deploy

Cloudflareの画面からデプロイされているか確認します。
この段階でSecrets Storeが使われてることも確認できます。


検証なので「*.workers.dev」ドメインで「test-secret-store-01」のCloudflare Workersにアクセスしてみます。
curl https://test-secret-store-01.xxx.workers.dev | jq .

{
"result": [
{
...
],
"success": true,
"errors": [],
"messages": []
}

登録されているCloudflare Workersの一覧が取得できました。
また「test-secret-store-02」のCloudflare Workersにも同じようにアクセスしてみて同じ結果が取得できることを確認します。
curl https://test-secret-store-02.xxx.workers.dev | jq .

{
"result": [
{
...
],
"success": true,
"errors": [],
"messages": []
}

これで「test-secret-store-01」、「test-secret-store-02」にて同じsecretが適用されてることが確認できました。
各Cloudflare Workersごとにsecretを配置しなくてよいので管理がしやすくなりました。

ローカルでのSecrets Storeの使い方


ローカルで開発する際にはSecrets Storeがないので開発が面倒だなと思っていたのですが、ローカルでもSecrets Storeでsecretが作成できるようになってました。

シンプルに作成コマンドの「--remote」を外してあげれば、ローカルのSecrets Storeにsecretが登録できます。
※create、 delete、 listも問題なく動作しました。
$ npx wrangler secrets-store secret create ストアID --name test-secret-01 --scopes workers

Enter a secret value: … ******

ローカルにsecretを作成した状態でローカルデプロイのコマンドを実行すれば同じように動きます。
$ npx wrangler dev

ただ1つ注意が必要なのが、間違って本番側環境に対してdeleteコマンドを実行してしまうと、workersにbindされてる状態でも躊躇なく削除されてしまいます。

削除後にCloudflareの画面から確認すると、2つSecrets Storeのsecretがbindされてるように見えます。


ただ、ブラウザからアクセスしてみるとエラー画面になってしまいました。


ローカルと本番環境を間違えてしまうと大変なことになりますので注意が必要です。
※GAされるくらいになればこういったところの制御も入るのではないかと思いますが。

アクセス権限の設定について


secretに入れる情報は基本的に秘匿情報などが入ることが多いと思います。
保存自体は暗号化されているのでセキュリティ的に安心ですが、その情報にアクセスして使用する権限についても気をつけなければいけません。

CloudflareですとSecrets Storeに対してロールベースでのアクセス権限のコントロールが可能です。

◆Cloudflare公式ドキュメント:https://developers.cloudflare.com/secrets-store/access-control/

Secrets Store関連の権限には下記があり、管理者・開発者・閲覧者といった役割でアカウントレベルで権限を分けることが可能です。
※super administratorの場合はSecrets Storeのすべての操作が可能です。



Cloudflare APIでSecrets Storeの情報を操作させる際の権限についても指定が可能です。

◆Cloudflare API(Secrets Store):https://developers.cloudflare.com/api/resources/secrets_store/subresources/stores/subresources/secrets/

アカウントAPIトークンからtokenを作成する際に下記権限が選択可能です。



適切な権限をアカウントなどに設定し、セキュアにsecretの取り扱いを行うことができます。

監査ログ


Secrets Storeの操作ログはCloudflareのaudit logsに記録されます。

◆Cloudflare公式ドキュメント:https://developers.cloudflare.com/secrets-store/audit-logs/

これにより誰が操作したのかがログとして記録されますので、作成・変更・削除されたりなどした際に原因を追うことが可能となっております。

・作成ログ例


・削除ログ例


要件によっては監査ログをストレージなどに長期保存することが求められる場合があると思います。
その場合には、log pushでaudit logsをS3などのクラウドストレージなどに送信したり、CloudflareのAPIを使用してaudit logsをダウンロードをして保存を行うことが可能です。

最後に

簡単ではありますがSecrets Storeの検証をさせて頂きました。

今までWorkersごとに同じ名前、同じ内容のsecretを作成してましたが、Secrets Storeを使用することで一元管理できるようになるので管理が非常に楽になります。

また、現在はCloudflare WorkersでしかSecrets Storeのsecretを利用することができませんが、今後Cloudflare Workers以外でも使用できるようになるということですので、管理が楽になる幅が広がりますので楽しみです。

そしてCloudflareなら上記以外でも、

 ・パフォーマンスの向上
 ・サイトの信頼性の向上
 ・セキュリティの向上

が、一つのサービスで実現できますので非常におすすめです。

Cloudflareに、アクセリアの運用サポートをプラスしたCDNサービスを提供しています

アクセリア自社CDNの開発と運用は、20年以上にわたります。それらの経験とノウハウを駆使したプロフェッショナルサポートをパッケージしたサービスが、[Solution CDN]です。
移行支援によるスムーズな導入とともに、お客様の運用負担を最小限に​とどめながら、WEBサイトのパフォーマンスとセキュリティを最大限に高めます。運用サポートはフルアウトソーシングからミニマムサポートまで、ご要望に合わせてご提供します。

Cloudflare(クラウドフレア)の導入や運用について、またそれ以外のことでもなにか気になることがございましたらお気軽にご相談下さい。

Cloudflareの導入・運用について ご相談いただけます。 導入に関するご相談だけでなく、運用についてもご相談ください。

杉木 俊文

アクセリア株式会社 サービス事業本部プラットフォーム部
Contact usお問い合わせ

サービスにご興味をお持ちの方は
お気軽にお問い合わせください。

Webからお問い合わせ

お問い合わせ

お電話からお問い合わせ

03-5211-7750

平日09:30 〜 18:00

Download資料ダウンロード

製品紹介やお役立ち資料を無料でご活用いただけます。

Magazineメルマガ登録

最新の製品情報などタイムリーな情報を配信しています。

Free Service

PageSpeed Insights シミュレータ

CDNによるコンテンツの最適化を行った場合のPageSpeed Insightsのスコアをシミュレートしてレポートします。