feat(dashboard): ApiKeysPage lists and accepts dashboard_tags constraints

The constraints column enumerated only the eight positional ApiKeyConstraints
members, so a key whose sole recorded policy was a dashboard tag summarised to
an empty string and rendered as "-" — the same cell a key with no policy at
all gets. ApiKeyConstraints.IsEmpty counts DashboardTags, so that key is not
unconstrained, and the column was quietly telling operators otherwise about a
grant that decides who can watch a session's events.

The create form had no dashboard-tags input either, so tagged keys could only
be minted from the apikey create-key CLI. Adds the field beside the other
constraint lists (same ParseList separators) and attaches it through the
record's init-only member, since it postdates the eight-member constructor.

CreateModel, OpenCreateDialog and TryBuildCreateRequest widen to internal for
the new render tests: the create form is behind a click and static rendering
cannot dispatch one. That is the assembly's existing InternalsVisibleTo seam.
This commit is contained in:
Joseph Doherty
2026-08-17 07:17:43 -04:00
parent fccf75324b
commit c037d9960d
3 changed files with 343 additions and 7 deletions
+8 -2
View File
@@ -195,8 +195,14 @@ another tenant's tag. A key with no tags opens untagged sessions.
Tags are set at key creation with
`apikey create-key --dashboard-tags team-a,team-b` (repeatable; segments are
trimmed and de-duplicated ordinal-ignore-case). Keys created from the dashboard
API Keys page are currently always untagged.
trimmed and de-duplicated ordinal-ignore-case). The dashboard API Keys page sets
them too: its create form has a **Dashboard tags** field alongside the data-access
constraints, split on the same separators the other constraint fields use.
That page's constraints column names `dashboard_tags` like any other member. It
has to: `IsEmpty` counts the tags, so a key whose only recorded policy is a
dashboard tag is not unconstrained, and leaving it out of the summary rendered
that key with the same empty cell as a key with no policy at all.
The dashboard ACL that consumes the tag shipped on 2026-08-17 (SEC-25 / TST-15).
`IDashboardSessionAcl.CanViewSession` is consulted at both dashboard subscribe