> ## 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 用戶端憑證。每個用戶端都隸屬於一個服務帳戶和一個組織。\*\*OAuth 為選用功能：\*\*對於能夠安全儲存並輪替金鑰的私有伺服器整合，具範圍限制的 API 金鑰即已足夠。如需選擇這兩種方法並了解服務帳戶的適用方式，請參閱[驗證](/zh-Hant/developers/v1/authentication)。

<Note>
  您的組織必須已啟用 OAuth 存取。您的設定會提供區域權杖端點、簽發者、受眾以及用戶端驗證方法。如果您需要這些設定，或無法存取用戶端管理功能，請聯絡 Living Security 支援團隊。
</Note>

用戶端憑證授權（client credentials grant）代表的是您的服務帳戶。它不會讓任何人登入，也不會要求客戶授權應用程式。透過瀏覽器進行的委派授權屬於另一項 OAuth 功能，這些作業並未提供該功能。

## 開始之前

* 建立一個[服務帳戶](/zh-Hant/developers/developer-hub/service-accounts)，且僅授予整合所需的權限。
* 使用具備 `service_account:manage` 以及您要授予新用戶端之每項權限的管理憑證。目標帳戶也必須持有這些權限。用戶端無法擴大任一帳戶的授權範圍。
* 選擇組織所在的[區域](/zh-Hant/developers/v1/regions)。API 憑證與 OAuth 存取權杖必須用於對應的區域 API 主機。
* 請將用戶端密鑰與權杖保存在伺服器端的密鑰儲存庫中。切勿將它們放入瀏覽器程式碼、行動應用程式、原始碼控管或請求記錄中。

## 建立用戶端

`POST /v1/oauth_clients` 需要 `service_account_id`、一份非空且明確列出的 `scopes` 清單，以及一個 `Idempotency-Key`。不接受萬用字元。每個用戶端最多支援 100 個範圍，總長度不得超過 4,096 個字元。每個服務帳戶最多可擁有 20 個用戶端或未完成的建立／清理作業。撤銷會立即拒絕 API 存取。在遠端清理獲得確認之前，用戶端或結果不確定的提供者端建立作業仍會計入上限。已放棄的預留，或已證實在提供者端作業開始前即失敗的建立作業，可安全地釋出其名額。其重試金鑰仍屬於原始嘗試；在決定是否建立替代用戶端之前，請先復原該收據。

請為此次建立嘗試選擇一個重試金鑰，並在傳送請求**之前**將其持久化保存。請使用 1–255 個可見的 ASCII 字元，且不含空格。在回應遺失後，請搭配相同的帳戶、範圍、管理主體、區域與 API 版本重複使用該金鑰。在同一服務帳戶下輪替管理憑證，不會產生新的重試身分。

請安裝 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()
```

此範例只發出一次請求，並將結果保留在記憶體中。在正式環境執行之前，請在標示之處加入您的密鑰管理工具的寫入作業。範例刻意要求在結果不確定時由您做出決定，而不是默默地再建立另一個用戶端。網路例外狀況同樣需要執行下列復原步驟。

建立與收據回應使用 `201`，並包含一個 `oauth_client` 資源，其中具有 `id`、`service_account_id`、`client_id`、`scopes`、`status`、`created_at` 與 `client_secret`。回應會標記為 `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 與復原詳細資訊，請參閱[錯誤](/zh-Hant/developers/v1/errors/overview)。切勿在支援請求中附上用戶端密鑰或存取權杖。

## 檢視與撤銷

請使用您的管理憑證與平台資源 `id`：

| 作業 | 請求 | 成功 |
| - | - | - |
| 檢視目前狀態 | `GET /v1/oauth_clients/{id}` | `200`，不含密鑰的用戶端資源 |
| 撤銷存取 | `DELETE /v1/oauth_clients/{id}` | `200`，不含密鑰的已撤銷用戶端資源 |

撤銷會封鎖該用戶端後續的 API 請求，包括使用已簽發權杖的請求。但它不會取消 API 已接受的工作。遠端憑證清理可能稍後才會完成。重複執行撤銷是安全的，且不需要重試金鑰。如果被撤銷的用戶端本身就是 API 呼叫者，請繼續使用管理憑證。

## 在不中斷存取的情況下輪替

請建立第二個用戶端，並設定所需的範圍上限。儲存其密鑰，使用您的區域權杖端點取得權杖，並驗證整合可以透過它正常運作。將整合切換至替代用戶端，然後撤銷舊資源。請保留一組獨立的管理憑證，以便在部署出錯時進行復原。

存取權杖所能授予的權限，不會超過用戶端的範圍與服務帳戶目前的權限。移除帳戶權限或撤銷用戶端，其效力優先於權杖的剩餘有效期限。請勿將快取的權杖視為授權仍然有效的證明。請在到期前重新驗證用戶端以取得新的存取權杖；此授權方式不使用重新整理權杖。


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