Учетные данные – это секреты, управляемые сервером, которые позволяют агентам получать доступ к сторонним сервисам, не вводя секрет в среду агента. Вы сохраняете учетные данные один раз, ссылаетесь на них по идентификатору, а исходящий прокси-сервер разрешает и вставляет их во время запроса.
Значения секретов доступны только для записи. После сохранения они никогда не возвращаются ни одной конечной точкой, поэтому взломанный агент не может прочитать используемые им токены.
Основное место, где используются учетные данные, – это белый список сети на странице 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}`);
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Create(ctx, operations.CreateCredentialRequest{
Body: credentials.NewCredentialCreateParams(credentials.HTTPBearerConfig{
ID: "github-production",
Token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Credential ID: %s, Status: %v\n", res.Credential.ID, res.Credential.GetStatus())
}
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: "*" },
],
},
},
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{
Agent: interactions.AgentOption("antigravity-preview-09-2026"),
Input: interactions.NewInteractionsInput("Triage the open issues in my-org/my-repo."),
Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment(interactions.Environment{
Network: genai.Ptr(interactions.NewNetwork(interactions.EnvironmentNetworkEgressAllowlist{
Allowlist: genai.Ptr(interactions.NewAllowlist([]interactions.AllowlistEntry{
{Domain: "api.github.com", Credential: genai.Ptr("github-production")},
{Domain: "*"},
})),
})),
})),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Interaction.GetOutputText())
}
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, который определяет, какие поля он принимает и как прокси-сервер применяет его.
| Тип | Пример использования | Поведение |
|---|---|---|
bearer_token |
Персональные токены доступа, токены ботов, статические ключи API | Прокси-сервер вставляет токен в качестве заголовка запроса. Нет логики обновления. |
oauth2 |
Приложения OAuth и потоки с делегированием прав пользователя | Прокси-сервер обменивает токен обновления на токены доступа и обновляет их по истечении срока действия. |
environment_variable |
Клиентские SDK, которые считывают секреты из среды процесса | В среде агента появится плейсхолдер. Прокси-сервер заменяет секретный ключ в исходящих запросах. |
Используйте учетные данные из белого списка сети.
Добавьте credential в правило белого списка, и прокси-сервер будет аутентифицировать каждый исходящий запрос к этому домену. Это рекомендуемый способ предоставить агенту доступ к частному 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" },
],
},
},
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{
Agent: interactions.AgentOption("antigravity-preview-09-2026"),
Input: interactions.NewInteractionsInput("Sync the open Jira issues into the tracking sheet in my repo."),
Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment(interactions.Environment{
Sources: []interactions.Source{
{
Type: interactions.SourceTypeRepository.ToPointer(),
Source: genai.Ptr("https://github.com/your-org/backend"),
Target: genai.Ptr("/backend-app"),
},
},
Network: genai.Ptr(interactions.NewNetwork(interactions.EnvironmentNetworkEgressAllowlist{
Allowlist: genai.Ptr(interactions.NewAllowlist([]interactions.AllowlistEntry{
{Domain: "github.com", Credential: genai.Ptr("github-production")},
{Domain: "api.atlassian.com", Credential: genai.Ptr("jira-oauth")},
{Domain: "*.googleapis.com"},
})),
})),
})),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Interaction.GetOutputText())
}
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" }
]
}
}
}'
Поскольку прокси-сервер обрабатывает учетные данные по запросу, учетные данные oauth2 прозрачно обновляют токен доступа. Долго выполняемое взаимодействие не прерывается, когда срок действия токена доступа истекает.
Сочетание эмодзи credential и transform
Правила белого списка также принимают встроенный объект transform, который задает заголовки непосредственно в правиле. Оба механизма применяются исходящим прокси-сервером, поэтому в обоих случаях значение заголовка никогда не существует в песочнице. Оба поля могут быть указаны в одном правиле.
| Конфигурация правила | Поведение |
|---|---|
Только credential |
Прокси-сервер разрешает учетные данные и вставляет их заголовок в каждый запрос к домену. |
Только 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, и прокси-сервер будет добавлять заголовок авторизации в каждый запрос к этому серверу:
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",
}],
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{
Agent: interactions.AgentOption("antigravity-preview-09-2026"),
Input: interactions.NewInteractionsInput("Create a new issue in my-org/my-repo"),
Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment(interactions.Environment{
Network: genai.Ptr(interactions.NewNetwork(interactions.EnvironmentNetworkEgressAllowlist{
Allowlist: genai.Ptr(interactions.NewAllowlist([]interactions.AllowlistEntry{
{Domain: "api.githubcopilot.com", Credential: genai.Ptr("github-production")},
})),
})),
})),
Tools: []interactions.Tool{
interactions.NewTool(interactions.MCPServer{
Name: genai.Ptr("github"),
URL: genai.Ptr("https://api.githubcopilot.com/mcp"),
}),
},
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Interaction.GetOutputText())
}
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"
}
]
}'
Правила credential и headers имеют тот же приоритет, что и белый список.
Сначала применяется учетные данные, а затем 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.
Остальные заголовки оставьте на своих местах.
Используйте учетные данные в качестве переменных среды
Некоторые клиентские библиотеки считывают секреты из среды процесса, а не принимают их в качестве заголовков запросов. Клиенты в режиме сокетов и с длительным опросом – это распространенный случай.
Привяжите учетные данные 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" },
},
},
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateAgentInteraction{
Agent: interactions.AgentOption("antigravity-preview-09-2026"),
Input: interactions.NewInteractionsInput("Run the sync script and check notifications."),
Environment: genai.Ptr(interactions.NewCreateAgentInteractionEnvironment(interactions.Environment{
Env: genai.Ptr(interactions.NewEnv(map[string]interactions.EnvVar{
"NODE_ENV": {Value: genai.Ptr("production")},
"SLACK_BOT_TOKEN": {Credential: genai.Ptr("slack-bot-token")},
})),
})),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.Interaction.GetOutputText())
}
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>__, а прокси заменяет его на реальный секрет только для исходящих запросов, отправляемых в домен из trusted_domains учетных данных. Запрос к любому другому домену отклоняется, поэтому секрет никогда не покидает периметр, а вместо него не отправляется плейсхолдер.
Установите значение trusted_domains для каждого объекта учетных данных environment_variable. Это элемент управления, который определяет, где можно использовать секрет.
Как создать учетные данные
Каждый запрос на создание должен содержать 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",
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Create(ctx, operations.CreateCredentialRequest{
Body: credentials.NewCredentialCreateParams(credentials.HTTPBearerConfig{
ID: "github-production",
Token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created credential: %s\n", res.Credential.ID)
}
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"
}
По умолчанию прокси-сервер отправляет Authorization: Bearer <token>. Переопределите header_name и prefix, чтобы указать сервис, который ожидает другие значения:
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: "",
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Create(ctx, operations.CreateCredentialRequest{
Body: credentials.NewCredentialCreateParams(credentials.HTTPBearerConfig{
ID: "my-api-key",
Token: "key_xxxxxxxxxxxx",
HeaderName: genai.Ptr("x-goog-api-key"),
Prefix: genai.Ptr(""),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created credential: %s\n", res.Credential.ID)
}
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_name и prefix.
| Конфигурация | Вставленный заголовок |
|---|---|
{"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_id, client_secret, refresh_token и token_url. Поле scopes необязательное:
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"],
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Create(ctx, operations.CreateCredentialRequest{
Body: credentials.NewCredentialCreateParams(credentials.OAuth2Config{
ID: "jira-oauth",
ClientID: "my-client-id",
ClientSecret: "my-client-secret",
TokenURL: "https://auth.atlassian.com/oauth/token",
RefreshToken: "rt_xxxxxxxxxxxxxxxxxxxx",
Scopes: []string{"read:jira-work", "write:jira-work"},
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created OAuth2 credential: %s\n", res.Credential.ID)
}
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"
}
}
После сохранения прокси-сервер обновляет токены доступа по истечении срока их действия. Если поставщик меняет токены обновления и возвращает новый во время обновления, новый токен автоматически заменяет сохраненный.
Переменная среды
Для сертификата environment_variable требуются value и injection_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",
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Create(ctx, operations.CreateCredentialRequest{
Body: credentials.NewCredentialCreateParams(credentials.EnvironmentVariableConfig{
ID: "slack-bot-token",
Value: "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx",
TrustedDomains: []string{"*.slack.com", "slack.com"},
InjectionLocation: credentials.NewEnvironmentVariableConfigInjectionLocation(credentials.InjectionLocationEnumHeader),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created environment variable credential: %s\n", res.Credential.ID)
}
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 указывает прокси-серверу, в каком месте исходящего запроса нужно подставить секрет. Он принимает значения header, query или body в виде одной строки или массива, если сервису требуется несколько значений:
"injection_location": ["header", "query"]
Замена происходит только в указанных вами местоположениях. Запрос, в котором плейсхолдер находится в другом месте, отклоняется, а не пересылается.
Чтобы привязать учетные данные к названию переменной, ознакомьтесь с разделом Как использовать учетные данные в качестве переменных среды.
Сгенерированные идентификаторы
Поле 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"
}
Укажите собственный идентификатор, если вам нужна стабильная и понятная ссылка для использования в разных взаимодействиях. Поскольку идентификатор появляется в пути к ресурсу, рекомендуется использовать строчные буквы, цифры, дефисы и символы подчеркивания.
Как посмотреть учетные данные
Перечислите учетные данные, относящиеся к вашему проекту. Используйте параметры разбивки на страницы, чтобы контролировать размер пакета ответов.
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}`);
}
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.List(ctx, operations.ListCredentialsRequest{
PageSize: genai.Ptr(10),
})
if err != nil {
log.Fatal(err)
}
for _, cred := range res.CredentialListResponse.Credentials {
fmt.Printf("Credential ID: %s, Type: %v\n", cred.ID, cred.GetType())
}
}
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 |
string | Токен из свойства next_page_token предыдущего ответа. |
Как получить учетные данные
Получение метаданных для определенных учетных данных по их идентификатору.
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}`);
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Get(ctx, operations.GetCredentialRequest{
ID: "github-production",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Credential ID: %s, Status: %v\n", res.Credential.ID, res.Credential.GetStatus())
}
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"
}
}
Как выполнить ротацию учетных данных
Заменить секрет, не затрагивая ни одно правило белого списка, определение инструмента или переменную среды, которые на него ссылаются. Поворот вступит в силу при следующем разрешении прокси.
Запрос должен содержать элемент 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",
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Update(ctx, operations.UpdateCredentialRequest{
ID: "github-production",
Body: credentials.NewCredentialUpdate(credentials.HTTPBearerUpdateConfig{
Token: genai.Ptr("ghp_new_xxxxxxxxxxxxxxxxxxxx"),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated credential %s at %v\n", res.Credential.ID, res.Credential.GetUpdateTime())
}
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",
});
Проложить маршрут
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/credentials"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Credentials.Update(ctx, operations.UpdateCredentialRequest{
ID: "jira-oauth",
Body: credentials.NewCredentialUpdate(credentials.OAuth2UpdateConfig{
RefreshToken: genai.Ptr("rt_new_xxxxxxxxxxxxxxxxxxxx"),
}),
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated credential %s at %v\n", res.Credential.ID, res.Credential.GetUpdateTime())
}
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");
Проложить маршрут
package main
import (
"context"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
_, err = client.Credentials.Delete(ctx, operations.DeleteCredentialRequest{
ID: "github-production",
})
if err != nil {
log.Fatal(err)
}
}
REST
curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/credentials/github-production" \
-H "x-goog-api-key: $GEMINI_API_KEY"
При успешном удалении возвращается пустой объект:
{}
Любое правило белого списка, инструмент или переменная среды, в которых по-прежнему используется идентификатор, не будут работать, поэтому сначала обновите их.
Справочник по полям
Поля, общие для всех учетных данных:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id |
string | Нет | Уникальный идентификатор. Если не указан, генерируется как UUID. |
type |
string | Да | bearer_token, oauth2, environment_variable. |
status |
string | Только чтение | Текущий статус учетных данных. |
create_time |
string | Только чтение | Временная метка создания в формате RFC 3339. |
update_time |
string | Только чтение | Временная метка последнего обновления в формате RFC 3339. |
Поля для bearer_token:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
token |
string | Да | Только для записи. Значение токена. |
header_name |
string | Нет | Заголовок, который нужно внедрить. Значение по умолчанию – Authorization. |
prefix |
string | Нет | Префикс значения. Значение по умолчанию – Bearer. Если вы не хотите использовать фильтр, укажите значение "". |
Поля для oauth2:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
client_id |
string | Да | Идентификатор клиента OAuth2. |
client_secret |
string | Да | Только для записи. Секретный код клиента OAuth2. |
refresh_token |
string | Да | Только для записи. Токен обновления, используемый для получения токенов доступа. |
token_url |
string | Да | Конечная точка токена поставщика. |
scopes |
Массив | Нет | Области действия OAuth, которые нужно запросить. |
Поля для environment_variable:
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
value |
string | Да | Только для записи. Значение секрета. |
injection_location |
Строка или массив | Да | Где заменить секрет. Один или несколько из следующих вариантов: header, query, body. |
trusted_domains |
Массив | Нет | Шаблоны доменов, для которых разрешена подстановка. |
Ошибки
В случае ошибки возвращается объект JSON со свойствами message и code:
{
"error": {
"message": "Credential 'github-production' already exists.; CreateCredential call failed",
"code": "aborted"
}
}
| Статус HTTP | code |
Причина |
|---|---|---|
| 400 | invalid_request |
Отсутствует обязательное поле, неизвестное поле, неподдерживаемый символ type или не пройдена проверка OAuth2. |
| 404 | not_found |
Учетных данных с таким идентификатором нет. |
| 409 | aborted |
Учетные данные с таким идентификатором уже существуют. |
Неизвестные поля не игнорируются, а отклоняются. В сообщении об ошибке указывается название поля:
{
"error": {
"message": "Unknown parameter 'headerName'. Did you mean 'header_name'?",
"code": "invalid_request"
}
}
Дальнейшие действия
- Среды. Узнайте, как агенты выполняют код и сохраняют файлы.
- Обзор агентов. Узнайте об основных понятиях, связанных с управляемыми агентами.
- Создание специальных агентов. Определите собственных агентов, используя
AGENTS.mdиSKILL.md.