受管理代理程式中的憑證

憑證是由伺服器管理的密鑰,可讓代理存取第三方服務,且密鑰不會進入代理的環境。您只需儲存一次憑證,然後依 ID 參照憑證,出口 Proxy 就會在要求時解析並注入憑證。

密鑰值只能寫入,儲存後,任何端點都不會傳回這些權杖,因此遭入侵的代理程式無法讀取正在使用的權杖。

您主要會在 environment.network 的網路許可清單中使用憑證。請先儲存密鑰:

Python

from google import genai

client = genai.Client()

credential = client.credentials.create(
    id="github-production",
    type="bearer_token",
    token="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)

print(f"Credential ID: {credential.id}, Status: {credential.status}")

JavaScript

import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({});

const credential = await client.credentials.create({
    id: "github-production",
    type: "bearer_token",
    token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
});

console.log(`Credential ID: ${credential.id}, Status: ${credential.status}`);

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/credentials" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "id": "github-production",
    "type": "bearer_token",
    "token": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'

然後附加至驗證的網域:

Python

interaction = client.interactions.create(
    agent="antigravity-preview-09-2026",
    input="Triage the open issues in my-org/my-repo.",
    environment={
        "type": "remote",
        "network": {
            "allowlist": [
                {"domain": "api.github.com", "credential": "github-production"},
                {"domain": "*"},
            ]
        },
    },
)

JavaScript

const interaction = await client.interactions.create({
    agent: "antigravity-preview-09-2026",
    input: "Triage the open issues in my-org/my-repo.",
    environment: {
        type: "remote",
        network: {
            allowlist: [
                { domain: "api.github.com", credential: "github-production" },
                { domain: "*" },
            ],
        },
    },
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "agent": "antigravity-preview-09-2026",
    "input": "Triage the open issues in my-org/my-repo.",
    "environment": {
        "type": "remote",
        "network": {
            "allowlist": [
                { "domain": "api.github.com", "credential": "github-production" },
                { "domain": "*" }
            ]
        }
    }
}'

現在,代理程式會向 api.github.com 發出經過驗證的要求,且權杖絕不會出現在沙箱中。

認證類型

每項憑證都有 type,可決定憑證接受哪些欄位,以及 Proxy 如何套用憑證。

類型 用途 行為
bearer_token 個人存取權杖、機器人權杖、靜態 API 金鑰 Proxy 會將權杖插入要求標頭。沒有重新整理邏輯。
oauth2 OAuth 應用程式和使用者委派流程 Proxy 會將更新權杖換成存取權杖,並在權杖過期時更新。
environment_variable 從程序環境讀取密鑰的用戶端 SDK 代理程式的環境會收到預留位置。Proxy 會在傳出要求中替換實際密鑰。

使用網路許可清單中的憑證

credential 加入許可清單規則,Proxy 就會驗證傳送至該網域的每個外送要求。建議您採用這種方式,授予代理程式非公開 API、私人存放區或私人儲存空間的存取權。

您可以在同一個允許清單中混用已驗證和未驗證的規則:

Python

interaction = client.interactions.create(
    agent="antigravity-preview-09-2026",
    input="Sync the open Jira issues into the tracking sheet in my repo.",
    environment={
        "type": "remote",
        "sources": [
            {
                "type": "repository",
                "source": "https://github.com/your-org/backend",
                "target": "/backend-app",
            }
        ],
        "network": {
            "allowlist": [
                {"domain": "github.com", "credential": "github-production"},
                {"domain": "api.atlassian.com", "credential": "jira-oauth"},
                {"domain": "*.googleapis.com"},
            ]
        },
    },
)

JavaScript

const interaction = await client.interactions.create({
    agent: "antigravity-preview-09-2026",
    input: "Sync the open Jira issues into the tracking sheet in my repo.",
    environment: {
        type: "remote",
        sources: [
            {
                type: "repository",
                source: "https://github.com/your-org/backend",
                target: "/backend-app",
            },
        ],
        network: {
            allowlist: [
                { domain: "github.com", credential: "github-production" },
                { domain: "api.atlassian.com", credential: "jira-oauth" },
                { domain: "*.googleapis.com" },
            ],
        },
    },
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "agent": "antigravity-preview-09-2026",
    "input": "Sync the open Jira issues into the tracking sheet in my repo.",
    "environment": {
        "type": "remote",
        "sources": [
            {
                "type": "repository",
                "source": "https://github.com/your-org/backend",
                "target": "/backend-app"
            }
        ],
        "network": {
            "allowlist": [
                { "domain": "github.com", "credential": "github-production" },
                { "domain": "api.atlassian.com", "credential": "jira-oauth" },
                { "domain": "*.googleapis.com" }
            ]
        }
    }
}'

由於 Proxy 會為每個要求解析憑證,因此 oauth2 憑證會以透明方式重新整理存取權杖。存取權杖過期時,長時間執行的互動不會中斷。

合併 credentialtransform

允許清單規則也接受內嵌的 transform 物件,可直接在規則中設定標頭。這兩種機制都會由線路上的輸出 Proxy 套用,因此在兩種情況下,標頭值都不會出現在沙箱中。這兩個欄位可以出現在同一條規則中。

規則設定 行為
僅觀看credential Proxy 會解析憑證,並在每次向網域發出的要求中插入憑證標頭。
僅觀看transform 靜態標頭插入。您撰寫的標頭會照常傳送。
兩者皆有 系統會先套用憑證,然後在頂端合併 transform。如果兩者都設定相同的鍵,則以明確的 transform 標頭為準。
以上皆非 網域已獲准,且未插入任何標頭。

如果您想儲存一次密碼,並從專案中的每個環境、代理程式和觸發程序參照該密碼,以及想讓系統為您處理存取權杖重新整理和輪替作業,就適合使用憑證。如果值屬於單一呼叫,則適合使用內嵌 transform,例如您在建立互動前自行產生的權杖。

這兩者通常會合併使用。憑證會攜帶驗證標頭,而 transform 會在同一要求中新增上游服務預期的任何其他內容:

{
    "domain": "api.atlassian.com",
    "credential": "jira-oauth",
    "transform": {
        "X-Atlassian-Workspace": "my-workspace-id"
    }
}

如要將密鑰從內嵌 transform 移至憑證,請使用 POST /credentials 儲存密鑰,將 transform 中的驗證標頭替換為 "credential": "<id>",並保留 transform 物件的其餘部分。

搭配 MCP 伺服器使用憑證

遠端 MCP 伺服器會採用相同的 credential 欄位。在 mcp_server 工具上設定,Proxy 會將驗證標頭插入傳送至該伺服器的每個要求:

Python

interaction = client.interactions.create(
    agent="antigravity-preview-09-2026",
    input="Create a new issue in my-org/my-repo",
    environment="remote",
    tools=[{
        "type": "mcp_server",
        "name": "github",
        "url": "https://api.githubcopilot.com/mcp",
        "credential": "github-production",
    }],
)

JavaScript

const interaction = await client.interactions.create({
    agent: "antigravity-preview-09-2026",
    input: "Create a new issue in my-org/my-repo",
    environment: "remote",
    tools: [{
        type: "mcp_server",
        name: "github",
        url: "https://api.githubcopilot.com/mcp",
        credential: "github-production",
    }],
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "agent": "antigravity-preview-09-2026",
    "input": "Create a new issue in my-org/my-repo",
    "environment": "remote",
    "tools": [
        {
            "type": "mcp_server",
            "name": "github",
            "url": "https://api.githubcopilot.com/mcp",
            "credential": "github-production"
        }
    ]
}'

credentialheaders 遵循與許可清單相同的優先順序規則。 系統會先套用憑證,然後合併 headers,因此如果兩者都設定相同的金鑰,則會採用明確的標頭:

{
    "type": "mcp_server",
    "name": "jira",
    "url": "https://jira.atlassian.com/mcp",
    "credential": "jira-oauth",
    "headers": {
        "X-Atlassian-Workspace": "my-workspace-id"
    }
}

如要將密鑰從內嵌 headers 移至憑證,請使用 POST /credentials 儲存密鑰,並將 headers 中的驗證項目替換為 credential。 其他標題則維持原位。

將憑證設為環境變數

部分用戶端程式庫會從程序環境讀取密鑰,而不是將密鑰當做要求標頭接受。Socket 模式和長輪詢用戶端是常見情況。

environment_variable 憑證繫結至 environment.env 下的變數名稱:

Python

interaction = client.interactions.create(
    agent="antigravity-preview-09-2026",
    input="Run the sync script and check notifications.",
    environment={
        "type": "remote",
        "env": {
            "NODE_ENV": "production",
            "SLACK_BOT_TOKEN": {"credential": "slack-bot-token"},
        },
    },
)

JavaScript

const interaction = await client.interactions.create({
    agent: "antigravity-preview-09-2026",
    input: "Run the sync script and check notifications.",
    environment: {
        type: "remote",
        env: {
            NODE_ENV: "production",
            SLACK_BOT_TOKEN: { credential: "slack-bot-token" },
        },
    },
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "agent": "antigravity-preview-09-2026",
    "input": "Run the sync script and check notifications.",
    "environment": {
        "type": "remote",
        "env": {
            "NODE_ENV": "production",
            "SLACK_BOT_TOKEN": { "credential": "slack-bot-token" }
        }
    }
}'

env 會並排接受字串和憑證參照。系統會將字串常值以一般純文字變數的形式,插入容器中。

憑證參照則否。變數會收到預留位置 __GEMINI_CRED_<credential-id>__,且 Proxy 只會針對傳送至憑證 trusted_domains 中網域的外送要求,替換為實際密鑰。系統會拒絕傳送至任何其他網域的要求,因此密碼絕不會離開 perimeter,也不會傳送預留位置。

在每個 environment_variable 憑證上設定 trusted_domains。這項控制項會指定密鑰的使用範圍。

建立憑證

每項建立要求都需要 type,以及該類型要求的任何欄位。

直接呼叫 REST 時,所有欄位名稱都會使用 snake_case。傳送 camelCase 欄位會傳回 400

不記名權杖

持有人權杖憑證只需要:token

Python

credential = client.credentials.create(
    id="github-production",
    type="bearer_token",
    token="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)

JavaScript

const credential = await client.credentials.create({
    id: "github-production",
    type: "bearer_token",
    token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/credentials" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "id": "github-production",
    "type": "bearer_token",
    "token": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}'

回應只會傳回中繼資料,絕不會傳回權杖:

{
  "id": "github-production",
  "type": "bearer_token",
  "status": "active",
  "create_time": "2026-07-15T10:00:00.000000000Z",
  "update_time": "2026-07-15T10:00:00.000000000Z"
}

根據預設,Proxy 會傳送 Authorization: Bearer <token>。覆寫 header_nameprefix,以指定預期其他內容的服務:

Python

credential = client.credentials.create(
    id="my-api-key",
    type="bearer_token",
    token="key_xxxxxxxxxxxx",
    header_name="x-goog-api-key",
    prefix="",
)

JavaScript

const credential = await client.credentials.create({
    id: "my-api-key",
    type: "bearer_token",
    token: "key_xxxxxxxxxxxx",
    header_name: "x-goog-api-key",
    prefix: "",
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/credentials" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "id": "my-api-key",
    "type": "bearer_token",
    "token": "key_xxxxxxxxxxxx",
    "header_name": "x-goog-api-key",
    "prefix": ""
}'

這項設定會產生 x-goog-api-key: key_xxxxxxxxxxxx 標頭。

下表顯示 header_nameprefix 的組合方式:

設定 插入的標頭
{"token": "ghp_xxx"} Authorization: Bearer ghp_xxx
{"token": "sk_live_xxx"} Authorization: Bearer sk_live_xxx
{"token": "key_xxx", "header_name": "x-goog-api-key", "prefix": ""} x-goog-api-key: key_xxx
{"token": "mytoken", "header_name": "X-API-Token", "prefix": ""} X-API-Token: mytoken

OAuth2

OAuth2 憑證需要 client_idclient_secretrefresh_tokentoken_urlscopes 欄位為選填:

Python

credential = client.credentials.create(
    id="jira-oauth",
    type="oauth2",
    client_id="my-client-id",
    client_secret="my-client-secret",
    token_url="https://auth.atlassian.com/oauth/token",
    refresh_token="rt_xxxxxxxxxxxxxxxxxxxx",
    scopes=["read:jira-work", "write:jira-work"],
)

JavaScript

const credential = await client.credentials.create({
    id: "jira-oauth",
    type: "oauth2",
    client_id: "my-client-id",
    client_secret: "my-client-secret",
    token_url: "https://auth.atlassian.com/oauth/token",
    refresh_token: "rt_xxxxxxxxxxxxxxxxxxxx",
    scopes: ["read:jira-work", "write:jira-work"],
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/credentials" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "id": "jira-oauth",
    "type": "oauth2",
    "client_id": "my-client-id",
    "client_secret": "my-client-secret",
    "token_url": "https://auth.atlassian.com/oauth/token",
    "refresh_token": "rt_xxxxxxxxxxxxxxxxxxxx",
    "scopes": ["read:jira-work", "write:jira-work"]
}'

建立 OAuth2 憑證時,系統會對 token_url 執行即時權杖交換,確認設定是否正常運作。只有在提供者傳回含有 access_token 的成功權杖回應時,系統才會儲存憑證。系統接受 JSON 和 form-urlencoded 回應。

也就是說,您必須在建立時提供有效且未過期的更新權杖。如果供應商拒絕兌換,系統會傳回錯誤:

{
  "error": {
    "message": "OAuth token validation failed with HTTP 403: {\"error\":\"unauthorized_client\",\"error_description\":\"refresh_token is invalid\"}",
    "code": "invalid_request"
  }
}

儲存後,Proxy 會在存取權杖到期時重新整理。如果供應商輪替更新權杖,並在更新期間傳回新權杖,系統會自動以新權杖取代儲存的權杖。

環境變數

environment_variable 認證需要 valueinjection_location

Python

credential = client.credentials.create(
    id="slack-bot-token",
    type="environment_variable",
    value="xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx",
    trusted_domains=["*.slack.com", "slack.com"],
    injection_location="header",
)

JavaScript

const credential = await client.credentials.create({
    id: "slack-bot-token",
    type: "environment_variable",
    value: "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx",
    trusted_domains: ["*.slack.com", "slack.com"],
    injection_location: "header",
});

REST

curl -X POST "https://generativelanguage.googleapis.com/v1beta/credentials" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "id": "slack-bot-token",
    "type": "environment_variable",
    "value": "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx",
    "trusted_domains": ["*.slack.com", "slack.com"],
    "injection_location": "header"
}'

injection_location 欄位會告知 Proxy 要在傳出要求中的哪個位置替換密鑰。這個方法接受 headerquerybody,可做為單一字串,或在服務需要多個時做為陣列:

"injection_location": ["header", "query"]

系統只會在您列出的位置進行替換。如果要求在其他位置攜帶預留位置,系統會拒絕要求,而不是傳送要求。

如要將憑證繫結至變數名稱,請參閱「將憑證做為環境變數使用」。

產生的 ID

id 欄位為選填。省略此項,服務會產生 UUID:

{
  "id": "9e545973-4330-49bb-9a44-930cea9fbe3c",
  "type": "bearer_token",
  "status": "active",
  "create_time": "2026-07-15T10:00:00.000000000Z",
  "update_time": "2026-07-15T10:00:00.000000000Z"
}

如果您想在互動中使用穩定且可讀取的參照,請提供自己的 ID。由於 ID 會顯示在資源路徑中,建議使用含連字號或底線的小寫英數字元。

列出憑證

列出專案所屬的憑證。使用分頁參數控制回應批次大小。

Python

response = client.credentials.list(page_size=10)
for credential in response.credentials:
    print(f"Credential ID: {credential.id}, Type: {credential.type}")

JavaScript

const response = await client.credentials.list({ page_size: 10 });
for (const credential of response.credentials) {
    console.log(`Credential ID: ${credential.id}, Type: ${credential.type}`);
}

REST

curl -X GET "https://generativelanguage.googleapis.com/v1beta/credentials?page_size=10" \
-H "x-goog-api-key: $GEMINI_API_KEY"

回應只包含中繼資料:

{
  "credentials": [
    {
      "id": "github-production",
      "type": "bearer_token",
      "status": "active",
      "create_time": "2026-07-15T10:00:00.000000000Z",
      "update_time": "2026-07-15T10:00:00.000000000Z"
    },
    {
      "id": "jira-oauth",
      "type": "oauth2",
      "status": "active",
      "create_time": "2026-07-15T10:05:00.000000000Z",
      "update_time": "2026-07-15T10:05:00.000000000Z"
    }
  ],
  "next_page_token": "Cj...5aE="
}

next_page_token 做為 page_token 傳回,即可擷取下一頁。如果沒有其他結果,則會省略此欄位。

參數 類型 說明
page_size 整數 每頁的憑證數量上限。
page_token 字串 前一則回覆的 next_page_token 中的權杖。

取得憑證

依 ID 擷取特定憑證的中繼資料。

Python

credential = client.credentials.get(id="github-production")
print(f"Credential ID: {credential.id}, Status: {credential.status}")

JavaScript

const credential = await client.credentials.get("github-production");
console.log(`Credential ID: ${credential.id}, Status: ${credential.status}`);

REST

curl -X GET "https://generativelanguage.googleapis.com/v1beta/credentials/github-production" \
-H "x-goog-api-key: $GEMINI_API_KEY"

回應類似於下列內容:

{
  "id": "github-production",
  "type": "bearer_token",
  "status": "active",
  "create_time": "2026-07-15T10:00:00.000000000Z",
  "update_time": "2026-08-01T14:30:00.000000000Z"
}

要求不存在的憑證會傳回 404

{
  "error": {
    "message": "Result not found.; GetCredential call failed",
    "code": "not_found"
  }
}

輪替憑證

替換密鑰,但不要變更任何參照該密鑰的許可清單規則、工具定義或環境變數。輪替會在下次 Proxy 解析時生效。

要求必須包含 type,以及要變更的欄位。如果省略欄位,系統會保留目前的值。

輪替不記名權杖:

Python

credential = client.credentials.update(
    id="github-production",
    type="bearer_token",
    token="ghp_new_xxxxxxxxxxxxxxxxxxxx",
)

JavaScript

const credential = await client.credentials.update("github-production", {
    type: "bearer_token",
    token: "ghp_new_xxxxxxxxxxxxxxxxxxxx",
});

REST

curl -X PATCH "https://generativelanguage.googleapis.com/v1beta/credentials/github-production" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "type": "bearer_token",
    "token": "ghp_new_xxxxxxxxxxxxxxxxxxxx"
}'

輪替 OAuth2 更新權杖:

Python

credential = client.credentials.update(
    id="jira-oauth",
    type="oauth2",
    refresh_token="rt_new_xxxxxxxxxxxxxxxxxxxx",
)

JavaScript

const credential = await client.credentials.update("jira-oauth", {
    type: "oauth2",
    refresh_token: "rt_new_xxxxxxxxxxxxxxxxxxxx",
});

REST

curl -X PATCH "https://generativelanguage.googleapis.com/v1beta/credentials/jira-oauth" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
    "type": "oauth2",
    "refresh_token": "rt_new_xxxxxxxxxxxxxxxxxxxx"
}'

回覆內容會反映新的 update_time

{
  "id": "jira-oauth",
  "type": "oauth2",
  "status": "active",
  "create_time": "2026-07-15T10:05:00.000000000Z",
  "update_time": "2026-08-01T14:30:00.000000000Z"
}

憑證的 type 在建立時即固定,如要變更,請刪除憑證並重新建立。

刪除憑證

不再需要憑證時,請刪除憑證和儲存的密鑰。

Python

client.credentials.delete(id="github-production")

JavaScript

await client.credentials.delete("github-production");

REST

curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/credentials/github-production" \
-H "x-goog-api-key: $GEMINI_API_KEY"

如果刪除成功,會傳回空白物件:

{}

如果任何允許清單規則、工具或環境變數仍參照該 ID,將無法解析,因此請先更新這些項目。

欄位參照

所有憑證都有的欄位:

欄位 類型 必要 說明
id 字串 專屬 ID。如果省略,系統會以 UUID 形式產生。
type 字串 可能的值為 bearer_tokenoauth2environment_variable
status 字串 唯讀 憑證的目前狀態。
create_time 字串 唯讀 RFC 3339 建立時間戳記。
update_time 字串 唯讀 上次更新的 RFC 3339 時間戳記。

bearer_token」的欄位:

欄位 類型 必要 說明
token 字串 唯寫。權杖值。
header_name 字串 要插入的標頭。預設值為 Authorization
prefix 字串 值前置字元。預設為 Bearer。如要停用,請設為 ""

oauth2」的欄位:

欄位 類型 必要 說明
client_id 字串 OAuth2 用戶端 ID。
client_secret 字串 唯寫。OAuth2 用戶端密鑰。
refresh_token 字串 唯寫。用於取得存取權杖的更新權杖。
token_url 字串 提供者權杖端點。
scopes 陣列 要要求的 OAuth 範圍。

environment_variable」的欄位:

欄位 類型 必要 說明
value 字串 唯寫。密鑰值。
injection_location 字串或陣列 要替換密鑰的位置。headerquerybody 其中一或多個。
trusted_domains 陣列 可替換的授權網域模式。

錯誤

錯誤會傳回含有 messagecode 的 JSON 物件:

{
  "error": {
    "message": "Credential 'github-production' already exists.; CreateCredential call failed",
    "code": "aborted"
  }
}
HTTP 狀態 code 原因
400 invalid_request 缺少必填欄位、欄位不明、不支援 type,或 OAuth2 驗證失敗。
404 not_found 找不到該 ID 的憑證。
409 aborted 已有 ID 相同的憑證。

系統會拒絕不明欄位,而非忽略,且錯誤會命名該欄位:

{
  "error": {
    "message": "Unknown parameter 'headerName'. Did you mean 'header_name'?",
    "code": "invalid_request"
  }
}

後續步驟