Home/Cookbook/Reveal a credential ENУКРРУС API Reference (ReDoc) ↗

Reveal a credential

Show a stored secret to a named operator — and meet every guard the reveal path puts in the way.

The most sensitive read in the service, exercised guard by guard: Reveal returns plaintext exactly once per deliberate, named, audited request.

Goal

Reveal one credential's plaintext with a reveal-scoped token, and observe each refusal: wrong scope, anonymous call, deleted record.

Prerequisites

  • A service token with the provider-credentials.reveal scope: export REVEAL_TOKEN=...; an admin-scoped token for contrast (Service Plane Tokens).
  • A stored credential's id (scenario 07).

Steps

1. The admin scope is not enough

Call POST /internal/v1/admin/credentials/{id}/reveal with the admin token and an actor label. Expected 403 FORBIDDEN — edit rights do not imply seeing secrets; the scopes are granted separately.

2. Anonymity is refused

Same call with the reveal token but no X-Admin-Actor. Expected 400 INVALID_REQUEST — a reveal without a named operator would leave a meaningless audit trace, so it is rejected by construction.

3. The reveal itself

curl -s -X POST "$CREDS_BASE/internal/v1/admin/credentials/$CRED_ID/reveal" \
  -H "Authorization: Bearer $REVEAL_TOKEN" \
  -H "X-Admin-Actor: panel:olha"

Expected 200: plaintext credentials, open configuration, owner coordinates, revealed_at. This works even on a disabled record — a suspected-broken key is inspected exactly when it is off (Defaults and Lifecycle).

revealed = r.json()
assert revealed["credentials"]["api_key"].startswith("sk-")   # the actual secret

4. The trace outlives the response

Query the audit trail for event_type=credential.revealed. Expected: an event with actor_id = "service:<client_id>!panel:olha", metadata naming the revealed field names (never values) — committed before the response was sent, and exempt from retention purge.

5. Deleted means gone

Soft-delete the credential, reveal again. Expected 404 CREDENTIAL_NOT_FOUND — the recovery window keeps ciphertext for operators of the purge job, not for reveals.

Verified by the test test_s08_reveal_a_credential.