Execute runtime credentials for declared identity promotion #18
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Meta/Campaign
Meta/Epic
Meta/Session
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
Reviewed/Confirmed
Reviewed/Curated
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Scope/Campaign
Status/Abandoned
Status/Blocked
Status/Conflicted
Status/In Progress
Status/In Review
Status/Need Grooming
Status/Need More Info
Status/Ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Blocks
Depends on
#8 Implement bounded Kanidm credential mutations
Ting/Vedanta
You do not have permission to read 1 dependency
Reference
Ting/Vedanta#18
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Proposal
Vedanta's optional runtime executor for a promotion that flake-ops has already declared and a NixOps4 provider has already applied: mint the workflow-time credential that reflects the new authority.
Delivery class
agent-unit— a gated runtime path with capture doubles. It reusessrc/kanidm.rs's bounded mutations rather than growing new ones.Design
This record is a duplicate, deliberately, and must never be the only implementation. The provider (nixops4-providers#25) is the required path for declared identity and role state. What Vedanta adds is workflow-time immediacy: a running workflow that needs a credential reflecting a promotion should not wait for the next apply.
Gated twice, and the second gate is the load-bearing one. It acts only on a declared promotion, and only after the provider-observed projection shows it applied. Gating on the declaration alone would make Vedanta decide what the declaration meant — which is the provider's job — and would let a runtime credential exist for an authority the directory has not actually granted.
Bounded to credentials. It invalidates the prior short-lived workflow JWT and mints a fresh one carrying only the declared promoted authority. It creates no directory state, changes no role, and touches no durable principal — those are the provider's, and Vedanta's law forbids it either way.
Not the pool's path. This is a durable stable identity being promoted, not a pool slot being allocated.
src/pool.rsandsrc/checkout.rsare not involved.Tasks
Specification Delta
Requirement: a runtime promotion follows the provider, never leads it
Scenario: the declaration exists but the provider has not converged
Requirement: the runtime path touches credentials only
Scenario: a runtime promotion succeeds
OpenSpec
OpenSpec 85
Structural parent
Ting/Ting#86 — Epic: promotion.
Re-pointed by the 2026-09-04 restructure of the promotion path.
This record is now a Deliverable under Ting/Ting#86, not a Session. The
Meta/Sessionlabel is removed.Three freeholder rulings moved it here:
Ting/Vedantafor the estate tracker (Ting/Ting#85). It spans three repositories and Vedanta holds the optional half.What to build against: OpenSpec 85, not this body. This record predates the package and has not yet been refined to project it — that refinement is the next pass, and until it runs the body here is provenance rather than instruction.
Refinement against OpenSpec 85 — the pass this record was told to wait for
The body predates the package. This projects it, and answers the one question the body leaves open.
Q1 — what "the provider-observed projection" is, concretely
The body gates on it twice and never says how Vedanta reads it. It cannot read nixops4's state: that file lives on whichever operator's machine ran the apply, and Vedanta is a service on another host.
Proposed: the gate is what the DIRECTORY shows, read by Vedanta itself.
This is not a substitute for the provider's projection — it is it.
nixops-kanidmpublishes outputs read back from kanidm after the write, never the declared values (nixops4-providers#44 states that as its own rule, for exactly this reason: an output that echoed the declaration would report success for a write the directory refused). So "what the provider observed" and "what the directory holds" are the same fact by construction, and only one of the two requires coupling Vedanta to a deployment tool it does not run.It is also the stronger gate. A state file records what a tool believed at apply time; the directory is the thing authority is actually read from. If they disagree, the directory is right and the state file is drift — which is #11's to notice, not this endpoint's to trust.
Concretely: the promotion is observed when the declared uuid is a member of the declared role group, read from kanidm at call time.
Q2 — what the gate is NOT
Not "a declaration exists". Not "an apply ran". Membership, now, for that uuid. A declaration the provider has not converged leaves the directory unchanged, and this endpoint must refuse against the directory rather than against a record of intent.
Unchanged
Bounded to credentials; no directory entity, role, or membership altered; not the pool's path. Those hold as written.
Delivery
Building with #19 in one PR — Vedanta's law is one PR per session, and the two share the gate. Two PRs would carry two copies of it.