目次を開く
さくらのクラウドで PaaS を作るときの認証情報 3 種の使い分け

さくらのクラウドで PaaS を作るときの認証情報 3 種の使い分け

API 駆動に踏み込んだ瞬間に現れる壁

さくらのクラウドをコンソールから手で操作している限り、認証で困ることはほとんどない。ログインすれば、あとは画面が全部やってくれる。

ところが「インフラの払い出しからアプリケーションのデプロイまでを、すべてコードから API 経由で行う」という領域に踏み込むと、風景が一変する。さくらのクラウドには実質 3 種類の認証情報が存在し、どれがどの API に通るかが一様ではないからだ。しかも、通らなかったときのエラーメッセージが必ずしも真の原因を指してくれない。結果として、本題であるはずのインフラ自動化に入る前に、認証の切り分けで数日を溶かすことになる。

EastCloud ではさくらのクラウド上でアプリケーション実行基盤(PaaS)を開発しており、コンテナのビルド、VPC・データベース・オブジェクトストレージの払い出し、コンテナ実行基盤へのデプロイまでを API から一気通貫で制御している。本稿は、その開発過程で実機検証を通じて確定させた「認証情報の地図」である。

以下に記す挙動は、すべて筆者が実際に API を叩いて確認したものである。さくらのクラウドは機能追加が活発なプラットフォームであり、ここに書かれた制約が後日解消されている可能性は十分にある。重要な判断を行う際は、公式ドキュメントと各自の環境で改めて確認されたい。


3 種類の認証情報とその役割

細部に入る前に、まず全体像を示す。

認証情報 認証方式 主な用途
サービスプリンシパル(SP) 秘密鍵で署名した JWT からトークンを取得し、Bearer で送る IAM 体系の API。プロジェクト配下のリソース操作
プロジェクトの API キー Basic 認証(トークン + シークレット) 従来からの Cloud API 系。サーバ、ディスク、アプライアンス、コンテナレジストリ、オブジェクトストレージのコントロール面
リソース操作 API キー Basic 認証(トークン + シークレット) Terraform・usacloud などのツール群
さくらのクラウドの認証情報3種とAPIの対応関係。サービスプリンシパルはオブジェクトストレージのコントロールAPIで弾かれることがある
図1:3種類の認証情報と、それぞれが通るAPI。SPはオブジェクトストレージのコントロールAPIで弾かれることがある

要約すれば、サービスプリンシパルは「機械のための身分証」であり、API キー系は「従来から実務を支えてきた鍵」である。さくらのクラウドは現在、新しい IAM の体系と、長年運用されてきた API 体系が並走しているフェーズにある。どちらか一方だけでは、すべての API に手が届かない。

「最も新しく、最も機械向けに設計されたサービスプリンシパルを使えば全部いけるはずだ」という発想は自然だが、実際には成立しない。以下、その理由を 4 つの具体的な壁として説明する。


壁 1:プロジェクトを作る権限は、どこに付けるのか

マルチテナントの基盤を設計するとき、「顧客が 1 社増えたら、その顧客専用のプロジェクトを自動作成し、その中にリソースを積む」という構成は素直な発想である。プロジェクトが課金と権限の境界になるので、分離の単位として理にかなっている。

ところが、サービスプリンシパルの認証情報でプロジェクト作成 API(POST /iam/1.0/projects)を呼ぶと 403 permission_denied が返る。ロールの付与が足りないのだろうと考えて、オーナーを含む強い権限のロールを順に付与しても、結果は変わらない。

この壁の正体は、時期によって答えが変わる。 ここが本稿で最も注意を要する部分である。

2026 年 5 月時点:構造として不可能だった

当時、SP の認証情報で IAM のロール一覧を取得し、全件をダンプして確認したところ、用意されていたロール 26 件が、一件残らずプロジェクトスコープだった。プロジェクトより上位に効くロールが一覧に存在しない。さらに、最も強いはずのオーナーロールの説明文には、次のように明記されていた。

プロジェクトを管理する権限
プロジェクト作成以外のプロジェクトに関する全ての操作を行うことができる

つまりロールの付け方の問題ではなく、サービスプリンシパルにプロジェクト作成権限を与える手段が、構造として存在しなかった。プロジェクトを作成できるのはアカウントの所有者、すなわちコンソールを操作する人間だけ、という状態である。当時はこれを前提に、プロジェクトの払い出しを人間の運用手順として切り出す設計を採らざるを得なかった。

