Repository navigation
Mandate 0.9.0
Wave 8: the second half of agent security. An execution-bound delegation is decided instead of
refused, a workload runtime and the application agent it runs are authenticated each on its own,
the second check after an approval-required decision consumes the approval, and the control
plane decides delegated requests over the delegations it recorded. One security review covered
the wave.
Added
mandate.authorization.CheckWithApproval.mandate_authz::check_with_approvaldecides the
request throughcheck's own path; an approval-required result is cleared by the named
approval when it is recorded, of the verified organization, unexpired, and names this subject,
actor, action and resource. Any mismatch refuses like an unknown approval and consumes nothing;
a consumed one iswrong-state; a deny or a reauthentication requirement stands. The new
eventApprovedDecisionRecordedrecords the decision and the consumption together, and the
delegation fold applies it as the approval's consume.Checkitself is unchanged.mandate.workload.AuthenticateWorkload.mandate_authz::workloadverifies a workload proof
behind a trust-domain port, resolves it to one recorded workload identity (the runtime), and
authenticates the application agent separately: a recorded, unretired agent of that
organization with a standing principal, never derived from the proof. A named execution must
be open and the agent's. Every refusal is onemandate.workload.Denied. The event
WorkloadAuthenticatedcarries the runtime and the agent as two principals. No SPIFFE verifier
ships yet; the port takes one.
Changed
- Execution-bound delegations are decided.
CheckandCreateDelegationshare one rule: the
bound execution is recorded, unexpired and not completed, of the delegation's organization,
held by the delegate, and names no subject or the delegator and no delegation or this one. A
bound delegation refuses a call naming no execution or another one. Every failure refuses like
an unrecorded execution. An unbound delegation keeps the stricter rule of 0.8.0. - Breaking. The control plane's decision point holds the fold of the recorded
mandate.delegationevents instead of the empty read:Admittinggainsdelegations()and
record_delegation,Deploymentgainsrecord_delegation,delegationsandadmit, and
recording without a decision point refuses withDelegationUnrecorded. - Breaking.
mandate_model::workload::WorkloadIdentityReadgainsbindings, the lookup by
trust domain and external subject. - The obligations registry files an implemented command with the crate the coverage manifest
names as its implementer, so a command decided outside its domain's crate is admitted. - A branch or tag cut from a GitHub merge of
mainneeds no Gates baseline move.