> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livingsecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth クライアント認証情報

> スコープを限定したサービスアカウントクライアントのプロビジョニング、一度だけ表示されるシークレットの取り扱い、および結果が不確かなリクエストからの安全な復旧方法について説明します。

バックエンド連携で有効期間の短いアクセストークンが必要な場合、またはセキュリティポリシーで求められている場合は、OAuth クライアント認証情報を使用します。各クライアントは、1 つのサービスアカウントと 1 つの組織に属します。**OAuth の使用は任意です。** キーを安全に保管およびローテーションできるプライベートなサーバー連携であれば、スコープを限定した API キーで十分です。2 つの方式の選択方法およびサービスアカウントの位置づけについては、[認証](/ja/developers/v1/authentication)を参照してください。

<Note>
  組織で OAuth アクセスを有効にする必要があります。リージョン別のトークンエンドポイント、発行者、オーディエンス、およびクライアント認証方式は、セットアップ時に提供されます。これらの設定が必要な場合、またはクライアント管理にアクセスできない場合は、Living Security サポートまでお問い合わせください。
</Note>

クライアント認証情報グラントは、サービスアカウントを表します。ユーザーのサインインや、顧客によるアプリケーションの承認は行いません。ブラウザー経由の委任認可は別の OAuth 機能であり、これらの操作では提供されません。

## 開始する前に

* 連携に必要な権限のみを付与した[サービスアカウント](/ja/developers/developer-hub/service-accounts)を作成します。
* `service_account:manage` と、新しいクライアントに付与する各権限を持つ管理用認証情報を使用します。対象アカウントもそれらの権限を保有している必要があります。クライアントがどちらのアカウントの権限も拡張することはできません。
* 組織の[リージョン](/ja/developers/v1/regions)を選択します。API 認証情報と OAuth アクセストークンは、対応するリージョンの API ホストで使用してください。
* クライアントシークレットとトークンは、サーバー側のシークレットストレージに保管してください。ブラウザーコード、モバイルアプリケーション、ソース管理、リクエストログには絶対に含めないでください。

## クライアントを作成する

`POST /v1/oauth_clients` には、`service_account_id`、明示的な `scopes` の空でないリスト、および `Idempotency-Key` が必要です。ワイルドカードは使用できません。1 つのクライアントがサポートするスコープは最大 100 個で、合計の長さは最大 4,096 文字です。各サービスアカウントが持てるクライアント数、または未解決の作成/クリーンアップ操作の数は、合わせて最大 20 件です。失効させると、API アクセスは直ちに拒否されます。クライアント、またはプロバイダー側での作成結果が不確かな状態のものは、リモートのクリーンアップが確認されるまで上限に対してカウントされ続けます。放棄された予約、またはプロバイダー側の処理が始まる前に失敗したことが確認された作成は、安全に枠を解放できます。そのリトライキーは引き続き元の試行に属します。代替のクライアントを作成するかどうかを判断する前に、そのレシートを復旧してください。

この作成試行に使用するリトライキーを 1 つ選び、リクエストを送信する**前**に永続化してください。リトライキーには、スペースを含まない 1～255 文字の可視 ASCII 文字を使用します。レスポンスが失われた後は、同じアカウント、スコープ、管理プリンシパル、リージョン、API バージョンでこのキーを再利用してください。同じサービスアカウントで管理用認証情報をローテーションしても、新しいリトライ ID は作成されません。

Python の `requests` パッケージをインストールします。通常のシークレット管理および構成管理の仕組みを使用して、次の環境値を読み込みます。

| 変数 | 値 |
| - | - |
| `LIVING_SECURITY_API_KEY` | 管理用 API キー |
| `LIVING_SECURITY_REGION` | `us` または `eu` |
| `LIVING_SECURITY_SERVICE_ACCOUNT_ID` | 対象サービスアカウント ID |
| `LIVING_SECURITY_OAUTH_CREATE_KEY` | 事前に永続化したリトライキー |

```python Python theme={null}
import os
import requests

HOSTS = {
    "us": "https://api.us-east-1.livingsecurity.ai/v1",
    "eu": "https://api.eu-west-1.livingsecurity.ai/v1",
}
base = HOSTS[os.environ["LIVING_SECURITY_REGION"]]
response = requests.post(
    f"{base}/oauth_clients",
    auth=("apikey", os.environ["LIVING_SECURITY_API_KEY"]),
    headers={
        "Living-Security-Version": "2026-07-01",
        "Idempotency-Key": os.environ["LIVING_SECURITY_OAUTH_CREATE_KEY"],
    },
    json={
        "service_account_id": os.environ["LIVING_SECURITY_SERVICE_ACCOUNT_ID"],
        "scopes": ["organization:read"],
    },
    timeout=(5, 30),
    allow_redirects=False,
)
try:
    if response.status_code != 201:
        raise RuntimeError(
            f"Client creation needs review: HTTP {response.status_code}; "
            f"request_id={response.headers.get('Request-Id', 'unknown')}"
        )
    client = response.json()
    if client.get("object") != "oauth_client" or not client.get("id"):
        raise RuntimeError("Unexpected client receipt; preserve the retry key")
    if client.get("status") != "active" or not client.get("client_secret"):
        raise RuntimeError(
            f"Client {client['id']} needs recovery; no usable secret was returned"
        )
    # Persist client['id'], client['client_id'], and client['client_secret']
    # directly in your secret manager before using the client. Do not print them.
finally:
    response.close()
```