2026 年 7 月:組織・フォルダ階層の提供で状況が変わった

2026 年 7 月 9 日、さくらのクラウドは「組織・フォルダ IAM ポリシー」機能の提供を開始した公式アナウンス)。アナウンスにはこうある。

これまで各プロジェクトごとに個別に設定していた IAM ポリシーが、組織またはフォルダ単位で一括付与できるようになります。設定した IAM ポリシーは階層構造に従って継承され、上位で付与した権限は下位のリソースにも適用されるようになります。

つまり 5 月に「不可能」だったのは当然だった。プロジェクトより上位の階層に IAM ポリシーを付与する仕組みそのものが、当時は存在しなかったのである。ロールが全部プロジェクトスコープだったのは、その帰結にすぎない。

本稿を書くにあたって同じロール一覧を取り直したところ、ロールは 31 件に増え、うち 4 件がプロジェクトスコープを超えていた。

ロール 付与可能な階層 説明
フォルダ管理者 フォルダ フォルダに対する全ての操作を行うことができる
プロジェクト作成者 フォルダ プロジェクトを作成できる
サービスポリシー管理者 組織
管理者イベントログ 組織

オーナーロールの説明からも「プロジェクト作成以外」という文言が消えている。

なお、公式アナウンスが述べているのは「組織・フォルダ単位での IAM ポリシー付与が可能になった」ことであり、個々のロール名には触れていない。上位階層に付与できるロールが一覧に現れるようになったのは筆者の観測であって、これらのロールが以前から定義だけ存在していたのか、今回追加されたのかまでは分からない。実務上重要なのは、いま組織階層でこれらを付与できるという事実のほうである。

2026年5月と7月のロール体系の比較。5月は26件すべてがプロジェクトスコープ、7月は組織・フォルダ階層が加わり31件に
図2:同じ質問への答えが、ロール体系の変化で変わった

そこで実際に権限を付与して検証したところ、サービスプリンシパルでプロジェクトを作成できた201 Created)。手順は次のとおりである。

コンソールの IAM ポリシー画面を開き、スコープをプロジェクトから組織に切り替える。 ここが最大の落とし穴になる。プロジェクト作成者 は「フォルダ階層以上にのみ付与可能」なロールなので、プロジェクトを選択した状態の IAM ポリシー画面では、ロールの選択肢にすら現れない。実際、プロジェクトスコープでロールのプルダウンを開き IAM カテゴリを展開しても、出てくるのは「組織管理者」と「オーナー」の 2 つだけで、プロジェクト作成者 はどこにも無い。画面の右上にあるリソース階層のセレクタを、プロジェクトから組織(アカウント)に切り替える必要がある。

組織スコープで「アクセス権の付与」を行い、プリンシパルにサービスプリンシパル、ロールに プロジェクト作成者 を指定する。 なお、フォルダを 1 つも作っていなくても、組織階層で直接付与できる。

これだけで、それまで 403 だったプロジェクト作成 API が通るようになる。反映には最大 3 分かかるとコンソールには表示されるが、実際には保存直後の 1 回目で成功した。

IAMポリシー画面。プロジェクトスコープでは「プロジェクト作成者」が候補に出ないが、組織スコープに切り替えると選べる
図3:同じ画面でも、スコープがプロジェクトのままでは「プロジェクト作成者」は候補にすら現れない

この壁から得られる本当の教訓

「構造的に不可能」と結論した制約が、クラウド側の機能追加で解けることがある。

5 月の調査は、当時としては正確だった。ロール一覧を全件ダンプして確認しており、推測ではない。それでも 2 ヶ月後、機能がひとつ提供されたことで答えが変わった。しかも本稿の検証は、その提供開始からわずか 4 日後に行っている。あと数日ずれていたら、筆者は「不可能である」と書いて公開していた。

クラウドの制約は動く標的である。半年前の検証結果を前提に設計を固定すると、すでに解けている制約を回避するための遠回りな仕組みを、いつまでも保守し続けることになる。 制約を前提に設計を歪めた箇所は、どこかに記録しておき、定期的に叩き直したほうがよい。あわせて、利用しているクラウドのリリースノートを継続的に追うこと。設計を縛っていた制約が、告知ひとつで消えていることがある。

