コンテンツにスキップ
HaneDOCSEN

Hane Platform

組織・プロジェクト・環境

組織・プロジェクト・環境の階層と、メンバーの招待、ロールと権限、サービスアカウントと API キー、緊急停止を説明します。

このページでは、Hane のアクセスの単位である組織・プロジェクト・環境と、そこに入る人とプログラムの管理(メンバー、ロール、サービスアカウント、API キー)を説明します。

階層 意味 持つもの
組織 Hane を契約する単位。データと権限はここで分かれる メンバー、グループ、ロール、プロジェクトの一覧、緊急停止
プロジェクト 組織の中で、定義とデータを分ける単位。業務アプリや用途ごとに作る 環境、サービスアカウント、定義、業務データ
環境 同じプロジェクトの dev・stage・prod 環境ごとの業務データ、資格情報、有効なバージョン

プロジェクトを作ると、dev・stage・prod の 3 つの環境がそろいます。組織・プロジェクト・環境は URL に入れず、要求に付けた資格情報から決まります。

IdP でログインした利用者は、組織を作れます。まだ組織に入っていないので、IdP の ID トークンをそのまま付けて呼べます。作った人がその組織の owner になります。name は英小文字・数字・ハイフンで、URL やコマンドで使う識別子になります。組織を作れる人を提供側が限っている環境では、許された人だけが作れます。

POST /v1/platform/organizations
Authorization: Bearer <ID トークン>
Idempotency-Key: 7d0c…
Content-Type: application/json
{ "name": "acme", "display_name": "ACME 商事" }

プロジェクトは POST /v1/platform/projects に同じ形(name・display_name)で作ります。platform:projects.manage のスコープが要ります。

組織の利用者はメンバーとして管理します。人の資格情報(パスワードや多要素認証)は顧客の IdP が持ち、Hane は IdP の ID トークンを Hane のアクセストークンに交換して使います。

招待は、メールアドレスとロールを指定して行います。

POST /v1/platform/members
Authorization: Bearer <アクセストークン>
Idempotency-Key: 2f61…
Content-Type: application/json
{ "email": "sato@example.com", "roles": ["operator"], "display_name": "佐藤" }

招待したメンバーは invited の状態で作られます。招待された人が IdP でログインし、同じメールアドレスでアクセストークンを取ると、そのメンバーは active になります。組織に入る前でも、GET /v1/auth/me で自分が招待されている組織を確かめられます。

操作 API
メンバーの一覧 GET /v1/platform/members
ロールの変更 PUT /v1/platform/members/{id}/roles
組織から外す DELETE /v1/platform/members/{id}。その人のトークンは次の呼出しから拒否される。owner を外せるのは owner だけで、最後の owner は外せない
グループの作成・メンバーの置き換え PUT /v1/platform/groups/{name}。グループは Task を割り当てる単位にもなる
不在の間の代理 PUT /v1/platform/members/{id}/delegation。期間中、担当の候補を代理のメンバーへ回す

メンバーの権限はロールで決まります。ロールは組織全体に効き、ロールごとに使える公開 API のスコープ(<サービス>:<資源>.<操作> の形)が決まっています。

ロール 主にできること
owner すべての操作。緊急停止の解除は owner だけができる
admin すべてのスコープ。メンバー・サービスアカウント・API キーの管理、決定者の上書きの解除など
developer 読み取りに加えて、定義の apply と ReleaseBundle の作成・有効化、業務データの書込み、案件の操作、Agent の実行、監査の閲覧
operator 読み取りに加えて、業務データの書込みと値の確定、案件の操作、Task と承認の決定、連絡先の管理、文書の管理、Agent の実行
viewer 各サービスの読み取りだけ

いくつかの操作には、スコープに加えて「人であること」が必要です。値を確定にすること、Task と承認を決めることは、人の利用者だけができ、サービスアカウントや AI にはできません。

ロールは API での割り当てに加えて、マニフェストの RoleBinding でも足せます。RoleBinding は設定なので、apply するとすぐ効きます。owner は割り当てられず、API で割り当てたロールを外すこともしません。

apiVersion: platform/v1alpha1
kind: RoleBinding
metadata:
name: fleet-operators
spec:
roles: [operator]
subjects:
- { kind: Group, name: fleet-desk }
- { kind: User, name: sato@example.com }

ロール・グループ・API キーが変わるたびに、組織の権限の世代(policy_epoch)が上がります。古い世代で発行したトークンは拒否されるので、権限を外したときは次の呼出しから効きます。

業務アプリのサーバーや CI のような、人でない呼出し元にはサービスアカウントを作ります。サービスアカウントは 1 つのプロジェクトの 1 つの環境に結び付き、使えるスコープを指定して作ります。

POST /v1/platform/service-accounts
Authorization: Bearer <アクセストークン>
Idempotency-Key: 9a3e…
Content-Type: application/json
{ "name": "fleet-app", "project": "fleet", "environment": "dev",
"scopes": ["data:records.read", "data:records.write", "workflows:read"] }

API キーは POST /v1/platform/service-accounts/{id}/keys で発行します。expires_at で期限を付けられ、省くと期限なしです。

  • キーの値(secret)は発行の応答でだけ返ります。Hane はハッシュだけを保存するので、あとから表示できません。
  • キーは hane_<環境>_ で始まります。漏洩したキーを見つけやすくするためです。
  • 要らなくなったキーは DELETE /v1/platform/service-accounts/{id}/keys/{keyId} で失効させます。
  • API キーはサーバー側に置き、ブラウザに渡さないでください。利用者の操作として API を呼ぶときは、利用者のアクセストークンを使います。

業務アプリが利用者の代わりに API を呼ぶときは、利用者の ID トークンとアプリの API キーを合わせてアクセストークンに交換できます。このとき使えるスコープは、利用者とアプリのスコープの共通部分になり、承認や Task の決定は利用者本人として記録されます。手順は 認証 を参照してください。

組織で問題が起きたときは、緊急停止をかけてすべての API と実行を止められます。platform:suspend のスコープと、理由の記入が必要です。

POST /v1/platform/suspension
Authorization: Bearer <アクセストークン>
Idempotency-Key: c41b…
Content-Type: application/json
{ "reason": "誤った送信が続いているため" }

止めている間の要求は TENANT_SUSPENDED で断られます。解除は DELETE /v1/platform/suspension で、owner だけができます。