最小権限の原則と多層防御
「とりあえず全権限」をやめ、必要な分だけ渡す。さらに防御を一枚ではなく何層も重ねて、どこか1つ破られても被害を止める設計の考え方。
- 1.最小権限(Least Privilege)とは「仕事に必要な権限だけ与える」原則。広すぎる権限は、漏れた1個の鍵で全部が開く事故につながる。
- 2.目的は被害範囲(Blast Radius)の最小化。万一その権限が乗っ取られても、被害をそのアカウント・その範囲に閉じ込める。
- 3.完璧な防御はない前提で、認証・権限・ネットワーク・監視を何層も重ねるのが多層防御(Defense in Depth)。1枚破られても次の壁で止める。
最小権限とは何か(PoLP)
最小権限の原則(Principle of Least Privilege, PoLP)は、ユーザー・プログラム・サービスに対して「やるべき仕事を遂行できるギリギリの権限」だけを与え、それ以上は与えないという設計指針です。逆のアンチパターンが「面倒だから全部入り」――開発者アカウントに Administrator、アプリのDBユーザーに全テーブルへの全操作権、コンテナを root で起動、といった**過剰権限(over-privilege)**です。
なぜ問題かというと、権限は「もし漏れたら何ができるか」の上限そのものだからです。鍵が1本漏れたとき、その鍵が「自分の机の引き出し」しか開けないのか、「ビル全体のマスターキー」なのかで、事故の規模はまったく変わります。最小権限は、漏れる確率を下げるのではなく、漏れたときの被害の天井を下げる対策だと理解するのが肝心です。
「権限不足のエラーを潰すのが面倒」という理由で *:*(全アクション・全リソース許可)や Administrator を付けるのは、最も多い事故の入口です。アクセスキーがGitHubに誤コミットされた/SSRFで盗まれた瞬間、攻撃者はそのアカウントでできることすべてができてしまいます。権限は「足りなくて困ったら足す」方向に運用し、最初から広く付けて絞らないのは避けます。
なぜ効くのか:被害範囲(Blast Radius)の最小化
セキュリティの世界では「侵入されない」を100%保証することはできません。フィッシングでパスワードが抜かれる、ライブラリの脆弱性を突かれる、鍵を誤って公開する――どれかは起こり得ます。だからこそ「破られた後にどこまで広がるか」を設計で抑えます。これが**被害範囲(Blast Radius)**の最小化です。
最小権限が効くのは、まさにこの「広がり」を物理的に止めるからです。たとえば、あるWebアプリの認証情報が漏れたとして――
- 過剰権限の場合:そのアプリのDBユーザーが全テーブルにアクセスできれば、漏れた瞬間に全ユーザーの個人情報が抜かれます。
- 最小権限の場合:そのアプリが触れるのが「自分のスキーマの数テーブルだけ」なら、被害もそのテーブルの範囲に閉じます。
同じ「侵入」でも、結果が「全社データ流出」か「一部テーブルの参照」かは桁違いです。
最小権限は「侵入を防ぐ壁」ではなく「侵入された後の延焼を止める防火扉」です。だから「うちは堅牢だから不要」ではなく、堅牢な組織ほど“破られた前提”で被害を区画化しています。後述の多層防御と組み合わせて初めて、現実的な強さになります。
多層防御(Defense in Depth):壁は一枚にしない
最小権限が「1層の質」を上げる話なら、多層防御(Defense in Depth)は「層の数」を増やす話です。発想は「どんな単一の防御もいつかは破られる。なら独立した防御を直列に重ね、全部を同時には破れない状態にする」というもの。城の堀・城壁・門・天守を何重にも構えるのと同じ発想です。
重要なのは、各層が異なる原理で守っていることです。同じ仕組みを2回置いても、同じ攻撃で両方抜かれます。たとえばWebアプリなら、こんな層が重なります。
| 層 | 守るもの | 代表的な対策 |
|---|---|---|
| ネットワーク | そもそも到達させない | VPC / サブネット分離・セキュリティグループ・WAF |
| 認証(Authn) | 誰かを確かめる | MFA・強い[パスワード保管](/security/password-storage/)・SSO |
| 認可(Authz) | 何をしてよいか | 最小権限のIAM・RBAC・[認証と認可の分離](/security/authn-authz/) |
| アプリ | 入力・出力を安全に | [XSS](/security/xss/) / [SQLi](/security/sql-injection/)対策・入力検証 |
| データ | 盗まれても読ませない | 保存時暗号化・[TLS](/network/tls/)による通信暗号化 |
| 監視 | 破られたことに気づく | ログ・監査証跡・異常検知・アラート |
WAFを2台並べても、ファイアウォールのルールを増やしても、それは「層を増やした」ことになりません。同じ原理の防御は同じ攻撃で一斉に抜けます。多層防御の要点は性質の違う防御を直列にすること――「ネットワークで止め、認証で確かめ、認可で絞り、アプリで検証し、暗号で読ませず、監視で気づく」。各層が独立しているほど、攻撃者は全部を順に突破せねばならず、難度が跳ね上がります。
最小権限と多層防御の関係
混同しがちですが、両者は対立ではなく補完です。位置づけを整理します。
| 観点 | 最小権限の原則 | 多層防御 |
|---|---|---|
| 問いかけ | この主体に“どこまで”許すか | 防御を“何枚”重ねるか |
| 主な狙い | 破られた後の被害範囲を絞る | そもそも全部を同時に破らせない |
| 効くタイミング | 侵入“後”の延焼防止 | 侵入“前〜後”の各段階で減衰 |
| たとえると | 鍵が開ける範囲を最小にする | 扉を何重にも設ける |
実務では両方を使います。多層防御という大きな設計の中に、各層を支える具体策として最小権限が組み込まれる、という関係です。次節からは、その最小権限を「IAM」「ネットワーク」「スコープ」の3つの代表的な場面で具体化します。
具体例1:IAM(クラウドの権限)
クラウドでの最小権限の主戦場が IAM(Identity and Access Management)です。ありがちなのは、S3 の1バケットを読みたいだけのアプリに、全 S3・全アクションを許してしまう例です。
// ❌ 悪い例:S3 に対して全アクション・全リソースを許可
// 鍵が漏れれば、全バケットの作成・読み取り・削除がやり放題
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
// ✅ 良い例:必要な「読み取り」だけを「特定バケット」に限定
// 漏れても、被害はこのバケットの参照に閉じる
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-app-assets/*"
}
ポイントは3つです。(1) アクションを絞る(s3:* ではなく s3:GetObject のように必要な動詞だけ)。(2) リソースを絞る(* ではなく対象のARNだけ)。(3) 人ではなくロールに権限を持たせる――アプリには長期アクセスキーを埋め込まず、サーバやコンテナにIAMロールを割り当て、自動で短期の一時認証情報を使わせます。これで「漏れる鍵」自体を減らせます。
ソースコードや環境変数に長期のアクセスキーを直書きすると、リポジトリへの誤コミット・ログ流出・SSRF等で抜かれた瞬間に悪用されます(GitHub 上の漏洩キーは数分で自動スキャンされ悪用される、というのは有名な話です)。対策は IAMロール+短期トークン、どうしても鍵が要るなら Secrets Manager 等の秘密管理サービスに置き、コードには入れない。さらに付けた権限は定期的に棚卸しし、使われていない権限・キーは削除します(付けっぱなしが一番危険)。
具体例2:ネットワーク分離
権限は「データやAPIへのアクセス」だけでなく「ネットワーク的な到達可能性」にも適用できます。「触れる必要がないものには、そもそもネットワーク的に到達させない」――これも最小権限の一形態です。
典型は 3層構成です。インターネットに面するのはロードバランサ(公開サブネット)だけにし、アプリサーバとDBはプライベートサブネットに置いてインターネットから直接到達できなくします。さらにセキュリティグループ(仮想ファイアウォール)で「誰から・どのポートへ」を絞ります。
| 層 | 配置 | 通信を許す相手(最小化) |
|---|---|---|
| ロードバランサ | 公開サブネット | インターネットから 443(HTTPS) のみ |
| アプリサーバ | プライベートサブネット | ロードバランサからのアプリポートのみ |
| データベース | プライベートサブネット | アプリサーバから 5432 等のDBポートのみ |
こうすると、仮にアプリサーバが乗っ取られても、攻撃者はDBの決まったポートにしか到達できず、外部への自由な通信(情報持ち出しや横展開)も制限できます。DBがインターネットに直接晒されていれば総当たりや既知脆弱性を直接突かれますが、プライベートに隔離してあれば、まず内部に侵入しないと届きません。**「到達できないものは攻撃できない」**という素朴な強さです。
「内側のネットワークだから安全」という前提を捨て、層と層の間の通信も最小限だけ明示的に許可していく発想は、ゼロトラストの考え方そのものです。「ネットワーク的に内側か外側か」で信頼を決めず、どの通信も“必要だから許す”ものだけ通す――最小権限をネットワークに広げた延長線上にあります。
具体例3:最小スコープ(DB・トークン)
最後は、より細かい単位での「スコープ(権限の範囲)」の最小化です。IAMやネットワークと同じ原則を、DBユーザーやアクセストークンに適用します。
DBユーザーの権限を例にとると、参照しかしないアプリに、テーブルを書き換え・削除できる権限まで渡す必要はありません。
-- ❌ 悪い例:アプリ用ユーザーに何でもできる権限を付与
-- SQLインジェクションを食らうと DROP TABLE まで通ってしまう
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
-- ✅ 良い例:必要な操作だけを必要なテーブルに限定
-- 参照系サービスなら SELECT だけ。書き込みが要る機能は別ユーザーに分ける
GRANT SELECT ON app_db.products TO 'readonly_user'@'10.0.%';
GRANT SELECT, INSERT, UPDATE ON app_db.orders TO 'order_service'@'10.0.%';
権限を絞っておくと、万一 SQLインジェクションを許してもできることが SELECT の範囲に制限され、DROP TABLE や他テーブルの改ざんといった致命傷を防げます(もちろん SQLの基本を踏まえたプリペアドステートメントでの根本対策が大前提で、権限制限はその「次の壁」です)。
OAuth のアクセストークンのスコープも同じ発想です。プロフィール表示しかしないアプリが、メール送信や全データ削除の権限まで要求するのは過剰です。read:profile だけを要求すれば、トークンが漏れてもできるのはプロフィール参照だけ。認可の仕組みそのものは認証と認可・Web認証で扱うとおりですが、**「要求するスコープを最小にする」**こと自体が最小権限の実践です。
DBユーザーを SELECT だけにしても、SQLインジェクションを直す代わりにはなりません。最小権限はあくまで「破られた後の被害を縮める層」であり、入力検証・プリペアドステートメント・XSS対策といった根本対策(穴を塞ぐ層)と必ず併用します。これこそが多層防御――「塞ぐ層」と「被害を絞る層」を重ねて、片方が破れてももう片方で受け止める、という設計です。
まとめ:絞って、重ねる
最小権限と多層防御は、別々の技で覚えるより「ひとつの設計思想の両輪」として捉えると腑に落ちます。
- 最小権限=主体ごとに「できること」を必要最小限に絞る。狙いは破られた後の被害範囲(Blast Radius)の最小化。
- 多層防御=性質の違う防御を直列に重ねる。狙いは全部を同時には破らせないこと。
- 両者は補完関係。多層防御の各層を、最小権限で堅くするのが現実的な強さになる。
実務での合言葉は「まず拒否、必要な分だけ許可(deny by default)」と「壁は一枚にしない」。IAMもネットワークもDBもトークンも、同じ原則の繰り返しです。次は、この「内側だから安全とは限らない」という前提を突き詰めたゼロトラスト、あるいは個々の攻撃面である SQLインジェクション・XSS・CSRFに進むと、各層が何から守っているのかがより立体的に見えてきます。
セキュリティ Article
最小権限の原則と多層防御を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
最小権限
比較で見る軸
難易度: intermediate / カテゴリ: セキュリティ / タグ数: 4
導入後に効く点
目的は被害範囲(Blast Radius)の最小化。万一その権限が乗っ取られても、被害をそのアカウント・その範囲に閉じ込める。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- セキュリティ
- タグ数
- 4
判断チェックリスト
- 自社の用途が「最小権限 / 多層防御」に近いか確認する。
- 強みである「最小権限(Least Privilege)とは「仕事に必要な権限だけ与える」原則。広すぎる権限は、漏れた1個の鍵で全部が開く事故につながる。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。