補足:バリデーションは認可より先に走る

この検証中に、切り分けを誤らせる挙動に遭遇したので記しておく。

プロジェクト作成 API のリクエストで必須フィールド(code)を埋め忘れていた間、返ってくるのは一貫して 400 Invalid input だった。403 permission_denied は一度も見えない。リクエストの形が不正なうちは、バリデーションが先に走り、権限エラーが隠れる。

権限の有無を切り分けたいときは、まずリクエストボディを正しく埋めてから叩くこと。400 が返っている状態で「権限はあるらしい」と判断すると、事実と逆の結論に至る。


壁 2:SP の「リソース ID」と「キー ID」は別物である

サービスプリンシパルは 2 階層の構造を持つ。

サービスプリンシパル(本体 = 身分そのもの)
  ├─ リソース ID:12 桁の数値
  └─ サービスプリンシパルキー(公開鍵の登録。複数持てる)
       ├─ キー ID:UUID 形式(36 文字)
       └─ KID:公開鍵から計算されるフィンガープリント(43 文字)

JWT を組み立てる際、iss および sub クレームに入れるのは 本体のリソース ID(12 桁の数値) である。キーの UUID ではない。またヘッダの kid に入れるのは、キー ID の UUID ではなく KID のほうである。

サービスプリンシパルの3つの識別子とJWTの対応。リソースIDはiss/subへ、KIDはkidヘッダへ。キーIDのUUIDはどこにも入らない
図4:3つの識別子のうち、JWTに入るのは2つだけ。キーIDのUUIDはどこにも入らない

ここで SP キーの UUID を SP の ID だと取り違えて設定すると、次のエラーが返る。

JWTの検証に失敗しました

このエラーが厄介なのは、原因を誤った方向に誘導する点にある。秘密鍵も公開鍵も KID もすべて正しく、署名の計算にも誤りがない。それでも「検証に失敗しました」と言われるため、鍵の生成方法や署名アルゴリズムを疑い始めてしまう。実際には鍵は完全に正しく、「誰として名乗るか」の欄だけが間違っている。

似た形式の識別子が同じ画面に 3 つ並んでいれば、取り違えは必ず起きる。コンソールで SP の詳細画面を開き、「リソース ID」と明記された 12 桁の数値を使う。 本稿でこの一点だけでも持ち帰る価値がある。

さらに静かな罠:ID を取り違えても認証は通る

これに関連して、より発見しにくい問題がある。

SP の ID を別の SP のものと取り違えていても、署名さえ正しければ認証は成立してしまう。 検証中、口頭で受け取った番号をそのまま設定したところ、認証も API 呼び出しも問題なく通り、当然正しいものだと考えていた。実際には別プロジェクトの SP だった。

「認証が通った」は「意図した身分で認証が通った」を意味しない。SP の ID は、必ずコンソールの詳細画面(プロジェクト名も併記される)で裏を取る必要がある。


壁 3:SP の JWT が通らない API が存在する

本稿で最も重要な点がこれである。

新しいプロジェクトの初期構築を Terraform で実行する際、プロファイルにサービスプリンシパルの情報だけを設定した場合、次のように挙動が割れる。

  • サーバやゾーンの一覧取得(IaaS 系)→ 通る
  • オブジェクトストレージのコントロール API → API Error 400: JWTの検証に失敗しました

同一の認証情報で、一方は通り、他方は弾かれる。この非対称性が切り分けを難しくする。

原因は、オブジェクトストレージのコントロール API が、この SP の JWT を検証できないことにある。検証した範囲では kid の形式差が関係しているようだった。フィンガープリント形式(base64url)の KID を持つ SP キーでは両方通る一方、コンソール上で見えた UUID を設定した場合、IaaS には通るがオブジェクトストレージには通らない、という挙動になる。

対処は単純である。Terraform や usacloud のプロファイルには、サービスプリンシパルではなく「リソース操作 API キー」(トークンとシークレットの組)を設定する。 これで IaaS もオブジェクトストレージも両方通る。この API キーは従来からある汎用の認証手段であり、ツール群との相性が最も良い。

ここから導かれる運用ルールは次の 3 点である。

Terraform / usacloud のプロファイルには、リソース操作 API キーを入れる。 サービスプリンシパルだけを設定すると、SP キーの kid の形式によってはオブジェクトストレージの操作で行き詰まる。API キーを入れておけば、この分岐を考えなくて済む。

