Implement bounded Kanidm credential mutations #8

Closed
opened 2026-08-14 23:21:56 +00:00 by agent.odin · 3 comments
Owner

Proposal

Implement the one narrow Kanidm mutation adapter used by the private Vedanta lifecycle service.

Delivery class

agent-unit — add src/kanidm.rs and capture-double tests. The live narrow-manager proof remains flake-ops #123.

Design

Mint requires explicit expiry and returns value, token ID, expiry, and subject once. Rotation creates a distinct successor rather than extending in place. Invalidate targets one authenticated token ID. Kanidm denial is final and never triggers broader authority.

Tasks

  • Implement bounded mint with typed result metadata.
  • Implement successor rotation with the next credential generation.
  • Implement exact token-ID invalidation.
  • Prove unrelated-subject denial and no authority-widening retry.

Specification Delta

Requirement: every credential mutation is bounded and exact

Scenario: a successor is rotated and its predecessor invalidated

  • GIVEN an eligible service account and authenticated predecessor token ID
  • WHEN rotation and later invalidation run
  • THEN a distinct expiring successor is created and only the named predecessor is invalidated

OpenSpec

OpenSpec 20

Structural parent

Vedanta#20

## Proposal Implement the one narrow Kanidm mutation adapter used by the private Vedanta lifecycle service. ## Delivery class `agent-unit` — add `src/kanidm.rs` and capture-double tests. The live narrow-manager proof remains flake-ops #123. ## Design Mint requires explicit expiry and returns value, token ID, expiry, and subject once. Rotation creates a distinct successor rather than extending in place. Invalidate targets one authenticated token ID. Kanidm denial is final and never triggers broader authority. ## Tasks - [ ] Implement bounded mint with typed result metadata. - [ ] Implement successor rotation with the next credential generation. - [ ] Implement exact token-ID invalidation. - [ ] Prove unrelated-subject denial and no authority-widening retry. ## Specification Delta ### Requirement: every credential mutation is bounded and exact #### Scenario: a successor is rotated and its predecessor invalidated - **GIVEN** an eligible service account and authenticated predecessor token ID - **WHEN** rotation and later invalidation run - **THEN** a distinct expiring successor is created and only the named predecessor is invalidated ## OpenSpec [OpenSpec 20](https://jo.et0.pw/Ting/Vedanta/wiki/OpenSpec-20-openbao-forge-identity-lifecycle) ## Structural parent [Vedanta#20](https://jo.et0.pw/Ting/Vedanta/issues/20)
Author
Owner

Grooming state: Clarified
Owner ruling (2026-08-26): Vedanta owns IDM mint_api_token, rotate_api_token, and explicit invalidate_api_token. Jostoph has no legitimacy in the IDM plan; its scope here is Forge-only.

Current placement: #8 remains the bounded Kanidm native-adapter unit under OpenSpec 20. The later ratified OpenSpec 61 also requires a Forgejo native adapter, but no current Session leaf owns it; that structural gap is carried by #20 Q1 rather than by silently broadening this record.

Clarification: rotation mints a successor; caller-selected grace leaves the old credential valid until explicitly invalidated. Invalidating unknown or already-invalid credentials succeeds externally while the audit trail retains the distinction.

Larandar: no API-token ownership decision remains on this record.

<!-- agent.odin:groom:v1 --> **Grooming state:** Clarified **Owner ruling (2026-08-26):** Vedanta owns IDM `mint_api_token`, `rotate_api_token`, and explicit `invalidate_api_token`. Jostoph has no legitimacy in the IDM plan; its scope here is Forge-only. **Current placement:** #8 remains the bounded Kanidm native-adapter unit under [OpenSpec 20](https://jo.et0.pw/Ting/Vedanta/wiki/OpenSpec-20-openbao-forge-identity-lifecycle). The later ratified [OpenSpec 61](https://jo.et0.pw/Ting/Ting/wiki/OpenSpec-61-forge-identity-lifecycle-contract) also requires a Forgejo native adapter, but no current Session leaf owns it; that structural gap is carried by #20 Q1 rather than by silently broadening this record. **Clarification:** rotation mints a successor; caller-selected grace leaves the old credential valid until explicitly invalidated. Invalidating unknown or already-invalid credentials succeeds externally while the audit trail retains the distinction. **Larandar:** no API-token ownership decision remains on this record.
larandar changed title from wave-1 B5/D1: mint_api_token / rotate_api_token in the kanidm effector to Kanidm effector: bounded mint, successor rotation, and token-ID invalidation 2026-08-29 17:07:55 +00:00
larandar changed title from Kanidm effector: bounded mint, successor rotation, and token-ID invalidation to Implement bounded Kanidm credential mutations 2026-08-29 19:53:26 +00:00
Owner

