67 lines
2.4 KiB
Markdown
67 lines
2.4 KiB
Markdown
|
|
---
|
||
|
|
id: KEY-WP-0028
|
||
|
|
type: workplan
|
||
|
|
title: "Reject service-identity fields that a browser client silently ignores"
|
||
|
|
domain: infotech
|
||
|
|
repo: key-cape
|
||
|
|
status: finished
|
||
|
|
owner: claude
|
||
|
|
topic_slug: browser-client-field-validation
|
||
|
|
created: "2026-09-09"
|
||
|
|
updated: "2026-09-09"
|
||
|
|
---
|
||
|
|
|
||
|
|
`serviceSubject` and `roles` are read only on the `client_credentials` path. On a
|
||
|
|
browser client they are accepted at startup and then ignored: the subject and
|
||
|
|
roles come from the directory user. A registration that looks effective and is
|
||
|
|
not fails later, somewhere else, as a downstream rejection rather than as a
|
||
|
|
registration defect.
|
||
|
|
|
||
|
|
`tokenLifetime` was already rejected this way for non-service clients, so the
|
||
|
|
rule exists — it was just incomplete.
|
||
|
|
|
||
|
|
## Reject the ignored fields
|
||
|
|
|
||
|
|
```task
|
||
|
|
id: KEY-WP-0028-T01
|
||
|
|
status: done
|
||
|
|
priority: medium
|
||
|
|
```
|
||
|
|
|
||
|
|
Config validation now rejects `serviceSubject` and `roles` on any client that
|
||
|
|
does not use `client_credentials`, naming where the value actually comes from.
|
||
|
|
Nothing in `config/dev-config.yaml`, the example fixture or the live deployment
|
||
|
|
sets either field on a browser client, so this breaks no existing configuration —
|
||
|
|
checked against all three rather than assumed.
|
||
|
|
|
||
|
|
**`tenant` is deliberately excluded from the rule**, and a test pins that. A
|
||
|
|
browser client may declare a tenant; `humanTenant` resolves it against the
|
||
|
|
directory and refuses issuance when the two disagree (KEY-WP-0013-T05). An
|
||
|
|
earlier version of this change rejected `tenant` too, which would have made that
|
||
|
|
feature unusable.
|
||
|
|
|
||
|
|
## Correction
|
||
|
|
|
||
|
|
```task
|
||
|
|
id: KEY-WP-0028-T02
|
||
|
|
status: done
|
||
|
|
priority: medium
|
||
|
|
```
|
||
|
|
|
||
|
|
This work started from KEY-WP-0013-T05's blocker paragraph, which described a
|
||
|
|
human token as unable to carry `tenant:platform`. That was true when written and
|
||
|
|
had already been fixed in a concurrent session by the time this task began; the
|
||
|
|
paragraph was read as current state rather than as a dated record.
|
||
|
|
|
||
|
|
Two consequences, both corrected within the session:
|
||
|
|
|
||
|
|
- the `tenant` rejection was removed before it was committed, and a test now
|
||
|
|
asserts a browser client carrying `tenant: tenant:platform` validates cleanly;
|
||
|
|
- a hub decision (`0145ab57`) recording the tenant question as open and
|
||
|
|
unimplemented was withdrawn with a rationale pointing at the implementation.
|
||
|
|
Nothing was built on it.
|
||
|
|
|
||
|
|
The lesson worth keeping: in a repository where several sessions work at once,
|
||
|
|
blocker prose ages faster than the code it describes. Re-read the source before
|
||
|
|
acting on a workplan's description of it.
|