Ключові поняття
Каталог проти сховища credentials, дві площини, три рівні власності, один ланцюг resolve.
П'ять ідей пояснюють увесь сервіс. Решта — деталі.
1. Каталог і сховище — різні речі
Каталог — це версіонований YAML, який їде разом із сервісом: які вендори й провайдери існують, як має виглядати credential для кожного (credential_schema), які несекретні налаштування він приймає (configuration_schema), що провайдер уміє і які рівні власності допускає. Через API він read-only та однаковий для всіх — див. Vendors and Providers.
Сховище credentials — це PostgreSQL: зашифровані секрети плюс їхні метадані, які комусь належать. Каталог каже, що можна налаштувати; сховище тримає те, що налаштовано насправді.
2. Дві площини — дві системи авторизації
| Площина | Шляхи | Хто | Auth |
|---|---|---|---|
| Користувацька | /v1/* |
люди, продуктові бекенди від імені користувача | короткоживучий exchange-JWT (User Plane Tokens) |
| Сервісна | /internal/v1/* |
довірені мікросервіси | client-credentials JWT зі scope (Service Plane Tokens) |
Обидві площини живуть в одному деплойменті й на одному домені. Користувацький токен ніколи не працює на /internal/*, а сервісний — на /v1/*: різні issuer-и, audience та валідатори. Сервісна площина ділиться далі за scope: provider-credentials.invoke робить resolve, provider-credentials.admin адмініструє, provider-credentials.reveal читає plaintext — і жоден не включає інший.
3. Три рівні власності
Кожен збережений credential належить рівно одному власнику:
- user — персональний; власник —
subтокена того, хто викликає (Personal Credentials). - organization — спільний для тенанта; власник — клейм
org_id; керують ним менеджерські ролі організації (Organization Credentials). - platform — спільний fallback, яким володіє оператор (User Plane Admin).
Каталог вирішує для кожного провайдера, які рівні взагалі дозволені. На користувацькій площині власник завжди береться з токена — тіла запитів ніколи не називають власника; лише внутрішня адмін-площина адресує довільних власників явно.
4. Один ланцюг resolve
Коли runtime перекладу питає «яким ключем мені працювати для користувача X і провайдера P?», сервіс іде ланцюгом USER → ORGANIZATION → PLATFORM у межах політики провайдера й повертає перший знайдений активний default credential — разом із plaintext, лише сервісною площиною. Fallback-у на runtime-помилки виданого ключа немає: зламаний ключ показується, а не мовчки підміняється. Уся історія: Resolve Chain.
5. Секрети лишаються запечатаними
Секрети валідуються проти схеми провайдера, шифруються (AES-256-GCM, версіонований keyring) і відтоді існують для API рівно у трьох формах:
- маскований — кожен read-ендпоїнт повертає
masked_credentials(sk-1***abcd); досить, щоб упізнати ключ, і ніколи не досить, щоб ним скористатися; - resolved — plaintext для машин, лише через resolve зі scope
invoke; - revealed — plaintext для названого оператора-людини, лише через reveal з його окремим scope, з audit-записом до відправлення відповіді.
Видалення м'які, з вікном відновлення (за замовчуванням 5 днів) до фізичного purge; кожна мутація, resolve і reveal лягають в audit-стрічку.
Усе впирається в статуси
Сутності каталогу бувають active/deprecated/disabled/removed; збережені credentials — active/disabled (+ м'яко видалені). Deprecated-провайдери не приймають нових credentials; disabled відповідають 409 на resolve. Правила видимості за ролями — у Vendors and Providers.