権限と所有者
access.set のセマンティクス、「Can view」の付与が実際に許すこと、読み取り専用の 5 つの穴、そして bot 管理リストの所有者になれるのは誰か
Slack List の読み取り専用アクセスは実在し、サーバー側で強制される — ただし「読み取り専用」の意味は、言葉の響きより具体的で、そして絶対的ではない。このページでは、付与の仕組み、閲覧者に実際にできること・できないこと、機微な用途で読み取り専用に頼る前に知っておくべき 5 つの穴、そして bot 管理リストにおける所有者の扱いを扱う。
access.set — アクセスを付与する唯一の手段
slackLists.access.set は書き込みメソッド(lists:write、Tier 3 — 50+/min)で、access_level 引数が必須だ — デフォルトはなく、省略すると呼び出しが失敗する。文書化されている値はちょうど 3 つ。
access_level | 付与されるもの |
|---|---|
read | リストへの読み取りアクセス |
write | 読み取りおよび書き込みアクセス |
owner | user_ids で指定したユーザーを所有者にする |
付与対象は user_ids または channel_ids で、両者は排他かつ少なくとも一方が必須。access_level: "owner" と channel_ids の組み合わせは invalid_arguments を返す。所有者になれるのはユーザーだけで、チャンネルは決してなれない。Slack 自身のドキュメントには、まさにこの読み取り専用ダッシュボードのケース向けのサンプルが用意されている。
{ "list_id": "F1234567", "access_level": "read", "channel_ids": ["C7654321"] }このメソッドの上に何かを組む前に知っておくべき契約上の細部がいくつかある。
読み戻す手段がない。
access.listもaccess.getもslackLists.infoも存在しない。付与は書き込み専用で、現在誰が読み取り権と書き込み権を持っているかをプログラムから監査することはできない。監査経路は UI の共有ペインだけだ。access.deleteは完全な取り消しで、access_level引数を持たない — 部分的な取り消しはない。書き込み権を読み取り権へ降格するには、access_level: "read"でaccess.setを呼び直す。有料プランが必須。 無料ワークスペースでは
paid_teams_onlyが返る。Lists をワークスペース単位または組織単位で無効化する管理者トグルは、別のエラーlists_disabled_user_teamを生む。SDK の型付けの穴: Node SDK は
access_levelを'read' | 'write' | 'owner'のユニオンではなく単なるstringとして型付けしている — 値のタイプミスが型チェックを素通りし、リクエスト時に初めて失敗する。
未検証
すでに write を持つ対象に対して access_level: "read" で access.set を呼び直したとき、本当に降格されるのか(それとも何も起きないのか、あるいは先に access.delete が必要なのか)は、ドキュメントのどこにも明言されていない。メソッド名が「set」である以上は置換を示唆するが、それは推論であって文書化された保証ではない。このプロジェクトの検証スパイクはスキップされたため、この項目は未検証ステータスのままだ — 誤って与えた書き込み権を巻き戻す唯一の手段としてこれに依存する前に、実際の付与に対して降格経路を確認すること。
UI の「Can view」が意味するもの
未検証
API の access_level: "read" が UI のロールラベル 「Can view」 に対応するという写像は、API の値がちょうど 3 つ、UI の状態もちょうど 3 つあることからの推論であり、この対応をそのまま述べた Slack のページは存在しない。ほぼ確実に正しいと考えてよいが、このプロジェクトの(スキップされた)検証スパイクでは確認されていない。
この対応を前提とすると、「Can view」保持者が閲覧以外に得る権利はちょうど 2 つ、リストを他の人と共有することと、他の人に閲覧アクセスを付与することだ。編集アクセスの付与は所有者と書き込み権保持者に限られる。実務上の帰結として、読み取り専用はエスカレーションについて閉じている — リスト上の誰も書き込み権を持たなければ、誰も他人に書き込み権を渡せない。閲覧者が広げられるのは閲覧だけで、編集は決して広げられないからだ。ただし、それ自体では伝播について閉じてはいない — 所有者が共有制限を有効にしないかぎり(下記の穴 3 を参照)、閲覧者は閲覧アクセスを次々と広げられる。
閲覧者にできること・できないこと
| 閲覧者にできること | 閲覧者にできないこと |
|---|---|
| ボードとテーブルのレイアウト切り替え、フィルタ・ソート・グループ化のその場での調整 | ボードの列間でカードをドラッグすること (未検証 — 下記参照) |
| 保存済みビュー間の切り替え | アイテム・セル・列の追加・編集・削除、担当者の割り当て |
| アイテム詳細ペインを開くこと | ビューの保存 — 保存には編集アクセスが必要 |
| アイテムのスレッドでコメントを読むことと投稿すること | デフォルトビューの設定 — 所有者のみ、UI 限定 (未検証 — 下記参照) |
| CSV のダウンロード(可能性あり)(未検証) |
レイアウトとフィルタの変更は閲覧者ごとの設定で、文書化されたアクセスゲートはない — アクセスを持つ人なら誰でも自分向けの見え方を調整できるし、誰かがすでに保存したビューの間は全員が切り替えられる。アイテム詳細ペインを開くのも同様だ。
単独で取り上げる価値のある本当の例外はこれだ。閲覧者はリストアイテムのスレッドでコメントを読むことも投稿することもできる。 これは Slack のキャンバスとは明確に異なる点で、キャンバスの閲覧専用はもっと沈黙に近い。リストでは、読み取り専用が守るのはデータ(セル、列、行)であって、各行に付随する会話ではない。
未検証
上記の「できない」のうち 3 点は実証検証の対象としてフラグが立てられていたが、このプロジェクトのスパイクがスキップされたため未検証ステータスのままだ。
ボードの列間でのカードのドラッグ。 Slack 自身のボードレイアウトの記述は「アイテムを列間で移動できる」となっており、ドラッグはおそらく閲覧者にはできないグループ化フィールドへの書き込みに当たる — しかし、ボード固有の制限ルールをその言葉で述べたページは存在しない。この制限が適用されるレイアウトの仕組みについてはボードレイアウトを参照。
デフォルトビューの設定が所有者のみであること。 元調査が報告している内容で、実際の付与に対して直接確認されたことはない。
read権限のみのユーザーによる CSV ダウンロードは確認済みというより示唆にとどまる —slackLists.download.startが要求するスコープはlists:readだけであり、閲覧者レベルのトークンでも呼べそうだと示唆されるが、実地で観測した者はいない。
いずれも全体像を変えるものではない(どちらに転んでも閲覧者の可能範囲は狭いままだ) — ダッシュボードの脅威モデルがこれらのいずれかに具体的に依存する場合にだけ問題になる。
読み取り専用の 5 つの穴
いずれも読み取り専用ダッシュボードの設計にとって致命的ではないが、「読み取りアクセス」を強固なセキュリティ境界として扱う前に、5 つとも知っておく価値がある。
閲覧者はコメントできる(前述)。アイテムのスレッド内での話だ。読み取り専用は沈黙ではない。
管理者は削除できる。 所有者と管理者は、自分が閲覧できるリストならどれでも削除できる — 誰が所有しているかに関わらず、ワークスペース管理者や組織管理者を止める ACL は存在しない。
閲覧者は閲覧アクセスをさらに再共有でき、意図した範囲を越えて広がり得る — 所有者が「Only you can share」(共有 → 詳細設定)を有効にしないかぎり。対象を限定したままにしたいダッシュボードでは必ず有効にすること。
パブリックチャンネル経由の漏洩。 「招待された人のみアクセス可能」に設定したリストをパブリックチャンネルへ共有すると、そのチャンネルのメンバーだけでなくワークスペースまたは Enterprise 組織の全員から見えるようになる。ミラーするデータが機微なら、共有先はプライベートチャンネルのみにすること。
UI の共有ダイアログはデフォルトが「Can edit」。 API 自体はこれに陥りようがない(
access_levelは必須でデフォルトがない)が、人間が UI から手作業でリストを共有すると、ドロップダウンをデフォルトから変更しないかぎりチャンネル全体に書き込みアクセスを与えてしまう。
アクセス制御とは別だが隣接するおまけの罠: リスト上に公開された Form ワークフローは、誰のアクセスレベルとも無関係にアイテムを挿入し、しかもその対象範囲はデフォルトで「全メンバー」だ — bot が排他的に所有すべきリストにはフォームを一切公開しないこと。これとは別に、「フィールド変更時に通知」する自動化が(人間の編集だけでなく)API 由来の書き込みでも発火するかは未記載だ。cron 駆動の同期にとってなぜそれが重要かは、ワンウェイミラーパターンのセットアップチェックリストを参照。
bot 管理リストの所有者構成
未検証
slackLists.create は「呼び出したユーザーが所有する」リストを作る — bot トークン(xoxb)ならそれは bot 自身のはずだが、Slack のドキュメントは「bot ユーザー」とは一度も書いておらず、「acting user」としか言っていない。これは元調査から引き継いだ推論であり、直接確認された事実ではない。
どちらにせよ実務上の落とし穴はこうだ。デフォルトビューと、ボードレイアウト / グループ化の設定は、所有者が設定するもので UI 限定 — そして bot は UI をクリックできない。 そのため、次の 2 つの構成のいずれかを選ぶことになり、どちらも書き込み権を持つ人間がちょうど 1 人残る形になる。
(a) 人間が先にリストを作成して設定する — ボードレイアウト、グループ化、デフォルトビューを手作業でセットアップする — その後 bot に
writeアクセスを、チャンネルにreadアクセスを付与する。bot が所有者になる必要はない。(b) bot がリストを作成し、その後
access.setにaccess_level: "owner"と運用担当者のuser_idsを渡して人間を昇格させる。これは bot がまだ所有者である間しか行えない — 「現在の所有者だけが別のユーザーを所有者に設定できる」。この昇格は早めに済ませること。bot が唯一の所有者のままアプリがアンインストールされた場合、文書化された復旧手段は存在しない。
どちらの構成でも、チームに読み取り専用アクセスという保証を与えられる — ただし文字どおり全人類がそうなるわけではない。書き込み権を持つ唯一の人間の名前を runbook に記録し、保証の裏に名前のある担当者を置くこと。なお、ゲストが見られるのは、自分がすでに所属しているチャンネルへ共有されたリストだけだ。
関連ページ
ボードレイアウト — 「閲覧者はカードをドラッグできない」という制限の背後にあるレイアウトの仕組み。
ワンウェイミラーパターン — これらのアクセスルールを端から端まで適用するセットアップチェックリスト(プライベートチャンネル、「Only you can share」、Form ワークフローなし)。