コンテンツにスキップ

認可 — 誰が何をしてよいか、そしてそれをどう証明するか

Control Center は 2 つの認可の問いに答えます。そしてこの 2 つは本質的に異なります。「この人物はこの操作を呼び出してよいか?」 は、人、ロール、リポジトリに関する問いです。「このエージェントはこの効果を引き起こしてよいか?」 は、アクション、引数、影響範囲に関する問いで、こちらはガードレールで扱います。

このページでは前者の問いを扱い、あわせて両者が残す記録について説明します。

人側の認可判断はすべて、単一の関数を通じて解決されます。

can(principal, permission, resource) → allow | deny + why

権限は <domain>:<tier> の形式です — tickets:write、members:administer、repos:read。カタログは手書きではなく導出されます。つまり、操作サーフェスそのものから計算されます(操作名の接頭辞がドメインを、その操作がすでに要求しているロールの下限が階層を与えます)。おかげで約 550 件の操作すべてが、誰かが 1 つずつ入力しなくても権限を持ちます。

守る価値があるのは、この導出という性質です。つまり、新しい操作はデフォルトでゲートされるということです。手作業で注釈を付けるモデルの失敗パターンは、誰かが付け忘れることであり、その付け忘れる対象こそがゲートです。ラチェットテストが導出されたドメイン集合を固定するので、新しい接頭辞の下に操作を追加することは、偶然ではなく人間が下す命名の判断になります。

4 つの階層は、組み込みロールに正確に対応します。

階層 ロールの下限 例
read ゲスト tickets:read
write メンバー tickets:write
administer 管理者 members:administer
own オーナー workspace:own

5 つの組み込みロール — オーナー、管理者、メンバー、閲覧者、ゲスト — は、このカタログに対するプリセットです。オーナー権はワークスペースごとに 1 席だけで、所有権を譲渡によって明示的に引き継ぎます(辞めるオーナーは、そうしなければ削除できません。SCIM のプロビジョニング解除はワークスペースのオーナーを拒否するので、先に譲渡してください)。

カスタムロールは減算方式です。 カスタムロールは、基底となるプリセット(admin、member、viewer、guest のいずれか — owner は不可)と、そこから削除する権限の集合を指定します — 「管理者だがメンバーを管理できない」のように。基底より多くを付与することは決してできません。だからこそ、既存のインストールへ安全に導入できるのです。既存のチェックはすべて、そのまま妥当な上限であり続けます。メンバーはこれを custom:<id> として保持し、この値を理解できないほど古いクライアントは、推測せずにゲストへフォールバックします。

ロールの下にはリポジトリ単位の権限付与(none / read / review / write)があります。ワークスペースのメンバーシップが、暗黙にコードホストより強い権限を与えることはありません。コードを露出させるすべてのサーフェスがこれをチェックします。スペースのワークツリー上で開いたターミナルやエディターセッションのように、間接的にコードへ到達するものも含まれます。

一部の操作はワークスペースとはまったく関係ありません。インストール全体の設定、SSO 設定、プロバイダーの認証情報、モデル管理、インストール全体のバックアップなどです。これらはサーバー権限を宣言し、インストールのオペレーター(記録されたサーバーのオーナー)以外のすべてに対して拒否されます。オペレーターの ID とその定義は、意図的にそれぞれ 1 つだけです。

すべての認可判断 — 許可と拒否の両方 — は、ワークスペース単位のハッシュチェーン化された監査証跡に追記されます。

拒否だけのログは「何をブロックしたか」には答えますが、「このエージェントが実際に何をし、誰がそれを認可したか」には答えられません。そして後者が、インシデントレビューが出発点とする問いです。そこで各エントリには、帰属の連鎖全体を記録します。行為主体であるプリンシパル、その代理として行動した人間、経由した委任、アクションとその引数(ダイジェストとして)、判断、そして判断を下したルールです。

エントリは連鎖します。各エントリのハッシュは前のエントリのハッシュを含むため、どの行を編集、削除、並べ替えても、それ以降のハッシュがすべて壊れます。チェーンを検証は、全体を再導出し、最初に破綻したリンクを名指しします。検証できない監査ログはただのログですが、再導出できるものは証拠になります。

知っておく価値のある帰結が 2 つあります。

  • 監査テーブルは経過時間ベースのプルーニングの対象外です。ハッシュチェーンは途中から切り詰めることができません。保持は「エクスポートしてから切り詰める」方式で、切り詰め時には、削除された区間の末尾ハッシュを保持するチェックポイントが残ります。そのため、残った部分も先頭まで検証できます。
  • これはアクティビティタイムラインの横に並ぶもので、その上に載るものではありません。タイムラインは人が行ったことであり、こちらは何が認可され、何が拒否されたかです。共有の相関 ID を使えば、1 回の呼び出しを両方から読み取れます。

改行区切りの JSON としてエクスポートでき、SIEM(Splunk、Elastic、Sentinel — ベアラートークン付きの HTTP エンドポイント)へストリームできます。ストリーミングは設計上ベストエフォートです。SIEM がダウンしていてもエージェントのツール呼び出しをブロックしてはならず、耐久性があり検証可能なコピーはいずれにせよディスク上にあります。

インストールでは、セッションの最大有効期間とアイドルタイムアウトを設定できます。どちらも、すべての認証済み経路が通るデバイス認証情報のチェック時に適用されます。クライアントが無視できる程度の制約では、攻撃者ではなくアンケートに答えることになります。インストールで SSO を必須にすることもでき、その場合、新しいデバイスの手動ペアリングが無効になります(ロックアウトガード付きで、機能する SSO 接続が 1 つも存在しない間は拒否します)。

  • オブジェクト単位の ACL ではありません。 チケット単位やメッセージ単位の権限は、意図的に存在しません。チームが実際に求めるのはリポジトリ単位の分離であり、それは存在します。オブジェクト単位の共有は組み合わせ的に膨らむ領域で、ここでは需要が示されたことはありません。
  • DSL で設定するポリシーエンジンではありません。 語彙は意図的に閉じており、そのためポリシー全体を描画、説明、列挙できます。
  • サーバー以外では適用されません。 クライアント側のチェックは、拒否される操作を提示しないためにだけ存在します。権威ある判断は常にサーバー側のものです。