pub struct Entry {Show 19 fields
pub seq: u64,
pub ts_ms: u64,
pub subject_type: String,
pub subject_id: String,
pub action: String,
pub resource_type: String,
pub resource_id: String,
pub context: Value,
pub decision: bool,
pub reasons: Vec<String>,
pub edge: EdgeType,
pub sponsor: Option<Party>,
pub sponsor_source: SponsorSource,
pub mission: Option<MissionRef>,
pub decision_subject: Option<DecisionSubject>,
pub asserted_by: Option<AssertedBy>,
pub notice_required: bool,
pub challenge: Option<ChallengeRecord>,
pub digests: BTreeMap<String, String>,
}Expand description
One record in the ledger: a decision — “what happened, with everything needed to replay it”. Several fields below are reserved and inert (see each field’s note): no shipped path sets them, they are retained only for struct/type stability, and a plain decision leaves them at their defaults, which serialize to no bytes — so every existing writer and stored line is unchanged.
Fields§
§seq: u64§ts_ms: u64§subject_type: String§subject_id: String§action: String§resource_type: String§resource_id: String§context: Value§decision: bool§reasons: Vec<String>§edge: EdgeTypeRFC 8785 SHA-256 digest of the parameters a decision was made over — binds a
record to the EXACT arguments, closing the TOCTOU gap between “authorized”
and “executed”. Set by decern-serve on decide / mission transitions.
The authority-graph edge type: Attenuate (default, omitted) = offline
narrowing WITHIN the delegator’s namespace (a decern tenant); Mint = a
trusted-issuer crossing that no offline delegate can produce. Reserved and
inert: never set by any shipped path, defaulted and
skipped-when-default, so existing records’ bytes and hashes are unchanged.
sponsor: Option<Party>The accountable-owner — who stands behind subject_id existing and
acting AT ALL. Resolved server-side from the directory’s delegation chain —
never a decision input (stripped before the kernel) and safe to store in the
clear: it names a principal already visible elsewhere in the same tenant’s
directory, not third-party PII — EXCEPT for a self-sponsored root principal,
where this equals subject_id verbatim. None on every record before this
field existed, and on any subject the directory doesn’t recognize (e.g. a
global/static-token caller) — existing bytes and hashes are unchanged.
sponsor_source: SponsorSourceWhether sponsor above was computed (Derived, the default — the pure
root of the delegation chain) or set by an admin override, constrained
to that same chain. Lets an auditor tell asserted from computed without
re-deriving it. Default + skipped-when-default, so existing records’
bytes and hashes are unchanged.
mission: Option<MissionRef>The Mission that justified this decision, when decide ran under a live
approval. None when no mission was bound (or on pre-mission records).
decision_subject: Option<DecisionSubject>The party the decision is about — the one it is taken upon, distinct
from the acting subject_id and from the accountable sponsor.
Descriptive, never an authorization input. Present only when that party
is a third party: a decision about the requester, or about the owner of
the resource named, carries none, because the record already says so.
asserted_by: Option<AssertedBy>The caller the server verified when it took this request — who ASSERTED the
subject, distinct from the subject itself and from the accountable sponsor.
Present only under bearer validation, where it is what the token proved, on
decision records and mission lifecycle records (Mission.Approve, Mission.Terminate).
Absent under a trusted front: an assertion the server did not verify itself does not
belong on a permanent record. Descriptive, never a decision input.
The token’s sub is written verbatim, permanently, and the subject-side
projection returns whole records — so front service identities here, not
end-user tokens: a person’s identifier in sub becomes visible to anyone
holding a decision-subject handle on the same record, and cannot be redacted
after the fact.
notice_required: boolWhether this decision is one an affected party should be told about. Recorded, not acted on: telling them is the job of whoever enforces the decision, and this server does not enforce. Recording it is what makes a notice that never went out a gap someone can point at rather than a thing nobody can prove either way.
challenge: Option<ChallengeRecord>A challenge from the party this decision was about, and how it was answered.
digests: BTreeMap<String, String>Digests of the things this record was bound to, by name.
DIGEST_PARAMETERS binds the arguments a decision authorized. This binds
everything else worth pinning, without a new column each time something is: a
consumer of this crate records what its own decisions depend on under names it
chooses, and a reader who does not know a name can still see that something was
pinned and that it does not match.
decern-serve writes DIGEST_AUTHORITY. The chain already proves a record was
not altered afterwards; it says nothing about what the record was decided
against, and that moves. Revoke a delegation tomorrow and an allow recorded today
still reads as an allow, with nothing to say what was true when — the trail is
immutable while the thing it refers to is not. A digest of the authority state
makes the decision addressable: a later reading can tell whether the authority it
was taken against is still the same one.
Ordered, so the serialization is deterministic — this is inside the bytes the chain hashes, and a map that serialized in a different order each time would break it. Values are digests, not content: whatever is being pinned may be large, may be about a person, and cannot be taken back out of an append-only log.