Delivered by PR #27, merged 2026-09-02, which carried Closes #8 and landed src/kanidm.rs with 10 capture-double tests — bounded mint with typed result metadata, successor rotation with caller-selected grace, exact token-ID invalidation with the observed-before distinction, and terminal unrelated-subject denial.

The Closes keyword did not fire on merge for this record, nor for #23 or #24, while #12, #21 and #22 closed normally. Closing by hand against the merge rather than leaving three delivered Deliverables reading as open work.

The live narrow-manager proof remains flake-ops#123, per this record's own delivery class — that was never this issue's to close.

Delivered by [PR #27](https://jo.et0.pw/Ting/Vedanta/pulls/27), merged 2026-09-02, which carried `Closes #8` and landed `src/kanidm.rs` with 10 capture-double tests — bounded mint with typed result metadata, successor rotation with caller-selected grace, exact token-ID invalidation with the observed-before distinction, and terminal unrelated-subject denial. The `Closes` keyword did not fire on merge for this record, nor for [#23](https://jo.et0.pw/Ting/Vedanta/issues/23) or [#24](https://jo.et0.pw/Ting/Vedanta/issues/24), while #12, #21 and #22 closed normally. Closing by hand against the merge rather than leaving three delivered Deliverables reading as open work. The live narrow-manager proof remains [flake-ops#123](https://jo.et0.pw/lar.ad/flake-ops/issues/123), per this record's own delivery class — that was never this issue's to close.
Owner

Dependency on flake-ops#123 removed (freeholder direction, 2026-09-03), and this record closed.

The edge asserted a blocker this record's own scope disclaims. Its delivery class reads "agent-unit — add src/kanidm.rs and capture-double tests. The live narrow-manager proof remains flake-ops #123" — the proof is named as a separate record, not as a precondition — and PR #27 merged carrying Closes #8. Two independent statements that the agent-unit work is complete, against one triage edge from 2026-08-13 that predates both.

The proof is not cancelled, only unlinked. flake-ops#123 stays open and Status/Blocked, behind flake-ops#98just bootstrap vedanta-token, an owner act with no undo that revokes every live idm_admin session. Until that runs, sa-vedanta does not exist and the narrow delegation is unproven against a live directory. What closing this record says is that src/kanidm.rs is written and tested, not that the authority it assumes has been demonstrated.

The same edge blocked #23, #24 and #9 transitively; all four close together.

**Dependency on [flake-ops#123](https://jo.et0.pw/lar.ad/flake-ops/issues/123) removed** (freeholder direction, 2026-09-03), and this record closed. The edge asserted a blocker this record's own scope disclaims. Its delivery class reads *"`agent-unit` — add `src/kanidm.rs` and capture-double tests. **The live narrow-manager proof remains flake-ops #123**"* — the proof is named as a separate record, not as a precondition — and [PR #27](https://jo.et0.pw/Ting/Vedanta/pulls/27) merged carrying `Closes #8`. Two independent statements that the agent-unit work is complete, against one triage edge from 2026-08-13 that predates both. **The proof is not cancelled, only unlinked.** flake-ops#123 stays open and `Status/Blocked`, behind [flake-ops#98](https://jo.et0.pw/lar.ad/flake-ops/issues/98) — `just bootstrap vedanta-token`, an owner act with no undo that revokes every live `idm_admin` session. Until that runs, `sa-vedanta` does not exist and the narrow delegation is unproven against a live directory. What closing this record says is that `src/kanidm.rs` is written and tested, not that the authority it assumes has been demonstrated. The same edge blocked [#23](https://jo.et0.pw/Ting/Vedanta/issues/23), [#24](https://jo.et0.pw/Ting/Vedanta/issues/24) and [#9](https://jo.et0.pw/Ting/Vedanta/issues/9) transitively; all four close together.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
Ting/Vedanta#8
No description provided.