Зробіть reveal credential
Покажіть збережений секрет названому оператору — і зустріньте кожен запобіжник на шляху reveal.
Найчутливіше читання в сервісі, прогнане запобіжник за запобіжником: Reveal повертає plaintext рівно один раз на свідомий, названий, зафіксований в audit запит.
Мета
Зробити reveal plaintext одного credential з reveal-scoped токеном і спостерігати кожну відмову: хибний scope, анонімний виклик, видалений запис.
Передумови
- Сервісний токен зі scope
provider-credentials.reveal:export REVEAL_TOKEN=...; admin-scoped токен для контрасту (Service Plane Tokens). idзбереженого credential (сценарій 07).
Кроки
1. Admin-scope недостатньо
Викличте POST /internal/v1/admin/credentials/{id}/reveal з admin-токеном і міткою актора. Очікуване 403 FORBIDDEN — право редагувати не означає бачити секрети; ці scope видаються окремо.
2. Анонімність відхиляється
Той самий виклик із reveal-токеном, але без X-Admin-Actor. Очікуване 400 INVALID_REQUEST — reveal без названого оператора лишив би беззмістовний audit-слід, тож він відкинутий самою конструкцією.
3. Сам reveal
curl -s -X POST "$CREDS_BASE/internal/v1/admin/credentials/$CRED_ID/reveal" \
-H "Authorization: Bearer $REVEAL_TOKEN" \
-H "X-Admin-Actor: panel:olha"
Очікуване 200: plaintext credentials, відкрита configuration, координати власника, revealed_at. Це працює навіть на disabled-записі — підозріло зламаний ключ інспектують саме тоді, коли він вимкнений (Defaults and Lifecycle).
revealed = r.json()
assert revealed["credentials"]["api_key"].startswith("sk-") # the actual secret
4. Слід переживає відповідь
Запитайте audit-стрічку за event_type=credential.revealed. Очікувано: подія з actor_id = "service:<client_id>!panel:olha", метадані якої називають розкриті імена полів (ніколи значення) — закомічена до відправлення відповіді й виключена з purge ретенції.
5. Видалено означає зникло
М'яко видаліть credential і зробіть reveal знову. Очікуване 404 CREDENTIAL_NOT_FOUND — вікно відновлення тримає шифротекст для операторів purge-джоба, а не для reveal-ів.
Перевірено тестом test_s08_reveal_a_credential.