Secrets API
Управление секретами интеграций. Секреты хранятся в D1 базе данных integ-db в таблице creds в зашифрованном виде.
Архитектура
Секреты - это высокоуровневый API для управления чувствительной информацией интеграций с фильтрацией по интеграции.
Admin UI
|
v
/api/core/secrets (GET, POST, PATCH, DELETE)
|
v
SecretsService (высокоуровневая логика)
|
v
CryptoService (AES-256-GCM + PBKDF2)
|
v
D1 Database (integ-db.creds table)Шифрование
Секреты шифруются с использованием единого алгоритма, совместимого с integ-core:
| Параметр | Значение |
|---|---|
| Алгоритм | AES-256-GCM |
| Key derivation | PBKDF2 (100,000 итераций, SHA-256) |
| IV длина | 12 байт |
| Формат | {iv_base64}.{data_base64} |
Переменные окружения (Doppler):
CRYPTO_KEY— мастер-ключ шифрованияCRYPTO_SALT— соль для PBKDF2
ВАЖНО
Данные, зашифрованные в integ-core (Cloudflare Workers), могут быть расшифрованы в integ-api (NestJS) и наоборот, при условии использования одинаковых CRYPTO_KEY и CRYPTO_SALT.
Таблица структура
CREATE TABLE creds (
id INTEGER PRIMARY KEY AUTOINCREMENT,
integration_name TEXT NOT NULL, -- 'sofa', 'rozetka', 'promua'
key TEXT NOT NULL, -- 'NETHUNT_API_KEY', 'KEYCRM_API_KEY'
encrypted_value TEXT NOT NULL, -- зашифровано CryptoService
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
UNIQUE(integration_name, key)
);
CREATE INDEX idx_creds_integration ON creds(integration_name);Эндпоинты
GET /api/core/secrets
Получить все секреты.
Query Parameters:
integration(optional) - фильтр по названию интеграции
Request:
GET /api/core/secrets
Authorization: Bearer <token>или с фильтром:
GET /api/core/secrets?integration=sofa
Authorization: Bearer <token>Response (200 OK):
[
{
"id": 1,
"integration": "sofa",
"key": "NETHUNT_API_KEY",
"encryptedValue": "****...****",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
]GET /api/core/secrets/:id
Получить секрет по ID.
Request:
GET /api/core/secrets/1
Authorization: Bearer <token>Response (200 OK):
{
"id": 1,
"integration": "sofa",
"key": "NETHUNT_API_KEY",
"encryptedValue": "****...****",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}GET /api/core/secrets/:id/value
Получить расшифрованное значение секрета.
Request:
GET /api/core/secrets/1/value
Authorization: Bearer <token>Response (200 OK):
{
"value": "actual-api-key-value"
}БЕЗОПАСНОСТЬ
Значение расшифровывается на сервере. Клиент получает реальное значение только при явном запросе через этот endpoint с /value.
POST /api/core/secrets
Создать новый секрет.
Request:
POST /api/core/secrets
Authorization: Bearer <token>
Content-Type: application/json
{
"integration": "sofa",
"key": "NETHUNT_API_KEY",
"value": "your-api-key-value"
}Response (201 Created):
{
"id": 1,
"integration": "sofa",
"key": "NETHUNT_API_KEY",
"encryptedValue": "****...****",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}PATCH /api/core/secrets/:id
Обновить значение секрета.
Request:
PATCH /api/core/secrets/1
Authorization: Bearer <token>
Content-Type: application/json
{
"value": "new-api-key-value"
}Response (200 OK):
{
"id": 1,
"integration": "sofa",
"key": "NETHUNT_API_KEY",
"encryptedValue": "****...****",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-02T10:30:00.000Z"
}DELETE /api/core/secrets/:id
Удалить секрет.
Request:
DELETE /api/core/secrets/1
Authorization: Bearer <token>Response (200 OK):
{
"success": true
}POST /api/core/secrets/decrypt
Расшифровать произвольное зашифрованное значение. Используется для отладки и интеграции с integ-admin.
Request:
POST /api/core/secrets/decrypt
Authorization: Bearer <token>
Content-Type: application/json
{
"encryptedValue": "base64iv.base64data"
}Response (200 OK):
{
"value": "decrypted-secret-value"
}Использование
Этот endpoint полезен для расшифровки данных, зашифрованных в integ-core (Cloudflare Workers), без необходимости знать исходный ключ интеграции.
Пример использования
import axios from "axios";
const api = axios.create({
baseURL: "http://localhost:3000/api",
headers: {
Authorization: `Bearer ${token}`
}
});
async function manageSecrets() {
// 1. Получить все секреты
const { data: allSecrets } = await api.get("/core/secrets");
console.log("All secrets:", allSecrets);
// 2. Получить секреты конкретной интеграции
const { data: sofaSecrets } = await api.get("/core/secrets?integration=sofa");
console.log("Sofa secrets:", sofaSecrets);
// 3. Создать новый секрет
const { data: newSecret } = await api.post("/core/secrets", {
integration: "sofa",
key: "NETHUNT_API_KEY",
value: "your-secret-value"
});
console.log("Created:", newSecret);
// 4. Получить информацию о секрете по ID (замаскированное значение)
const { data: secretInfo } = await api.get(`/core/secrets/${newSecret.id}`);
console.log("Secret info:", secretInfo);
// 5. Получить расшифрованное значение
const { data: secretValue } = await api.get(`/core/secrets/${newSecret.id}/value`);
console.log("Decrypted value:", secretValue.value);
// 6. Обновить значение
const { data: updated } = await api.patch(`/core/secrets/${newSecret.id}`, {
value: "new-secret-value"
});
console.log("Updated:", updated);
// 7. Удалить секрет
await api.delete(`/core/secrets/${newSecret.id}`);
console.log("Deleted");
// 8. Расшифровать произвольное значение (для integ-admin)
const { data: decrypted } = await api.post("/core/secrets/decrypt", {
encryptedValue: "base64iv.base64encrypteddata"
});
console.log("Decrypted:", decrypted.value);
}Дополнительно
- Cache API - Управление KV store
- D1 Proxy API - Прямой доступ к D1 таблицам
- Интеграции - Управление интеграциями