Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
6.3 KiB
Owner-invoked LLDAP group maintenance
Source repair: NK-WP-0049-T02, 2026-10-14. The shell entry points now delegate to
lldap_admin.py, which reuses the existing identity-provisioner directory
operations and service-group validation. This is the bootstrap/maintenance path,
not a new account lifecycle service, credential broker or authority boundary.
Scope and custody
An authorized IAM custodian supplies an explicit private temporary custody root
outside Git. The root and lldap/ directory must be owned by the caller and mode
0700; lldap/secrets.env must be an owned, single-link, non-symlink regular file
with mode 0600. The existing custody reader parses LLDAP_LDAP_USER_PASS literally.
Do not add shell quotes, export, or executable commands. Other generated fields
may remain in that file; this tool does not rewrite it.
Credential ownership/routing and an exact live change approval remain required. The adapter does not fetch Kubernetes Secrets, use an ambient admin password, create accounts or credentials, invoke curl/kubectl, or install a permanent key. A preview digest is an observation binding, not an approval, caller identity or runtime isolation proof. Use the owner's protected execution context; do not hand the directory admin credential to an unisolated agent.
The default origin is https://lldap.coulomb.social. An explicit literal
127.0.0.1 or [::1] origin with a port is accepted for an owner-approved forward
or isolated fixture. localhost, arbitrary hosts, HTTP on the public host,
userinfo, paths, queries and fragments are refused. TLS uses system trust;
redirects and ambient proxies are disabled. Credentials stay in Python memory
and the HTTP body/header, never in child-process arguments. Provider errors are
contained; output has fixed failure phases, not raw responses.
Bootstrap: only three empty groups
./bootstrap-users.sh --root /absolute/private/custody
The default is a nonmutating preview. It names missing net-kingdom-users,
net-kingdom-admins and activity-core-operators groups, with a
snapshot_sha256. After reviewing that exact operation under the existing live
approval, apply using the preview digest:
./bootstrap-users.sh --root /absolute/private/custody \
--apply --expected-digest REVIEWED_PREVIEW_SHA256
Existing groups, IDs, users and memberships must survive unchanged. This command only creates missing groups without members. It cannot grant platform-admin membership, reset a password or reconstruct missing users after data loss.
App-scoped membership
Ordinary account onboarding stays in User Engine / identity-provisioner. To preview an exact service-group change for an existing directory identity:
./manage-group-members.sh add --user agent-codex --group activity-core-operators \
--root /absolute/private/custody
./manage-group-members.sh remove --user agent-codex --group activity-core-operators \
--root /absolute/private/custody
./manage-group-members.sh list --group activity-core-operators \
--root /absolute/private/custody
Add/remove require --apply --expected-digest REVIEWED_PREVIEW_SHA256 to mutate.
List is read-only and emits only member identifiers. Group and user must already
exist; this path never creates either. Tenant, platform (net-kingdom-),
suspension (netkingdom-) and LLDAP administrative groups are refused by the
existing service-group validator before login. Use their respective owners for
those operations; the old unrestricted membership helper is not a fallback.
Preservation, interruption and recovery
The digest binds origin, operation, target and the observed directory users, groups, IDs and memberships. Apply re-reads before its first write and refuses stale state. Final readback must equal precisely the intended change, including unchanged unrelated memberships. An already-satisfied change is a verified no-op.
LLDAP does not provide a cross-query compare-and-swap transaction here. The owner must hold an exclusive maintenance window across preview/apply; two reads are not a lock. A failure during multiple group creations can leave partial state. There is no blind rollback or retry and no group deletion. On failure retain the non-secret receipt, inspect current state and reconcile under the owner before a new reviewed preview. Do not infer failure means nothing changed.
T07 is a structural diagnostic
../verify-t07.sh --root /absolute/private/custody
This checks actual directory structure and reports missing baseline groups,
user count and break-glass account/group presence without declaring them usable.
It does not read KeyCape's configuration Secret, execute inside a pod, infer OIDC
claims or treat a reachable portal as user acceptance. Even complete structural
observations return 2, with native_acceptance: unverified. Invalid input,
authentication/transport failure or malformed responses return 1. Both mean
the old T07 completion gate is unsatisfied. Do not use this diagnostic alone to
close user lifecycle, MFA, session revocation, client access or recovery tasks.
Use current owner-specific issuer/consumer checks and actual authorized human
lifecycle/login/recovery receipts for those properties. The
legacy lifecycle retirement notice
and verification audit describe
these limits. openbao-client-config.py remains the specific OpenBao client
configuration checker; a configuration check is not actual client login.
Verification and live limits
Regression tests cover private input, refusals, previews, state drift,
preservation and malformed/failed readbacks. tests/lldap_groups_native_fixture.py
exercises the actual adapter against an immutable existing local LLDAP image,
with synthetic credentials, loopback-only publication and disposable storage.
It removes its own fixture container and private files. The pinned native test
image and results are in Custodian's lldap-group-maintenance.json receipt.
Those receipts do not prove the currently deployed directory version, current credential validity, attended authority, independent recovery or live enforcement of earlier identity-provisioner source fixes. NK-WP-0049-T03 retains native owner acceptance, and T02 retains incident-cutover/full caller-inventory work.