この例では、リクエストを 1 回送信し、結果をメモリ内に保持します。本番環境で実行する前に、マークされた箇所にお使いのシークレットマネージャーの書き込み操作を追加してください。結果が不確かな場合は、別のクライアントを黙って作成するのではなく、意図的に判断を求める設計になっています。ネットワーク例外が発生した場合も、以下の復旧手順が必要です。

作成とレシートのレスポンスは `201` を使用し、`id`、`service_account_id`、`client_id`、`scopes`、`status`、`created_at`、`client_secret` を含む `oauth_client` リソースを含みます。レスポンスには `Cache-Control: no-store` のマークが付きます。

* **`id`** はプラットフォームのリソースを識別します。取得および失効のために保存してください。
* **`client_id`** はトークン交換時にクライアントを識別します。プラットフォームのリソース ID ではありません。作成が保留中の間は `null` になることがあります。
* **`client_secret`** は、作成を完了させたリクエストにのみ返されます。成功レスポンスが失われた後の再試行を含め、繰り返された作成リクエストには、すべて `null` が返されます。取得操作でシークレットが返されることはありません。

## 失われた、または中断されたレスポンスから復旧する

保存しておいたリトライキーを使用して同じ作成リクエストを繰り返すと、リソースのレシートを復旧できます。レシートは現在の状態を反映するため、失効したクライアントは失効したままです。この操作は、一般的な 24 時間のキャッシュ済みレスポンス再生の仕組みを使用せず、`Idempotent-Replayed` ヘッダーも返しません。

| 結果 | 次の操作 |
| - | - |
| `active`、シークレットあり | シークレットを安全に保存し、オンボーディングを続行します。 |
| `active`、シークレットなし | シークレットは復旧できません。このクライアントを失効させ、失効を確認してから、新しいリトライキーを使用して代替のクライアントを作成します。 |
| `pending` | 作成が未確認です。同じリトライキーを保持してください。リソースを取得して状態を確認します。不確かな状態を回避するために重複を作成しないでください。 |
| `revoked`、`disabled`、または `expired` | このクライアントは使用しないでください。代替をプロビジョニングする前に、意図したアカウント構成を確認します。 |
| `409 idempotency_key_reuse` | 既存のキーでリクエスト内容が変更されました。別の作成が必要かどうかを判断する前に、元の操作を復旧してください。 |
| `409 invalid_request` | 対象アカウントのステータスと付与内容を確認します。クライアント数の上限に達している場合は、再試行する前にクリーンアップを完了してください。リトライキーを変更しても空き枠は増えません。 |
| `429` | `Retry-After` に従い、同じキーと同じリクエストを保持します。 |
| `500`、`503`、またはネットワークタイムアウト | 結果が不明である可能性があります。キーと入力内容を保持し、別のクライアントを作成する前にレシートを復旧してください。 |
| `401` または `403` | 再試行する前に、認証情報、権限、またはエンタイトルメントに関するアクセスの問題を解決してください。 |
| `404` | OAuth の有効化、リージョンのホスト、およびリソースの所有権を確認します。 |

リクエスト ID と復旧の詳細については、[エラー](/ja/developers/v1/errors/overview)を参照してください。サポートへの問い合わせに、クライアントシークレットやアクセストークンを送信しないでください。

## 確認と失効

管理用認証情報とプラットフォームのリソース `id` を使用します。

| 操作 | リクエスト | 成功時 |
| - | - | - |
| 現在の状態を確認 | `GET /v1/oauth_clients/{id}` | `200`、シークレットを含まないクライアントリソース |
| アクセスを失効 | `DELETE /v1/oauth_clients/{id}` | `200`、シークレットを含まない失効済みクライアントリソース |

失効させると、発行済みのトークンを使用するリクエストも含め、そのクライアントによる以降の API リクエストはブロックされます。API がすでに受け付けた処理は取り消されません。リモートの認証情報のクリーンアップは、後から完了する場合があります。失効の繰り返しは安全で、リトライキーは不要です。失効させるクライアント自体が API の呼び出し元である場合は、引き続き管理用認証情報を使用してください。

## アクセスを失わずにローテーションする

必要なスコープの上限を持つ 2 つ目のクライアントを作成します。そのシークレットを保存し、リージョンのトークンエンドポイントを使用してトークンを取得し、連携がそのクライアントで動作することを確認します。連携を代替のクライアントに切り替えてから、古いリソースを失効させます。不適切なロールアウトから復旧できるように、独立した管理用認証情報を保持してください。

アクセストークンは、クライアントのスコープおよびサービスアカウントの現在の権限を超える権限を付与できません。アカウントの権限の削除やクライアントの失効は、トークンの残りの有効期間よりも優先されます。キャッシュされたトークンを、認可が引き続き有効であることの証拠として扱わないでください。有効期限が切れる前に、クライアントを再度認証して新しいアクセストークンを取得してください。このグラントではリフレッシュトークンは使用されません。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.