NK-WP-0054-T02: draft-1 of the Service Identity and Privilege standard
Thirteen rules (one identity one class, people and services never share a credential, read-only per-service bind identities, one service-admin per service, break-glass is not routine, assurance on privileged roles, custody class, declaration, recovery, validation run by the operator identity), naming svc-<service> and <short>-admin, five initial exceptions and six open questions. Proposed; extends IAM Profile v0.3 and Credential Management v0.2. Hub decision routes the review. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 328925@bnt-lap001 Assistant-Session: 14b795fd-c632-4c01-8d28-e7e490c7b0ed
This commit is contained in:
parent
597ffbf111
commit
768e7252e8
3 changed files with 241 additions and 2 deletions
|
|
@ -309,7 +309,7 @@
|
|||
| task | NK-WP-0053-T03 | wait | — | workplans/NK-WP-0053-identity-restore-drill-cadence.md |
|
||||
| task | NK-WP-0053-T04 | todo | — | workplans/NK-WP-0053-identity-restore-drill-cadence.md |
|
||||
| task | NK-WP-0054-T01 | done | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T02 | todo | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T02 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T03 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T04 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T05 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
|
|
|
|||
230
canon/standards/service-identity-privilege_v0.1.md
Normal file
230
canon/standards/service-identity-privilege_v0.1.md
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
---
|
||||
id: netkingdom-service-identity-privilege
|
||||
type: standard
|
||||
title: "NetKingdom Service Identity and Privilege v0.1"
|
||||
domain: netkingdom
|
||||
status: proposed
|
||||
version: "0.1"
|
||||
created: "2026-10-24"
|
||||
updated: "2026-10-24"
|
||||
scope: service-account-governance
|
||||
revision: "draft-1"
|
||||
owner: net-kingdom
|
||||
last_reviewed: "2026-10-24"
|
||||
review_interval: 3m
|
||||
standard_token: service-identity-privilege_v0.1
|
||||
related:
|
||||
- canon/standards/iam-profile_v0.3.md
|
||||
- canon/standards/credential-management_v0.2.md
|
||||
- canon/standards/tenancy-posture_v0.1.md
|
||||
- canon/standards/security-zones_v0.1.md
|
||||
- canon/standards/posture-feedback_v0.1.md
|
||||
- docs/service-identity-inventory.md
|
||||
- docs/crisis-custody-list.md
|
||||
---
|
||||
|
||||
# NetKingdom Service Identity and Privilege v0.1
|
||||
|
||||
## 0. Status
|
||||
|
||||
**Proposed, draft-1.** It binds nothing until the founder ratifies it and each owner adopts it.
|
||||
It was started on 2026-10-24 from the founder's direction and from the first inventory
|
||||
(`docs/service-identity-inventory.md`, NK-WP-0054-T01). Its machine-readable declaration
|
||||
(NK-WP-0054-T03) and conformance check (T04) do not exist yet.
|
||||
|
||||
The finding behind it: one LLDAP account, `uid=admin`, is at the same time the human platform
|
||||
administrator, the directory super-admin and the bind credential of Authelia, KeyCape, the
|
||||
privacyIDEA resolver and the identity-provisioner. One account has one password, so the human
|
||||
login, four services and every backup bundle share one secret. The Credential Management
|
||||
Standard §6 already calls rotating it "3-way coordinated"; the inventory found five consumers.
|
||||
|
||||
## 1. Purpose and scope
|
||||
|
||||
This standard says which identities, and which privileges, may exist inside the services that
|
||||
are part of NetKingdom. It governs the **accounts** in a service's own store, directory or
|
||||
policy engine. It does not replace:
|
||||
|
||||
- the **token profile**: human, service and agent principals in tokens belong to
|
||||
[IAM Profile v0.3](iam-profile_v0.3.md);
|
||||
- **credential storage and rotation procedure**: [Credential Management v0.2](credential-management_v0.2.md);
|
||||
- **tenant isolation**: [Tenancy Posture](tenancy-posture_v0.1.md) and
|
||||
[Security Zones](security-zones_v0.1.md).
|
||||
|
||||
In scope: LLDAP, Authelia, KeyCape, privacyIDEA, the identity-provisioner, user-engine and
|
||||
tenant-engine at their boundary, OpenBao authentication roles and policies, and the platform
|
||||
consumers of these services. Out of scope: accounts that a tenant creates inside its own
|
||||
workloads, except where they cross into a NetKingdom service.
|
||||
|
||||
## 2. Vocabulary
|
||||
|
||||
An **identity** is any account, role, client or principal held in a service's own store. A
|
||||
**credential** is what proves an identity. A **consumer** is a person or system that presents
|
||||
the credential. Every identity has exactly one **class**.
|
||||
|
||||
| Class | Meaning | Examples today |
|
||||
| --- | --- | --- |
|
||||
| `human` | A person's attributable login | `tegwick`, `admin` |
|
||||
| `break-glass` | Final authority held offline, not routine | `platform-root` (king credential) |
|
||||
| `bind` | A service's own lookup in another service's directory | planned `svc-authelia` |
|
||||
| `service-admin` | The administrative account of one service | `pi-admin`, planned `ld-admin` |
|
||||
| `workload` | A service or agent that obtains tokens or secrets | KeyCape clients, `secrets-engine-openbao` |
|
||||
| `infrastructure` | A role below the application | database role `privacyidea` |
|
||||
|
||||
## 3. Rules
|
||||
|
||||
Each rule has a stable id so that findings, exceptions and the health check can cite it.
|
||||
|
||||
**SI-1 One identity, one class.** An identity MUST have exactly one class. An account that is
|
||||
both a person and a service is non-conformant.
|
||||
|
||||
**SI-2 People and services do not share credentials.** A person MUST NOT use a service
|
||||
credential, and a service MUST NOT use a person's credential. A human's password MUST NOT be
|
||||
stored in a Secret that a service reads.
|
||||
|
||||
**SI-3 Bind identities.** A `bind` identity MUST be read-only, limited to the least subtree and
|
||||
operations its consumer needs, unable to sign in interactively, and used by exactly one
|
||||
consuming service. Two services MUST NOT share a bind credential. Where a service must write
|
||||
(for example the identity-provisioner creating users), it gets its own `workload` identity with
|
||||
the narrowest working write scope and is never given the service-admin account.
|
||||
|
||||
**SI-4 Service-admin identities.** A service SHOULD have exactly one local administrative
|
||||
identity, separate from every bind and every human. It MUST be named for its service (§4),
|
||||
MUST require a second factor where the service can enforce one, and MUST NOT be used by
|
||||
automation unless the declaration says so.
|
||||
|
||||
**SI-5 Attributed administration first.** Where a service supports administrative roles granted
|
||||
to an attributed human identity (for example OpenBao policies bound to a group), day-to-day
|
||||
administration SHOULD use that route. The local `service-admin` is the sealed fallback and is
|
||||
listed in the crisis custody list. A service that has only a local administrator (privacyIDEA
|
||||
today) records that as an exception, not as a norm.
|
||||
|
||||
**SI-6 Break-glass.** There MUST be a break-glass identity, held offline. Using it is an event
|
||||
that MUST be recorded. It MUST NOT be used for routine operation, for backup validation or as the
|
||||
test subject of a drill. It authorizes; it does not operate.
|
||||
|
||||
**SI-7 The developer identity.** The developer identity MUST NOT hold break-glass or recovery
|
||||
custody items and MUST NOT hold a production service credential. It builds and tests.
|
||||
|
||||
**SI-8 Assurance.** Every `human` and `service-admin` identity MUST require a second factor
|
||||
where the service can enforce one. A role that grants administrative policy SHOULD require the
|
||||
assurance level itself (for example an `aal2` claim bound in the OpenBao role), not only rely on
|
||||
an upstream service having checked. A role that does not MUST record why in an exception.
|
||||
|
||||
**SI-9 Custody class.** Every credential MUST declare a custody class: `offline-key`,
|
||||
`personal-safe`, `openbao-lease`, `delivered-secret` (delivered into the workload by the
|
||||
platform), or `none` (federated, no stored credential). A credential used by more than one
|
||||
consumer is non-conformant under SI-3.
|
||||
|
||||
**SI-10 Ownership and rotation.** Every identity MUST name an owner, its consumers and a
|
||||
rotation path with its coupling (what must change together). Static long-lived binds are a
|
||||
stated gap under Tenancy Posture §9 (Decision 9.1 and 9.2), not a silent exclusion; their
|
||||
compensating controls are SI-3 and a restricted network path.
|
||||
|
||||
**SI-11 Declaration and legacy.** Every identity that exists in a service MUST be declared.
|
||||
An identity that exists and is not declared is non-conformant (`unknown`). A legacy identity
|
||||
MUST have a disposition (retire, accept, or defer) with an owner and a date.
|
||||
|
||||
**SI-12 Recovery.** Every identity needed to recover a service MUST appear in the crisis custody
|
||||
list with the answer to "does using it work when SSO and OpenBao are down?". An identity that
|
||||
cannot be used while its own service is down MUST NOT be the only recovery path.
|
||||
|
||||
**SI-13 Validation is operated by the operator identity.** Restore drills and backup validation
|
||||
MUST be run by the production operator identity, with that identity's own token as the test
|
||||
subject, and MUST record which identity ran each stage.
|
||||
|
||||
## 4. Naming
|
||||
|
||||
| Class | Pattern | Notes |
|
||||
| --- | --- | --- |
|
||||
| `bind` | `svc-<service>` | One per consuming service; `svc-<service>-<function>` if one service needs several |
|
||||
| `service-admin` | `<short>-admin` | The short form is registered per service (see §9): `pi-admin`; `ld-admin` proposed for LLDAP |
|
||||
| `break-glass` | `platform-root` | The king credential |
|
||||
| `human` | the person's own login | `tegwick`, `admin` |
|
||||
| `workload` | the token subject form already in use | for example `service:secrets-engine`; IAM Profile v0.3 governs the token |
|
||||
|
||||
Names are reserved for their class. A `svc-` or `-admin` name MUST NOT be used for a human.
|
||||
|
||||
## 5. Target shape for today's services (informative)
|
||||
|
||||
This table shows where the rules lead. The authoritative state is the inventory, and the
|
||||
steps are NK-WP-0054-T05 and T06.
|
||||
|
||||
| Service | `service-admin` | `bind` and write identities | Human route |
|
||||
| --- | --- | --- | --- |
|
||||
| LLDAP | `ld-admin` (the built-in super-admin, renamed or replaced after rehearsal) | `svc-authelia`, `svc-keycape`, `svc-privacyidea` read-only; a scoped provisioner identity | `admin` as a normal member of the admin group, no shared password |
|
||||
| Authelia | none (LDAP backend only) | uses `svc-authelia` | none |
|
||||
| privacyIDEA | `pi-admin` | resolver uses `svc-privacyidea` | none (local administrator only: exception) |
|
||||
| KeyCape | none | uses `svc-keycape` | none |
|
||||
| OpenBao | per its own policy | n/a | `net-kingdom-admins` group to `platform-admin` |
|
||||
|
||||
## 6. Declaration
|
||||
|
||||
Each service publishes one declaration of every identity it holds, in a machine-readable form
|
||||
defined by NK-WP-0054-T03. For each identity: name, class, purpose, privileges, custody class,
|
||||
consumers, owner, rotation path and coupling, second-factor requirement, status
|
||||
(`active`, `legacy`, `planned`) and any exception id. A declaration holds no credential and no
|
||||
secret-shaped value.
|
||||
|
||||
## 7. Conformance and the health check
|
||||
|
||||
For each identity the result is one of `conformant`, `non-conformant` (with the rule ids),
|
||||
`excepted` (with the exception id) or `unknown`. Unknown is a finding, not a pass.
|
||||
|
||||
The health check (NK-WP-0054-T04) compares declared against observed state: for example,
|
||||
which DN each service binds as, which groups the bind identities belong to, and which policies
|
||||
an admin role carries. It uses read-only metadata that each owner provides and repository
|
||||
manifests. It MUST NOT read a Secret. Its findings are proposals routed to the identity's owner
|
||||
through [Posture Feedback](posture-feedback_v0.1.md), with an evidence-freshness bound. It
|
||||
changes nothing.
|
||||
|
||||
## 8. Exceptions
|
||||
|
||||
An exception is time-boxed and records: the rule, the identity, the reason, the owner, an expiry
|
||||
date and the compensating control. It is reviewed at the standard's review interval. A rule
|
||||
without a recorded exception that is broken is non-conformant.
|
||||
|
||||
Initial exceptions at adoption:
|
||||
|
||||
| Id | Rule | Identity | Reason | Until |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| SI-X1 | SI-1, SI-2, SI-3 | LLDAP `admin` | One account is the human, the super-admin and the shared bind of five consumers | NK-WP-0054-T05 completes |
|
||||
| SI-X2 | SI-10 | LDAP binds | Static long-lived credential; LDAP has no lease | Tenancy Posture §9 gap review |
|
||||
| SI-X3 | SI-11 | `trigger-admin` (privacyIDEA) | Legacy account with uninventoried consumers | NK-WP-0049-T22 disposition |
|
||||
| SI-X4 | SI-8 | OpenBao `netkingdom-platform-admin` | Role binds on the group claim only in the repository file | Decision on §10 question 1 |
|
||||
| SI-X5 | SI-5 | privacyIDEA | Only a local administrator is supported | Upstream capability |
|
||||
|
||||
## 9. Relationship to other documents
|
||||
|
||||
- **IAM Profile v0.3** defines the principal types in tokens. This standard governs the
|
||||
accounts that exist behind them and does not change the token profile.
|
||||
- **Credential Management v0.2 §6** lists `LLDAP_LDAP_USER_PASS` as a three-way coupling.
|
||||
On adoption that row is corrected and replaced by the per-service bind accounts.
|
||||
- **Tenancy Posture §9** treats long-lived credentials as a gap; SI-10 applies it to binds.
|
||||
- **Security Layer Model v0.9** should be checked for an identity-layer statement this standard
|
||||
must match; that reconciliation is part of ratification.
|
||||
- **Crisis custody list** (`docs/crisis-custody-list.md`) is the recovery companion to SI-9 and SI-12.
|
||||
- The registry of `<short>-admin` forms lives with the declarations (T03) and starts with
|
||||
`pi-admin` and the proposed `ld-admin`.
|
||||
|
||||
## 10. Open questions
|
||||
|
||||
1. **OpenBao assurance.** Should the `platform-admin` role bind `aal2` itself (SI-8) or rely on
|
||||
KeyCape's `requireForAll`? The other privileged roles already bind it.
|
||||
2. **Renaming LLDAP's built-in admin.** The directory's super-admin name is configurable, but
|
||||
renaming it on an existing directory is untested. It needs a rehearsal in isolation before
|
||||
`ld-admin` is decided (T06).
|
||||
3. **The human `admin` in LLDAP.** Does the human keep LLDAP admin-UI rights through group
|
||||
membership, or administer users only through the governed provisioner path?
|
||||
4. **The provisioner's narrowest scope.** What is the least privilege that still lets it create
|
||||
users and groups? It must be tested against the pinned LLDAP image.
|
||||
5. **Workload clients.** KeyCape's confidential clients are governed by IAM Profile v0.3. This
|
||||
standard only requires that each is declared, owned and not shared. Is that enough?
|
||||
6. **Where the declarations live.** In each service's repository (preferred, owners are
|
||||
accountable) or in this repository (simpler to validate).
|
||||
|
||||
## 11. Adoption
|
||||
|
||||
Structure first, tooling second, as with Tenancy Posture. The order is: ratify the vocabulary and
|
||||
rules; complete the declarations (T03); run the health check read-only (T04) and publish the
|
||||
first report; then retire the exceptions one by one, starting with SI-X1 (T05). No exception is
|
||||
closed by writing a declaration. Each is closed by the live change and an evidence run.
|
||||
|
|
@ -73,10 +73,13 @@ is an uninventoried legacy admin, and OpenBao `platform-admin` binds on a group
|
|||
|
||||
```task
|
||||
id: NK-WP-0054-T02
|
||||
status: todo
|
||||
status: wait
|
||||
priority: high
|
||||
assignee: claude-code
|
||||
needs_human: true
|
||||
decision_id: "a3582e79-4ece-4902-9bfa-e962aef2b8f2"
|
||||
depends_on: [NK-WP-0054-T01]
|
||||
blocking_reason: "Draft-1 delivered 2026-10-24. Await the founder review and answers to the six open questions in section 10."
|
||||
state_hub_task_id: "5830e2eb-334a-52fa-9c55-a8c00d89c09f"
|
||||
```
|
||||
|
||||
|
|
@ -90,6 +93,12 @@ Profile v0.3, Credential Management v0.2 and the Security Zones standard.
|
|||
|
||||
**Done when:** the draft is reviewed by the founder and the service owners it names.
|
||||
|
||||
Draft-1 delivered 2026-10-24: `canon/standards/service-identity-privilege_v0.1.md` (proposed). Thirteen
|
||||
rules (SI-1 to SI-13), naming, a target shape for today's services, the declaration fields, the
|
||||
conformance result states, five initial exceptions (SI-X1 to SI-X5) and six open questions. It
|
||||
extends IAM Profile v0.3 and Credential Management v0.2 without changing either. Review is the
|
||||
founder's, then the service owners named in the inventory.
|
||||
|
||||
## Schema and offline conformance validator
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue