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

# Секреты и токены

> Как Велес хранит, загружает и использует секреты: зашифрованное локальное хранилище, ссылки на секреты и OAuth.

# Секреты и токены

Велес хранит секреты отдельно от обычного `config.json`. Конфигурация может содержать только ссылку на секрет (`SecretRef`) или пустое значение, а реальные токены загружаются во время работы и не отправляются в интерфейс Велеса или модель.

## Главный ключ

Для локального зашифрованного хранилища нужен ключ:

```powershell theme={null}
uv run veles secrets generate-key
$env:VELES_SECRETS_MASTER_KEY="PASTE_GENERATED_KEY"
uv run veles gateway
```

`VELES_SECRETS_MASTER_KEY` должен быть в окружении процесса сервера Велеса. Интерфейс Велеса не должен получать этот ключ.

## Где лежат локальные секреты

Зашифрованное локальное хранилище пишет файлы в каталог `secrets` внутри рабочей области, указанной в `agents.defaults.workspace` активного `config.json`:

* `<workspace>/secrets/values.enc.json` — обычные ключи API и секреты окружения навыков;
* `<workspace>/secrets/auth-profiles.enc.json` — OAuth-профили, например OpenAI Codex.

Файлы содержат зашифрованную оболочку AES-GCM (`version`, `alg`, `nonce`, `ciphertext`, `timestamps`). Значения секретов не лежат там открытым текстом.

## SecretRef

`SecretRef` говорит Велесу, откуда брать секрет:

* `local` — зашифрованное локальное хранилище Велеса;
* `env` — переменная окружения процесса сервера;
* `file` — файл на машине сервера;
* `exec` — команда, которая возвращает секрет.

Для `local` используется объект, а не строковая подстановка:

```json theme={null}
{
  "source": "local",
  "provider": "veles",
  "id": "channels.email.imapPassword"
}
```

Короткая строка вида `"${NAME}"` означает только ссылку на переменную окружения и не подходит для локальных секретов Велеса.

Интерфейс Велеса в первую очередь управляет `local`: пользователь вводит значение один раз, Велес шифрует его и дальше возвращает только замаскированный статус.

Пароль входа в Nerve тоже хранится на стороне Велеса, но не показывается как обычная цель в каталоге секретов. Велес записывает только scrypt-хэш пароля во внутренний ключ зашифрованного хранилища. Nerve при входе отправляет пароль в `auth.login`, получает `gateway.token` только в серверный процесс и не сохраняет его в браузере.

Если это зашифрованное хранилище нельзя прочитать, Велес не считает пароль отсутствующим и не включает вход через `gateway.token`. Сначала восстановите ключ шифрования или доступ к хранилищу секретов.

## Как интерфейс показывает секреты

В интерфейсе Велеса откройте «Рабочая область» → «Секреты». Интерфейс получает список целей так:

1. `GET /api/secrets`;
2. внутренний вызов `secrets.catalog`;
3. Велес строит каталог из провайдеров, инструментов, каналов, MCP-серверов и метаданных навыков.

Если строка показывает `MISSING` или `EMPTY`, это не значит, что секрет находится в интерфейсе. Это только замаскированная цель: Велес знает, что такой секрет может понадобиться, но значение ещё не настроено.

Поле поиска в панели **Секреты** фильтрует уже загруженный список на стороне Nerve. Оно не делает дополнительных запросов к gateway и ищет по названию секрета, target id, пути конфигурации и источнику.

## Секреты навыков

Навык может объявить нужный секрет окружения в `SKILL.md`:

```yaml theme={null}
metadata: {"veles":{"requires":{"env":["GH_TOKEN"]}}}
```

Тогда Велес создаст цель вроде `skills.github.env.GH_TOKEN`. Если значение сохранить в панели секретов, Велес будет подставлять `GH_TOKEN` только на время выполнения ответа. Значение не попадает в инструкцию модели и не записывается в `config.json`.

`requires.env` делает переменную обязательной: без неё навык считается недоступным. Для опциональных API-ключей используйте отдельный список секретов:

```yaml theme={null}
metadata: {"veles":{"secrets":{"env":["NCBI_API_KEY"]}}}
```

Такой ключ появится в панели секретов и будет подставлен при наличии, но отсутствие значения не выключит навык.

Например, встроенный навык `fda-database` объявляет опциональный `OPENFDA_API_KEY` как `skills.fda-database.env.OPENFDA_API_KEY`: ключ повышает дневной лимит openFDA, но без него навык всё равно работает.

Навык `google-workspace` хранит более крупные значения: файл клиента Google, токен и временное состояние авторизации. Они тоже записываются в зашифрованное локальное хранилище, но как JSON-значения с ключами `skills.google-workspace.google_client_secret_json`, `skills.google-workspace.google_token_json` и `skills.google-workspace.google_oauth_pending_json`.

## OpenAI Codex OAuth

OpenAI Codex использует OAuth, а не ключ API. Его токены хранятся в зашифрованном хранилище профилей:

```text theme={null}
<workspace>/secrets/auth-profiles.enc.json
```

Подключить или отключить Codex можно через интерфейс Велеса: «Рабочая область» → «Секреты». Браузер получает только ссылку и статус OAuth; токены доступа и обновления остаются внутри Велеса.

## Что важно помнить

* `config.json` не должен хранить новые секреты открытым текстом.
* Интерфейс Велеса никогда не показывает сохранённое значение секрета.
* Без `VELES_SECRETS_MASTER_KEY` чтение ссылок `env`, `file` и `exec` может работать, но локальная запись зашифрованных секретов и OAuth-хранилище будут недоступны.
* Для постоянного развёртывания нужно сохранять каталог `.veles` и передавать главный ключ через менеджер секретов окружения.
