security: retire unsafe legacy LDAP lifecycle callers
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
This commit is contained in:
parent
276b95f6ba
commit
84c5dbeec8
21 changed files with 390 additions and 1023 deletions
|
|
@ -1,5 +1,14 @@
|
|||
# NetKingdom Runtime Architecture
|
||||
|
||||
> Lifecycle update, 2026-10-14: the lifecycle tooling descriptions below are a
|
||||
> historical snapshot, not current execution instructions. Account creation,
|
||||
> pattern deletion and inferred-claims verification in the old 0019 helpers are
|
||||
> retired. Their secret handling and success assertions are not accepted evidence
|
||||
> of current safety or readiness. Use the [current owner routes](legacy-lldap-lifecycle-retirement.md)
|
||||
> and actual native receipts. Ordinary lifecycle delivery has since advanced in
|
||||
> NK-WP-0025/NK-WP-0038; independent recovery and other IAM callers remain open.
|
||||
|
||||
|
||||
**Status:** draft (initial capture for NET-WP-0018-T02)
|
||||
**Date:** 2026-06-03
|
||||
**Context:** Documents the *as-deployed* runtime after the first successful bootstrap (0015-0017) + T06-adjacent polish (0019). Not an idealized future architecture. Specific enough to guide a scratch rebuild or rehearsal without rediscovering integration details. Incorporates pragmatic audit paths and known UE integration points/gaps per the persisted assessment.
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ runbook or a dedicated procedure. Missing runbooks are listed separately.
|
|||
| `keycape/register-coulomb-social.sh` | None found | unknown |
|
||||
| `keycape/verify-openbao-client.sh` | [README.md](../sso-mfa/k8s/keycape/README.md), [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | unknown |
|
||||
| `lldap/bootstrap-users.sh` | [README.md](../sso-mfa/k8s/lldap/README.md), [OPERATOR-GROUPS.md](../sso-mfa/k8s/lldap/OPERATOR-GROUPS.md) | unknown |
|
||||
| `lldap/break-glass.sh` | [platform-root-custody.md](../docs/platform-root-custody.md) | unknown |
|
||||
| `lldap/break-glass.sh` | [platform-root-custody.md](../docs/platform-root-custody.md) | retired 2026-10-14; [owner routes](legacy-lldap-lifecycle-retirement.md) |
|
||||
| `lldap/create-secrets.sh` | [README.md](../sso-mfa/k8s/lldap/README.md), [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | unknown |
|
||||
| `lldap/create-user.sh` | [OPERATOR-GROUPS.md](../sso-mfa/k8s/lldap/OPERATOR-GROUPS.md), [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | unknown |
|
||||
| `lldap/dry-run-nonroot-user.sh` | [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | unknown |
|
||||
| `lldap/create-user.sh` | [OPERATOR-GROUPS.md](../sso-mfa/k8s/lldap/OPERATOR-GROUPS.md), [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | retired 2026-10-14; [owner routes](legacy-lldap-lifecycle-retirement.md) |
|
||||
| `lldap/dry-run-nonroot-user.sh` | [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | retired 2026-10-14; [owner routes](legacy-lldap-lifecycle-retirement.md) |
|
||||
| `lldap/manage-group-members.sh` | [OPERATOR-GROUPS.md](../sso-mfa/k8s/lldap/OPERATOR-GROUPS.md) | unknown |
|
||||
| `postgresql/create-secrets.sh` | [README.md](../sso-mfa/k8s/postgresql/README.md), [smooth-bootstrap-guide.md](../docs/smooth-bootstrap-guide.md) | unknown |
|
||||
| `privacyidea/bootstrap-admin.sh` | [README.md](../sso-mfa/k8s/privacyidea/README.md) | unknown |
|
||||
|
|
|
|||
68
docs/legacy-lldap-lifecycle-retirement.md
Normal file
68
docs/legacy-lldap-lifecycle-retirement.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Legacy LLDAP lifecycle retirement
|
||||
|
||||
Effective 2026-10-14; source reconciliation under NK-WP-0049-T02.
|
||||
|
||||
The three commands below now exit 2 before inspecting arguments, discovering
|
||||
credentials, or calling any external program. Their old arguments are ignored.
|
||||
The two Make targets and three console commands also refuse execution. No
|
||||
account, membership, password, token or deployed workload is changed by this
|
||||
source retirement. Existing credentials are not revoked.
|
||||
|
||||
| Retired command | Why withdrawn | Owner route |
|
||||
| --- | --- | --- |
|
||||
| `sso-mfa/k8s/lldap/create-user.sh` | Direct creation bypassed governed lifecycle/linking; test mode used predictable passwords; admin credentials were sourced or discovered and passed through unsafe shell paths. | Ordinary onboarding through User Engine and the existing identity-provisioner. Platform-root bootstrap remains a separate reviewed IAM procedure. |
|
||||
| `sso-mfa/k8s/lldap/dry-run-nonroot-user.sh` | The “dry-run” mutated real users and passwords; pattern cleanup lacked creation provenance; generated evidence overstated verification. | An explicitly scoped owner lifecycle trial with exact created-identity receipts and actual consumer checks. |
|
||||
| `sso-mfa/k8s/lldap/break-glass.sh` | Repeated execution could overwrite credentials and depended on an unsupported password GraphQL mutation. This is not an accepted provider recovery path. | Preserve existing offline custody; obtain the IAM owner's exact recovery procedure and native independent-recovery evidence under NK-WP-0049-T03. |
|
||||
|
||||
## Ordinary onboarding and lifecycle
|
||||
|
||||
Use the existing [public registration contract](public-registration-orchestration-contract.md):
|
||||
User Engine orchestrates mailbox verification for an admitted client/tenant,
|
||||
links the canonical subject, and invokes identity-provisioner. The IAM provider
|
||||
owns the single-use password-setup handoff. A fresh KeyCape login establishes the
|
||||
application session. No predictable password or direct administrative shell
|
||||
creation is a substitute. Completed NK-WP-0025 and NK-WP-0038 record earlier
|
||||
registration and scoped tenant-access delivery; those receipts do not establish
|
||||
current deployment availability. Check the owner’s current service and contract
|
||||
before a trial; this document does not introduce a new provisioning API.
|
||||
|
||||
The [User Engine boundary contract](../canon/standards/user-engine-boundary-contract_v0.1.md)
|
||||
keeps domain accounts/product memberships in User Engine and coarse authentication
|
||||
groups, passwords and MFA in IAM. Protected lifecycle mutations require the
|
||||
existing authorization path. Tenant-access changes must preserve other tenants,
|
||||
the global identity and unrelated suspension state. Group removal alone does not
|
||||
prove global lockout or session revocation. Public registration cannot create a
|
||||
platform-root or platform-admin identity.
|
||||
|
||||
## Evidence and cleanup
|
||||
|
||||
The console's `lifecycle-flow-template` and `onboarding-dry-run-template` now
|
||||
produce blank worksheets with false assurances. Fill them only from actual
|
||||
owner/consumer results. Their existing validators check structure and assertions;
|
||||
a valid document is not independent proof that a native operation happened.
|
||||
Historic evidence is retained as historic evidence.
|
||||
|
||||
For an authorized trial, retain exact subject/tenant/client identifiers and
|
||||
creation provenance, actual issued-claims and effective-access observations,
|
||||
negative access tests, and the disposition of the exact test identity and its
|
||||
sessions/credentials. Retain non-secret receipt references, never token or
|
||||
password values. Do not infer issued claims from a directory group list or delete
|
||||
accounts selected by a name pattern. Resource transfer and cross-tenant effects
|
||||
must be resolved through the lifecycle owner before offboarding.
|
||||
|
||||
## Recovery and remaining work
|
||||
|
||||
Keep the existing break-glass account and offline custody material until the
|
||||
owner explicitly authorizes a change. This retirement neither rotates its
|
||||
password nor proves it works independently of a failed identity provider.
|
||||
Disabling MFA is not evidence of independent recovery. The provider dependency
|
||||
limitation was already recorded in
|
||||
[the KeyCape exposure map](../history/2026-08-23-keycape-exposure-dependency-map.md).
|
||||
NK-WP-0049-T03 still needs the exact owner-approved recovery ceremony, separated
|
||||
key/snapshot custody, failed-key refusal, native restore and cleanup receipts.
|
||||
|
||||
`bootstrap-users.sh`, `manage-group-members.sh` and `verify-t07.sh` remain separate
|
||||
IAM caller repairs under NK-WP-0049-T02. Their credential extraction and current
|
||||
verification claims have not been repaired by this change. Incident cutover
|
||||
helpers and the complete root-output inventory also remain open. This document
|
||||
and these source tests do not close NK-WP-0049 or establish live recovery readiness.
|
||||
|
|
@ -162,7 +162,7 @@ deliberately short, closed, and enumerated here rather than left to judgement:
|
|||
|
||||
- `platform-root`'s own password and TOTP recovery codes
|
||||
- OpenBao unseal shares and root token
|
||||
- the `break-glass` account password (`sso-mfa/k8s/lldap/break-glass.sh`)
|
||||
- the existing `break-glass` account password under offline custody; the old creator is [retired](legacy-lldap-lifecycle-retirement.md), and independent recovery remains to be verified
|
||||
|
||||
Anything on that list in `operators/` would be a circular dependency: you would
|
||||
need the store to reach the credential that opens the store. Anything *not* on
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
# Security Bootstrap Scratch-Rebuild Risk Assessment And Rehearsal Plan
|
||||
|
||||
> Lifecycle update, 2026-10-14: the lifecycle tooling descriptions below are a
|
||||
> historical snapshot, not current execution instructions. Account creation,
|
||||
> pattern deletion and inferred-claims verification in the old 0019 helpers are
|
||||
> retired. Their secret handling and success assertions are not accepted evidence
|
||||
> of current safety or readiness. Use the [current owner routes](legacy-lldap-lifecycle-retirement.md)
|
||||
> and actual native receipts. Ordinary lifecycle delivery has since advanced in
|
||||
> NK-WP-0025/NK-WP-0038; independent recovery and other IAM callers remain open.
|
||||
|
||||
|
||||
**Status:** complete (NET-WP-0018-T09)
|
||||
**Date:** 2026-06-03
|
||||
**Workplan:** NET-WP-0018 Bootstrap Automation And Rebuild Readiness
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
# Security Bootstrap Retrospective and Automation Gap Matrix
|
||||
|
||||
> Lifecycle update, 2026-10-14: the lifecycle tooling descriptions below are a
|
||||
> historical snapshot, not current execution instructions. Account creation,
|
||||
> pattern deletion and inferred-claims verification in the old 0019 helpers are
|
||||
> retired. Their secret handling and success assertions are not accepted evidence
|
||||
> of current safety or readiness. Use the [current owner routes](legacy-lldap-lifecycle-retirement.md)
|
||||
> and actual native receipts. Ordinary lifecycle delivery has since advanced in
|
||||
> NK-WP-0025/NK-WP-0038; independent recovery and other IAM callers remain open.
|
||||
|
||||
|
||||
**Status:** initial draft (NET-WP-0018-T03)
|
||||
**Date:** 2026-06-03
|
||||
**Scope:** Captures the first successful NetKingdom bootstrap (through 0015-0017 "Reopen under custody" + 0019 T06-adjacent polish) and automation gaps. Input from T02 runtime architecture doc, prior workplan notes/evidence (0017/0019), console metadata/.local flags, operator experience, assessment, and pragmatic records (progress events, evidence.json, git, console validators).
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
# Security Bootstrap User Lifecycle
|
||||
|
||||
> Lifecycle update, 2026-10-14: the lifecycle tooling descriptions below are a
|
||||
> historical snapshot, not current execution instructions. Account creation,
|
||||
> pattern deletion and inferred-claims verification in the old 0019 helpers are
|
||||
> retired. Their secret handling and success assertions are not accepted evidence
|
||||
> of current safety or readiness. Use the [current owner routes](legacy-lldap-lifecycle-retirement.md)
|
||||
> and actual native receipts. Ordinary lifecycle delivery has since advanced in
|
||||
> NK-WP-0025/NK-WP-0038; independent recovery and other IAM callers remain open.
|
||||
|
||||
|
||||
Status: draft UX contract
|
||||
Date: 2026-05-24
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ See also:
|
|||
- docs/NetkingdomRuntimeArchitecture.md (T02 – what exists)
|
||||
- docs/security-bootstrap-retrospective.md (T03 – what was bumpy, now automated, gaps)
|
||||
- tools/security-bootstrap-console/security_bootstrap_console.py + make security-bootstrap-* (control surface, evidence, validators)
|
||||
- sso-mfa/k8s/lldap/dry-run-nonroot-user.sh + related (0019 polish)
|
||||
- [Current lifecycle owner routes](legacy-lldap-lifecycle-retirement.md); the 0019 scripts are retired.
|
||||
- .local/security-bootstrap.json + console status (current gates)
|
||||
|
||||
**Pragmatic note (per 0018 Coordination):** Track your progress through this guide using State Hub /progress/ (with workstream/task), dated notes in NET-WP-0018 workplan, git, console evidence/validators, /tmp evidence. This feeds future retrospectives.
|
||||
|
|
@ -25,7 +25,7 @@ From platform architecture and UX contracts:
|
|||
- **UI posture (console/web):** Calm field notebook; black/white + hi accents; panels; sentence case; no hype. Shows effective access before any save/action. Blocked conditions explicit (e.g., no platform-root for non-king, MFA required for privileged).
|
||||
- **Evidence discipline:** All steps produce/require non-secret evidence.json or metadata flags matching exact templates/validators (no secret markers). 12+ bools for user lifecycle (effective preview, no root grant, actor checks, verified identity/claims, reversible, no secrets recorded, etc.).
|
||||
- **Actor classes & previews:** Always distinguish (setup operator, platform admin, tenant admin, reviewer, king). Show effective privileges before create/save. Never grant platform-root except via explicit king path.
|
||||
- **Secret boundary:** Console/UI never collects/stores secrets. Use password-safe, k8s secrets, or operator memory. Prefer k8s fallback for dry-runs (see 0019).
|
||||
- **Secret boundary:** Console/UI never collects/stores secrets. Use password-safe, k8s secrets, or operator memory. Use the existing governed credential-delivery path; legacy automatic admin-secret extraction is withdrawn.
|
||||
- **Reversible where possible; human custody gates explicit.**
|
||||
- **Handoff to production readiness:** After S6, move to 0017 production items (audit durability, etc. – not duplicated here).
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ From platform architecture and UX contracts:
|
|||
5. KeyCape deployment + client registration + OIDC.
|
||||
6. OpenBao init/unseal/config (OIDC admin binding via KeyCape).
|
||||
7. Token cleanup, root disposition, restore drill, escrow/custody.
|
||||
8. User lifecycle (onboard/lock/offboard/review – use 0019 dry-run for tests).
|
||||
8. User lifecycle (onboard/lock/offboard/review through the current User Engine and IAM owner contracts).
|
||||
9. State Hub sync, audit posture, cleanup/rotation.
|
||||
10. Platform reopen (S6) + handoff.
|
||||
|
||||
|
|
@ -77,18 +77,18 @@ See T03 retrospective for past realm drift bumps (now partially automated via ru
|
|||
|
||||
## Step 3: LLDAP / Bootstrap User Creation (platform-root / king)
|
||||
|
||||
- Create platform-root user in LLDAP (via create-user.sh or LLDAP admin UI at lldap.coulomb.social).
|
||||
- Command example (with KUBECTL fallback): `cd sso-mfa/k8s/lldap && ./create-user.sh platform-root ...` (no --admin for non-root tests; use --admin only for platform admins via king path).
|
||||
- Establish or recover platform-root only through the exact owner-reviewed IAM bootstrap/recovery ceremony; ordinary public registration cannot grant platform-root.
|
||||
- The legacy account-creation and break-glass scripts are retired; see [recovery limits](legacy-lldap-lifecycle-retirement.md). Preserve existing account/password custody pending owner verification.
|
||||
- Self-enroll TOTP in privacyIDEA.
|
||||
- Verify MFA state: `bash sso-mfa/k8s/privacyidea/check-user-mfa-state.sh platform-root --token-file /absolute/private/diagnostic.jwt` after owner-admitted protected input. See the [diagnostic contract](../sso-mfa/k8s/privacyidea/README.md#scoped-factor-state-diagnostic); the KeyCape workload credential is not a general diagnostic delivery lane. Counts do not verify user existence or an MFA login.
|
||||
- Verify OIDC/KeyCape path: `cd ../keycape && ./verify-openbao-client.sh`.
|
||||
- Groups: net-kingdom-admins for platform-root.
|
||||
- Evidence: identity_account_created, identity_group_confirmed, mfa_*, oidc_login_verified.
|
||||
- For non-root tests: use 0019 dry-run (see Step 8).
|
||||
- For non-root trials: follow Step 7 with exact owner scope and actual consumer evidence.
|
||||
|
||||
**Blocked if:** Actor requests net-kingdom-admins without king path; no MFA for privileged.
|
||||
|
||||
**Console:** `lifecycle-guide` for full flow; `onboarding-dry-run*` for tests.
|
||||
**Console:** `lifecycle-guide` for current owner routes. Legacy execution and inferred-claims commands exit with failure.
|
||||
|
||||
## Step 4: KeyCape Deployment + Client Registration + OIDC
|
||||
|
||||
|
|
@ -160,34 +160,24 @@ See T02 for secret/credential path details; T03 for past claim shape / token iss
|
|||
|
||||
See T03 for operator-state / token bumps (now in metadata + validators).
|
||||
|
||||
## Step 7: User Lifecycle (Onboard / Lock / Offboard / Review) – Use 0019 Polish
|
||||
## Step 7: User lifecycle through its owners
|
||||
|
||||
This implements the first practical flow per docs/security-bootstrap-user-lifecycle.md (UX contract) + T02/ T03.
|
||||
Follow [the current lifecycle routes and retirement notice](legacy-lldap-lifecycle-retirement.md).
|
||||
User Engine owns ordinary onboarding, account lifecycle and product memberships;
|
||||
the existing identity-provisioner and IAM provider own identity and password setup.
|
||||
Use only admitted clients/tenants. Platform-root bootstrap has a separate owner
|
||||
ceremony and cannot be performed through public registration.
|
||||
|
||||
**Always:**
|
||||
- Preview effective access (actor_class, scope, groups, MFA, OpenBao policy, no root for non-king).
|
||||
- Record non-secret evidence/audit (State Hub /progress/, console evidence, k8s audit).
|
||||
- MFA required for privileged.
|
||||
- Reversible where possible.
|
||||
Preview the intended scope, obtain the existing authorization, and retain actual
|
||||
identity/claims/access, denial and exact cleanup receipts. A group list cannot
|
||||
verify issued claims or prove all sessions revoked. Never delete test accounts
|
||||
by a name pattern. Preserve other tenants and global identity state.
|
||||
|
||||
**Detailed (from console lifecycle-guide + 0019):**
|
||||
- Onboard scoped non-root: use `make security-bootstrap-onboarding-dry-run SUBJECT=... EMAIL=... DISPLAY="..."` (or direct ./dry-run-nonroot-user.sh). Internally: safe secret (k8s/env /tmp), create --test (no --admin), verify MFA/KeyCape, optional lock/offboard GraphQL, populate/validate evidence (lldap_identity_verified, keycape_oidc_claims_verified, effective_access_summary, lock_offboard_result, actor_class="user", groups=["net-kingdom-users"], no_secret_material_recorded, prevents_platform_root_grant, etc.).
|
||||
- Console: `onboarding-dry-run`, `onboarding-dry-run-claims` (infers claims from groups + T01 role; warns on admins/root), `lifecycle-cleanup-dryrun-users --pattern t06-*`.
|
||||
- Lock: remove from groups (GraphQL or LLDAP UI); reversible.
|
||||
- Offboard: delete user after resource transfer + reason/date; evidence.
|
||||
- Review: check-user-mfa-state, LLDAP groups, owned principals; rotate via creds tools.
|
||||
- Fabric/tenant admin: same but scoped groups, no platform-root, explicit preview "will NOT be in net-kingdom-admins".
|
||||
- For platform-root/king: king path only.
|
||||
|
||||
**Evidence templates:** `make security-bootstrap-onboarding-dry-run-template`, `lifecycle-flow-template`.
|
||||
**Validate:** `make security-bootstrap-validate-onboarding-dry-run`, `validate-lifecycle-flow`.
|
||||
**Runbook:** "User lifecycle dry-run (T06)" in console runbooks (refs 0019 + script).
|
||||
|
||||
**Blocked if:** Missing actor/scope, privileged without MFA, ordinary user gets root groups/policy.
|
||||
|
||||
See 0019 workplan + dry-run script + T03 matrix for past taint/hygiene bumps (now largely automated via /tmp + evidence).
|
||||
|
||||
Update console lifecycle_guide T06 section if it still shows old manual secret steps (prefer orchestrator).
|
||||
`lifecycle-flow-template` and `onboarding-dry-run-template` are blank evidence
|
||||
worksheets. Their validators check structure; passing is not native acceptance.
|
||||
The old Make/console execution commands and “User lifecycle dry-run (T06)” runbook
|
||||
are retired. Group administration and independent recovery remain open in
|
||||
NK-WP-0049; do not infer readiness from the earlier 0019 receipts.
|
||||
|
||||
## Step 8: Platform Reopen + Handoff
|
||||
|
||||
|
|
@ -203,7 +193,7 @@ Update console lifecycle_guide T06 section if it still shows old manual secret s
|
|||
|
||||
- Use T03 retrospective + T02 arch + this guide for future drills.
|
||||
- Address gaps (UE adapters per assessment, full Audit Core correlation, more T08 validators).
|
||||
- Rehearse rebuild per T09 (T09 complete; see docs/security-bootstrap-rebuild-risk-and-rehearsal.md for risk classification + non-destructive scripted/ns/parallel plan using 0019+creds+T08 validators; scripted/namespace first; use 0019 dry-run as model).
|
||||
- Rehearse rebuild per T09 (T09 complete; see docs/security-bootstrap-rebuild-risk-and-rehearsal.md for risk classification + non-destructive scripted/ns/parallel plan using 0019+creds+T08 validators; scripted/namespace first; use current owner lifecycle contracts and exact trial provenance).
|
||||
|
||||
## Evidence Summary Table (Core Non-Secret)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue