Symptom
The key field on sys_api_key — the stored SHA-256 hash of the API key — serializes over the data API on both get-by-id and list, despite being declared with a description that says it is never exposed.
- Observed: get-by-id and list responses for
sys_api_key include the key (hash) value. Admin-readable only on this app (ordinary personas are 403 on the object), but it does serialize where readable.
- Field declaration (
packages/platform-objects/src/identity/sys-api-key.object.ts, ~line 174):
key: Field.text({ label: 'Hashed Key', required: true, hidden: true, readonly: true,
description: 'Hashed API key value — never exposed to clients', group: 'Secret' })
Not a hidden-contract violation
The spec defines hidden as "Hidden from default UI", not "stripped from API serialization" — so serializing a hidden field is not a violation of the hidden contract. What is wrong is narrower: the field's own description ("never exposed to clients") is false on this build. The show-once secret handling is otherwise clean (the raw plaintext secret never re-serializes on get-by-id, list, or a reloaded DOM); this concerns only the stored hash column.
Root cause
Not located precisely by the run. The fix lands in one of two places — a maintainer call:
- Strip on serialization: genuinely omit
key from data-API output (a hidden-and-secret field should not serialize its value), making the description true; or
- Correct the description: if the hash is intentionally admin-readable, drop the "never exposed to clients" claim from the field description so the declaration stops lying.
Route domain:metadata (the field declaration and any serialization-strip both sit in platform-objects / metadata). Lower severity — labelled finding.
Reproduction
- As admin, create an API key (
POST /api/v1/keys {name}).
GET /api/v1/data/sys_api_key/{id} (and the list endpoint).
- Observe the
key (SHA-256 hash) present in the serialized payload, despite the field description "never exposed to clients".
Source
Extracted from the QA run #7663 (framework 92f26f7, console 09987b680).
Symptom
The
keyfield onsys_api_key— the stored SHA-256 hash of the API key — serializes over the data API on both get-by-id and list, despite being declared with a description that says it is never exposed.sys_api_keyinclude thekey(hash) value. Admin-readable only on this app (ordinary personas are 403 on the object), but it does serialize where readable.packages/platform-objects/src/identity/sys-api-key.object.ts, ~line 174):Not a
hidden-contract violationThe spec defines
hiddenas "Hidden from default UI", not "stripped from API serialization" — so serializing ahiddenfield is not a violation of thehiddencontract. What is wrong is narrower: the field's owndescription("never exposed to clients") is false on this build. The show-once secret handling is otherwise clean (the raw plaintext secret never re-serializes on get-by-id, list, or a reloaded DOM); this concerns only the stored hash column.Root cause
Not located precisely by the run. The fix lands in one of two places — a maintainer call:
keyfrom data-API output (ahidden-and-secret field should not serialize its value), making the description true; orRoute
domain:metadata(the field declaration and any serialization-strip both sit inplatform-objects/ metadata). Lower severity — labelledfinding.Reproduction
POST /api/v1/keys {name}).GET /api/v1/data/sys_api_key/{id}(and the list endpoint).key(SHA-256 hash) present in the serialized payload, despite the field description "never exposed to clients".Source
Extracted from the QA run #7663 (framework 92f26f7, console 09987b680).