Схемы провайдеров
credential_schema и configuration_schema — стройте формы по ним, а валидатором пусть будет 422.
Карточка каждого провайдера несёт две JSON Schema (Draft 2020-12). Это контракт между каталогом и каждым credential, который вы храните:
credential_schema— секретные поля.{"api_key": ...}у большинства провайдеров; пары ключей у AWS-стиля (access_key_id+secret_access_key); целый вложенный объект сервисного аккаунта у Google. Всё под ней шифруется при хранении и возвращается только маскированным.configuration_schema— несекретные настройки, хранящиеся рядом с секретом: регион, базовый URL, id модели. Хранятся и возвращаются в открытую.
Стройте формы, не хардкодьте
Схемы достаточно самоописательны, чтобы отрендерить форму: required перечисляет обязательные поля, properties.*.title даёт подписи, enum даёт выпадающие списки (например, выбор модели у LLM-провайдеров), const фиксирует дискриминаторы. UI, который рендерится из схемы, переживает каждое обновление каталога без релиза — ровно так работает операторская панель.
import httpx
provider = httpx.get(
f"{CREDS_BASE}/v1/providers/deepl_api",
headers={"Authorization": f"Bearer {TOKEN}"},
).json()
schema = provider["credential_schema"]
print(schema["required"]) # ['api_key']
print(list(schema["properties"])) # ['api_key']
Валидация происходит на записи
POST /v1/credentials и каждая ротация валидируют ваш объект credentials по credential_schema, а вашу configuration — по configuration_schema. Несовпадения отвечают 422 с выделенным кодом на каждый объект:
CREDENTIAL_SCHEMA_VALIDATION_FAILED— неверен секретный объект;CONFIGURATION_SCHEMA_VALIDATION_FAILED— неверна конфигурация.
error.details.errors несёт указатели на поля и сообщения — но никогда не отправленные вами значения, так что ответ безопасно логировать. Неизвестные поля тоже падают: большинство схем ставят additionalProperties: false, и чего схема не разрешает, того хранилище не сохранит. Разобранный пример: сценарий cookbook 10.
Секретные поля против конфигурационных — это граница безопасности
Регион вендора или id модели живёт в configuration — виден в каждом чтении. Всё, что даёт доступ, живёт в credentials — зашифровано, маскировано и раскрываемо только через операторский reveal. Когда документация вендора неоднозначна насчёт поля, каталог кладёт его на безопасную сторону.