Administer platform credentials
As a named operator on the service plane, store the platform fallback and list credentials across levels.
The operator's seat: the Internal Admin API with an admin-scoped token and an X-Admin-Actor label, creating the platform-level key everyone falls back to.
Goal
Create a platform default credential attributed to a named operator, then see credentials of different ownership levels in one list.
Prerequisites
- A service token with the
provider-credentials.adminscope:export ADMIN_TOKEN=...(Service Plane Tokens).
Steps
1. Read the catalog with schemas
Call GET /internal/v1/admin/providers. Expected 200: every provider with credential_schema inline — the create form renders straight from this (Provider Schemas).
2. Create the platform credential — with an explicit owner
Call POST /internal/v1/admin/credentials. The admin plane names the owner in the body; platform takes no owner_id:
curl -s -X POST "$CREDS_BASE/internal/v1/admin/credentials" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "X-Admin-Actor: panel:olha" \
-H "Content-Type: application/json" \
-d '{
"provider_code": "'$CODE'",
"owner_type": "platform",
"name": "Shared fallback",
"credentials": {"api_key": "sk-platform-0123456789"},
"make_default": true
}'
Expected 201: owner_type: "platform", owner_id: null, is_default: true, masked secret. Mismatched owner coordinates — platform with an owner_id, or user/organization without one — would be a 400.
3. One list, every level
Call GET /internal/v1/admin/credentials without filters, then narrowed:
all_records = httpx.get(f"{CREDS_BASE}/internal/v1/admin/credentials",
headers=admin_headers).json()
platform_only = httpx.get(f"{CREDS_BASE}/internal/v1/admin/credentials",
params={"owner_type": "platform"}, headers=admin_headers).json()
Expected: the unfiltered list mixes user, organization, and platform records (masks only); owner_type=platform narrows to the fallback keys.
4. The attribution is real
The create in step 2 landed in the audit trail with actor_id = "service:<client_id>!panel:olha" — filter for it in scenario 09. An anonymous call (no X-Admin-Actor) would have worked here — unlike reveal — but the panel always sends the label: per-operator budgets and a readable trail are worth one header.
Verified by the test test_s07_administer_platform_credentials.