API キーは、権限の範囲を明示して発行する。 「作成・削除レベル」に加え、オブジェクトストレージとコンテナレジストリを対象に含める必要がある。

インフラ構築ツールが使う認証情報と、アプリケーションのランタイムが使う認証情報を、明確に別物として扱う。 両者は役割も生存期間も異なる。ランタイム側はサービスプリンシパルで問題なく動作する。

「新しい認証方式に統一しよう」という発想は自然だが、少なくとも現時点では、用途ごとに適した認証情報を選ぶほうが素直に動く。統一を試みて半日を溶かすより、地図を持っておくほうが速い。


壁 4:一覧 API はアカウント全体を返す

最後に、認証そのものというより「認証の見え方」に関する問題を挙げる。

空のプロジェクトを新規作成し、そこに所属する SP の認証情報でサーバ一覧を取得すると、別のプロジェクトで稼働しているサーバ群が返ってくる。

すなわち、IaaS API のリソース一覧は、認証情報が所属するプロジェクトでは絞り込まれず、アカウント全体を返す。 一方でコンソールの「契約リソース」パネルはプロジェクト単位で正しく表示され、新規プロジェクトは 0 件、既存プロジェクトは実体どおりの件数を示す。

この差が意味するのは、「このプロジェクトは空か。削除して問題ないか」といった判断を一覧 API で行うと、盛大に誤判定するということである。

したがって、次のように使い分ける必要がある。

「いま、この瞬間にこのリソースが存在するか」 を知りたい場合は、ID を指定して読む。

「このプロジェクトに何が属しているか」 を知りたい場合は、コンソールの契約リソースパネルを正とする。ただしこのパネルは課金ベースの集計であり、数値の反映に 1 日程度の遅れが出る点に注意する。

一覧 API は便利だが、それが答えている質問は、こちらが聞きたい質問とは違うかもしれない。 これはさくらのクラウドに限らず、クラウド API 全般に通じる教訓である。


地図を持って歩く

改めて整理する。

サービスプリンシパルは、プロジェクト内のリソースを機械が操作するための身分証である。 プロジェクトそのものを作成させたい場合は、組織階層で プロジェクト作成者 ロールを付与する(プロジェクトスコープの画面では選択肢に出ない)。JWT に入れるのは本体の 12 桁のリソース ID であり、キーの UUID ではない。

プロジェクトの API キーは、従来からの Cloud API 系を叩くための鍵である。 サーバ、ディスク、アプライアンス、コンテナレジストリ、オブジェクトストレージのコントロール面は、この系統に乗っている。

リソース操作 API キーは、Terraform や usacloud のための汎用キーである。 インフラ構築ツールにはこれを設定する。サービスプリンシパルだけでは、オブジェクトストレージで止まることがある。

そして、一覧 API はプロジェクトでは絞られない。

これらを事前に知っていれば、認証で止まることはなくなる。さくらのクラウドは、新しい IAM の体系と、実績のある既存の API 体系が並走する過渡期にある。本稿で挙げた 4 つの壁は、いずれもその「継ぎ目」に集中している。裏を返せば、継ぎ目の位置さえ把握していれば、あとは素直に自動化できるということでもある。

なお、API の wire 仕様(リクエストやレスポンスの実際の形)を確認する必要が生じた場合、公式の OpenAPI 定義に加えて、Terraform プロバイダが内部的に利用している Go ライブラリのソースが有力な一次資料になる。特に従来からの Cloud API 系は OpenAPI として公開されていない部分があり、「OpenAPI に定義がない」ことは「API が存在しない」ことを意味しない。この点も、実装前に知っておく価値がある。

次回は、コンテナ実行基盤を閉域ネットワーク上で本番運用した際の知見を取り上げる予定である。


参考リンク

Need Support?

この記事のテーマをそのまま実務に広げたいときのために、近い内容から相談しやすい窓口をまとめました。

Cloud Support

クラウド活用を実務に合わせて進める

Cloudflare、CDN、AWS、GCP、さくらのクラウドを含む設計や移行の相談先を探している場合は、要件整理から一緒に進められます。

相談テーマがまだ曖昧でも大丈夫です

課題が整理しきれていない段階でも、状況を共有いただければ優先度付けから一緒に進められます。

記事をシェアする