認可
「あなたに何をする権限があるか」を判断するプロセス。認証の次に来る。
概要
認可(authorization)とは、認証によって本人確認が済んだ相手に対して、「この操作をしてよいか」を判断するプロセスです。管理者だけがユーザーを削除できる、自分の投稿だけ編集できる、経理部だけが請求データを見られる——アプリケーションの「権限」にまつわる設計は、すべて認可の話です。英語圏では AuthZ と略され、認証(AuthN)と対で語られます。
大事なのは、認証と認可が別の問いに答えているということです。認証は「あなたは誰か」を確かめ、認可は「その人に何が許されているか」を判断します。ログインに成功した(認証済み)からといって、すべての操作が許されるわけではありません。逆に、認可の判断は「誰か」が分かっていることが前提なので、通常は認証の後に来ます。
認可は人間のユーザーだけの話ではありません。API を呼び出すアプリケーションにどこまでの操作を許すか、クラウド上のサービスがどのリソースにアクセスできるか(IAM ロール)、コンテナや Kubernetes のワークロードに何を許すか——現代のシステムは認可の判断だらけです。
なぜ生まれたか
コンピュータを複数人で共有するようになった瞬間から、「誰か」の確認だけでは足りなくなりました。全員が本人確認済みでも、学生が教授の成績ファイルを書き換えられてよいはずがありません。1960〜70年代のタイムシェアリングシステムは、ファイルごとに「誰が読めるか・書けるか」を定める仕組み(UNIX のパーミッションはその代表)を備え、ここで「本人確認」と「権限の判断」が別の関心事として分離されました。
この分離が決定的に重要になったのが Web と API の時代です。組織の人数とリソースが増えると、「誰に何を許すか」を個別に管理するのは破綻します。また「他人に自分の権限の一部だけを貸したい」という新しい要求も生まれました。たとえば写真プリントサービスに、自分のクラウドストレージの写真だけを読ませたい。パスワードを渡せば全権限を渡すことになってしまう。この「権限の限定的な委譲」の問題を解決するために生まれたのが OAuth です。認可を認証から独立した概念として設計する重要性は、時代とともに増す一方です。
詳細
認可チェックの基本フロー
Web アプリケーションでの認可は、リクエストのたびに行われる判断です。典型的には次のような流れになります。
HTTP のステータスコードでは、未認証(そもそも誰か分からない)が 401 Unauthorized、認証済みだが権限がないのが 403 Forbidden です。401 の名前が “Unauthorized” なのは歴史的な混乱で、意味的には「Unauthenticated」に近い——この紛らわしさ自体が、認証と認可の混同がいかに根深いかを物語っています。
RBAC と ABAC — 権限をどうモデル化するか
認可設計の中心は「誰に何を許すか」をどう表現するかです。最も素朴なのはユーザーに権限を直接ひも付ける方法ですが、人数が増えると管理不能になります。そこで主流になったのがロールベースアクセス制御(RBAC)です。「管理者」「編集者」「閲覧者」のようなロール(役割)に権限をまとめ、ユーザーにはロールを割り当てます。人の異動はロールの付け替えだけで済み、権限の見通しも良くなります。多くの業務システムや Kubernetes の権限管理は RBAC が基本です。
ただし RBAC では表現しにくい要件もあります。「自分の投稿だけ編集できる」「営業時間内のみアクセス可」「同じ部署の文書のみ閲覧可」のような、リソースや状況の属性に依存する判断です。これに応えるのが属性ベースアクセス制御(ABAC)で、主体・リソース・環境の属性を組み合わせたポリシーとして権限を記述します。柔軟な反面、ポリシーが複雑化しやすく「なぜ拒否されたのか」の追跡が難しくなるトレードオフがあります。実務では「大枠は RBAC、所有者チェックのような細部は ABAC 的に」という併用が現実的な着地点になることが多いです。
スコープとトークン — API 時代の認可
REST API の世界では、認可の情報をトークンに載せて運ぶ設計が一般的です。OAuth では、アクセストークンに「スコープ」(read:photos のような許可範囲)を持たせ、API はトークンの提示を受けてスコープの範囲内の操作だけを許します。JWT を使えば、ロールやスコープをトークン自体に署名付きで埋め込み、サーバ側の照会なしに検証できます(その代わり即時失効が難しい、というトレードオフがあります)。クラウドの IAM も同じ発想の大規模版で、「どの主体が・どのリソースに・どの操作を」をポリシー文書で宣言します。
実務での落とし穴
認可の不備は、Webアプリケーションで最も頻出する脆弱性カテゴリのひとつです(OWASP Top 10 の「アクセス制御の不備」)。代表例が IDOR(Insecure Direct Object Reference)で、/orders/123 の数字を 124 に変えるだけで他人の注文が見えてしまう——「ログイン済みかどうか」しか確認せず、「そのリソースの持ち主か」を確認し忘れるミスです。認可チェックは URL やリソース ID がユーザー入力である以上、すべてのリクエストでサーバ側で行う必要があります。
もうひとつの典型が「フロントエンドだけの制御」です。管理メニューを画面上で非表示にしても、API を直接叩けば操作できてしまうなら認可は存在しないのと同じです。UI の出し分けは体験のためのもので、防御は必ずサーバ側で行います。設計の指針としては、デフォルト拒否(明示的に許可したもの以外は拒否する)、最小権限の原則(必要最小限の権限だけを与える)、そして認可の判定ロジックを各所に散らばらせず一箇所に集約すること。加えて、誰が何にアクセスしたかをログとして残しておくことが、事故時の調査と権限設計の見直しの土台になります。