Make snapshot attribute validation enforce a real rule
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 40s

Closes gap G06. checkNoUnknownAttributes was named for a rule it did not
implement: it rejected blank keys, which is not an allow-list, so a snapshot
carrying malformed or shadowing attribute names passed a check whose name said
otherwise. A rule that passes for the wrong reason is worse than an absent one,
because the report is read as evidence.

raw_attributes_well_formed requires each key to be a valid LDAP attribute
descriptor, forbids shadowing an attribute the canonical model owns (uid, cn,
mail) in any casing, and rejects keys differing only by case, which LDAP treats
as one attribute. spec/ldap-schema.yaml carries the same wording.

Two corrections to the gap's description rather than implementations of it. An
allow-list is not derivable: ldapAttributes is defined as what the canonical
model does not cover, so the schema cannot enumerate what may appear there. And
the reference constraint already existed -- checkValidGroupMemberships only
checks emptiness, but the semantic rule checkReferencedUsersExist resolves every
member against the user set.

Neutering the rule fails four of the five new tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
This commit is contained in:
tegwick 2026-09-07 23:22:55 +02:00
parent f366df814a
commit 21acb5cdd6
6 changed files with 298 additions and 26 deletions

View file

@ -263,6 +263,26 @@ identity existence. It does not derive its checks from the YAML schema.
the normative contract to the actual checks; add invalid-snapshot cases that
prove each stated rule. SCOPE now calls this limited snapshot validation.
**Status 2026-09-07 (KEY-WP-0021): closed.** The placeholder is replaced by
`raw_attributes_well_formed`, which requires each key to be a valid LDAP
attribute descriptor (RFC 4512 descr or numeric OID), forbids shadowing a
mapping the canonical model owns (uid, cn, mail) in any casing, and rejects two
keys differing only by case. `spec/ldap-schema.yaml` carries the same wording, so
the rule's name no longer overpromises. Invalid-snapshot cases cover every
constraint plus accepting legitimate raw attributes; neutering the rule fails
four of them.
Two corrections to this gap's own description. First, an allow-list of permitted
attribute names is not derivable: `ldapAttributes` is defined as the attributes
the canonical model does *not* cover, so the schema cannot enumerate what may
appear there — the constraints above are what is actually checkable. Second, the
reference constraint was already implemented: `checkValidGroupMemberships` does
only check emptiness, but the semantic rule `checkReferencedUsersExist` resolves
every member against the user set and fails on an unknown one. The rule existed
in a different function than the one this assessment examined.
Still not claimed: validation of attribute *values* against a directory schema.
### G07 — Optional tenant-role support is not wired into the server
**Priority: medium. Kind: integration gap.**