デプロイのアクセス制御
access カテゴリの API 操作を 5 件カバーします。
| メソッド | パス | 説明 |
|---|---|---|
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/access | デプロイのアクセスポリシー(runlot access) |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/access | ポリシーを変更します(runlot access set) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/access/bypass | 自動化用のバイパスキーを発行します(runlot access bypass --new) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/access/bypass | バイパスキーを無効化します(runlot access bypass --revoke) |
| POST | /v1/access/authorize | 保護されたデプロイにアクセスするためのワンタイムコード(docs/access.md §3.4-3) |
GET /v1/orgs/{orgSlug}/projects/{projectName}/access
このデプロイに誰がアクセスできるか(docs/access.md §3.1)。ポリシーを一度も設定していないプロジェクトは 404 ではなく public です — ほとんどのプロジェクトがこの状態です。
値はありません。パスワードはどの画面にも表示されず、バイパスシークレットは作成時に一度だけ表示されます。
viewer 以上 — このデプロイが公開されているかどうかは、org 内の誰もが知っておくべき事実です。
operationId getAccess
| ステータスコード | 説明 | レスポンスボディ |
|---|---|---|
| 200 | ポリシー | AccessPolicy |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — cp-core への接続がありません | Error |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/access
public は現在の動作を維持し、org はプロジェクトが属する org の member 以上を意味し、password はプロジェクトごとに1つの共有パスワードを意味します — ユーザーごとになった瞬間、それは subscriber テーブルの問題であり、この API の対象外です(docs/access.md §3.1)。
パスワードを送信しない場合、既存のパスワードはそのまま維持されます。 モードのみを変更する保存でパスワードもクリアされてしまうと、元に戻す際に再設定が必要になり、その不便さは安全性の向上にはつながりません。クリアしたい場合は新しい値を送信してください。
admin 以上が必要です。 member が境界を変更できるなら、それは境界とは言えません。access.set として監査記録されます(パスワード自体は監査に含まれません)。
operationId setAccess
リクエストボディ: application/json ・ object
| ステータスコード | 説明 | レスポンスボディ |
|---|---|---|
| 200 | 変更後のポリシー | AccessPolicy |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/access/bypass
これは CI が保護されたデプロイにアクセスするために使用するキーです(docs/access.md §3.6)。Runlot-Access-Bypass: <secret> リクエストヘッダーで送信してください。
この値はこのレスポンスにのみ表示されます。 再度確認することはできず、このエンドポイントを再度呼び出すと古い値は即座に無効になります — これが漏洩したシークレットを無効化する唯一の方法です。
このキーがないと CI は保護されたデプロイにアクセスできず、保護を無効にせざるを得なくなる場合があります。admin 以上が必要です。監査イベント access.bypass.new にキーの値は記録されません。
operationId newAccessBypass
| ステータスコード | 説明 | レスポンスボディ |
|---|---|---|
| 200 | バイパスキー(一度だけ表示されます) | AccessBypass |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/access/bypass
バイパスキーが存在しない場合でも 204 を返します。アクセスポリシー自体は変更されません。バイパスキーはポリシーとは別に管理されます。admin 以上が使用できます。access.bypass.revoke として監査記録されます。
operationId revokeAccessBypass
| ステータスコード | 説明 | レスポンスボディ |
|---|---|---|
| 204 | 切断済み | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
POST /v1/access/authorize
これはログインの往復フローの中間に位置します。保護されたデプロイへのリクエストがダッシュボードの /access/authorize 画面に戻ってくると、その画面がセッションとともにこの呼び出しを行い、受け取った redirect へ遷移します。そのコールバックを受け取るフロントエンドが Cookie を設定します — 異なるオリジンからは設定できないという事実が、このフロー全体の形を決めています。
to は既知のホスト名である必要があります。そうでない場合、404 を返します。このチェックがなければ、このエンドポイントはセッションを保持するユーザーを任意のドメインへ送るオープンリダイレクトになり、そのドメインがコードを受け取ってしまいます。next もパスのみを受け付けます(//evil.example は絶対アドレスとして解釈されます)。
org 外のユーザーは 403 になります — 再ログインしても結果は同じです(§3.7)。重要なのは member 以上ではなくviewer 以上であるという点です。デプロイを閲覧することはまさに viewer の役割だからです。
ドキュメントの §3.4-2 では、このフローをブラウザの GET /access/authorize として説明しています。ダッシュボードはセッショントークンを localStorage に保存するため、サーバーはその GET でセッションを確認できません。そのため、遷移を行う主体がサーバーからブラウザに変わっただけで、判定結果は変わりません。
operationId authorizeAccess
リクエストボディ: application/json ・ object
| ステータスコード | 説明 | レスポンスボディ |
|---|---|---|
| 200 | コールバック URL | AccessAuthorize |
| 400 | — | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |