Schema, validator, fixtures, declarations and tests (40 pass) now use the imported principal_type and authority grants MODE @ SCOPE with activation and environments, estate conventions bind and service-admin, unknown placeholders, and an elimination path on every exception. SI-4 and SI-7 became decidable. Before/after over the same declarations: 1/11/2/5/6 to 1/10/2/5/7 (non-conformant/unknown/excepted/planned/ conformant); the only move is KeyCape's secrets-engine-openbao client, whose scope is established. lldap/admin is now also excepted under SI-4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 328925@bnt-lap001 Assistant-Session: 14b795fd-c632-4c01-8d28-e7e490c7b0ed |
||
|---|---|---|
| .. | ||
| declarations | ||
| fixtures | ||
| tests | ||
| README.md | ||
| validate.py | ||
Service Identity Declaration Validator
NK-WP-0054-T03. Offline and read-only. Checks declarations against
canon/schemas/service-identity_v0.1.schema.json and evaluates the rules of the
proposed Service Identity and Privilege standard
that a declaration alone can decide. It was built against draft-1, before the founder's review,
so a rule change in the standard changes this tool. It follows draft-3.
make service-identity-test # unit tests
make service-identity-check # evaluate the checked-in declarations
uv run tools/service-identity/validate.py tools/service-identity/declarations/*.yaml --as-of 2026-10-24
Options: --as-of YYYY-MM-DD (evaluation date, so a run is reproducible and exceptions expire on a
stated day), --json, --fail-on-findings (exit 2 when anything is non-conformant or unknown).
Exit 1 means invalid input.
Results
| Result | Meaning |
|---|---|
conformant |
Every checked rule holds on declared facts |
non-conformant |
At least one rule is broken and not covered by a live exception, or an exception has expired |
excepted |
Every broken rule has a live, time-boxed exception |
unknown |
A fact nobody has established (unknown in the declaration). A finding, not a pass |
planned |
A target identity that does not exist yet; never counted as conformant |
Alongside the results, advisories report declarations not asserted complete by their owner, declarations not confirmed by the owning service, stale exceptions, more than one service-admin and more than one break-glass identity.
Model and rules decided here
Draft-3 of the standard is an estate profile of SecurityCanon. Each account declares an imported
principal_type (HUMAN, SERVICE, WORKLOAD, AGENT, CONTROLLER, DEVICE), its authority as grants
MODE @ SCOPE with activation and environments, and optional estate conventions (bind,
service-admin). Break-glass is activation: BREAK_GLASS, not a kind of account. unknown is allowed where a
fact is not established and is reported as a finding. Exceptions carry an elimination_path (DSM-EXC-004).
Decided from a declaration: SI-1, SI-2, SI-3 (including a credential shared by more than one service), SI-4
(a service-admin holds ADMINISTER over one service only), SI-6 (SOVEREIGN is offline and break-glass in
production), SI-7 (CONSTRUCT never in production), SI-8 (second factor; admin roles bind the assurance
claim), SI-9, SI-11 (overdue legacy disposition), SI-12, SI-14 (an agent presents as an agent, tokens at most
3600 seconds) and naming. More than one service-admin account per service is an advisory. SI-5, SI-10, SI-13 and
SI-15 are process rules. Observed state is the health check, NK-WP-0054-T04.
Declarations
declarations/ holds the first set, authored from docs/service-identity-inventory.md. Decided 2026-10-24:
declarations start here and move to each service's repository as its owner confirms them. Every one says owner_confirmed: false: they describe what
the repository establishes, not what the owning service has attested. Facts the repository cannot
establish are unknown, never guessed.
Safety
A declaration holds no credential. Secret-shaped values are rejected, and schema messages are never printed because they can echo the rejected value; invalid input reports only a count.