LESSON 30分

ストーリー

田中VPoE
シークレットのローテーションを学んだ。次は「ゼロスタンディング権限(Zero Standing Privileges)」だ。これはシークレット管理の究極形とも言える考え方だ
あなた
ゼロスタンディング権限?聞いたことがないです
田中VPoE
「常時アクセス権を持つアカウントをゼロにする」という原則だ。管理者であっても、普段は本番環境へのアクセス権を持たない。必要な時にだけ、承認を経て一時的な権限を取得する。これをJIT(Just-In-Time)アクセスと呼ぶ
あなた
つまり、本番環境の管理者アカウントのパスワードを常に知っている人がいない状態ですか
田中VPoE
そうだ。SolarWinds攻撃を思い出せ。管理者アカウントが常時存在し、そのアカウントが侵害されたことで甚大な被害が出た。ゼロスタンディング権限なら、侵害する対象そのものが存在しない

ゼロスタンディング権限の概念

従来のアクセスモデルとの比較

観点従来モデルゼロスタンディング権限
管理者アカウント常時存在、常時アクセス可能常時は存在しない
アクセス方法パスワード/鍵で直接アクセス承認→一時権限付与→アクセス
権限の有効期間無期限(手動で削除するまで)短期間(1-4時間)
監査「誰がいつアクセスしたか」をログで追跡「誰がなぜアクセスを要求し、誰が承認したか」まで追跡
内部脅威管理者が常時アクセス可能管理者も申請・承認が必要
攻撃面管理者アカウントが攻撃対象攻撃対象となるアカウントが存在しない

JITアクセスのフロー

JIT(Just-In-Time)アクセスのフロー:

1. アクセス要求
   [エンジニア] ──→ JITポータル
   「本番DBの読み取りアクセスが必要。障害調査のため。チケット: INC-456」

2. 承認
   [JITポータル] ──→ [承認者(セキュリティリード)]
   「承認します。有効期間: 2時間」

3. 一時権限の付与
   [JITポータル] ──→ [Vault]
   動的シークレットの生成(TTL: 2時間)

4. アクセス実行
   [エンジニア] ──→ [本番DB](一時認証情報で接続)
   全操作が監査ログに記録

5. 自動失効
   2時間後、認証情報が自動失効
   [エンジニア]のアクセスは自動的に無効化

ゼロスタンディング権限の実装パターン

パターン1: Vault + OPA による JIT アクセス

# Vault ポリシー: JIT アクセス用
# 通常時は誰も本番DBにアクセスできない
# JIT 承認後のみ、一時的にポリシーがアタッチされる

# JIT承認後にアタッチされるポリシー
path "database/creds/production-readonly" {
  capabilities = ["read"]
}

# TTL: 最大2時間
path "sys/leases/renew" {
  capabilities = ["update"]
}
# JIT アクセスポータルの概念コード
class JITAccessRequest:
    def __init__(self, requester: str, resource: str, reason: str, ticket: str):
        self.requester = requester
        self.resource = resource
        self.reason = reason
        self.ticket = ticket
        self.status = "pending"
        self.ttl = 7200  # 2時間

    async def approve(self, approver: str):
        """承認後、Vaultのエンティティにポリシーをアタッチ"""
        self.status = "approved"

        # Vault エンティティに一時ポリシーをアタッチ
        await vault.write(
            f"identity/entity/name/{self.requester}",
            policies=[f"jit-{self.resource}"]
        )

        # TTL後に自動でポリシーを剥奪するスケジュール
        await scheduler.schedule(
            action=self.revoke,
            delay_seconds=self.ttl
        )

        # 監査ログに記録
        await audit_log.record(
            event="jit_access_approved",
            requester=self.requester,
            approver=approver,
            resource=self.resource,
            reason=self.reason,
            ticket=self.ticket,
            ttl=self.ttl
        )

    async def revoke(self):
        """TTL後にポリシーを自動剥奪"""
        await vault.write(
            f"identity/entity/name/{self.requester}",
            policies=[]  # ポリシーを空に
        )
        self.status = "expired"

パターン2: AWS SSO + IAM Identity Center

AWS における JIT アクセスの実装:

通常時:
  エンジニアは「ReadOnly」PermissionSet のみ
  本番環境の「Admin」PermissionSet は未割り当て

JIT 要求時:
  1. Slack Bot / 社内ポータルで申請
  2. 承認者が承認
  3. AWS IAM Identity Center API で
     一時的に「Admin」PermissionSet を割り当て
  4. セッション期間: 最大1時間
  5. セッション終了後、自動でPermissionSetを剥奪

使用するAWSサービス:
├── IAM Identity Center(旧 AWS SSO)
├── AWS Organizations
├── CloudTrail(監査ログ)
└── Lambda + Step Functions(自動化)

パターン3: ブレイクグラス(Break Glass)手順

ブレイクグラス: 緊急時の特権アクセス手順

通常のJITフロー:
  申請 → 承認(人間) → アクセス

ブレイクグラス(緊急時):
  申請 → 自動承認(事後レビュー) → アクセス

条件:
├── 重大障害(SEV-1)が発生している
├── 通常の承認者が全員不在
└── または、承認を待つとSLAに違反する

統制:
├── ブレイクグラスの使用は全件アラート(Slack + PagerDuty)
├── 24時間以内に事後レビューを実施
├── 不正使用は懲戒対象
└── 四半期ごとにブレイクグラスの使用状況をレビュー

ゼロスタンディング権限の成熟度モデル

レベル状態対象
Level 0常時管理者アクセスが有効
Level 1共有管理者アカウントの廃止。個人アカウントに移行サーバーアクセス
Level 2JITアクセスの導入(手動承認)本番環境
Level 3自動化されたJIT + ブレイクグラス全環境
Level 4ゼロスタンディング + 全操作の監査 + 異常検出全リソース

「一気にLevel 4を目指す必要はない。まずLevel 1(共有アカウントの廃止)から始め、段階的に進めることが重要だ」 — 田中VPoE


まとめ

ポイント内容
ゼロスタンディング権限常時アクセス権を持つアカウントをゼロにする原則
JITアクセス必要な時にだけ承認を経て一時的な権限を取得
ブレイクグラス緊急時の特権アクセス手順(事後レビュー必須)
段階的導入共有アカウント廃止→JIT導入→自動化→全面展開

チェックリスト

  • ゼロスタンディング権限の概念を説明できる
  • JITアクセスのフローを設計できる
  • ブレイクグラス手順の要件を理解した
  • 段階的導入の成熟度モデルを把握した

次のステップへ

次は演習です。PayConnectシステムに対するシークレット管理基盤を設計しましょう。


推定読了時間: 30分