agent-passport-system 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/tool-integrity.d.ts +13 -0
- package/dist/src/core/tool-integrity.d.ts.map +1 -1
- package/dist/src/core/tool-integrity.js +1 -1
- package/dist/src/core/tool-integrity.js.map +1 -1
- package/dist/src/index.d.ts +28 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +242 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/v2/activation/canonical.d.ts +40 -0
- package/dist/src/v2/activation/canonical.d.ts.map +1 -0
- package/dist/src/v2/activation/canonical.js +64 -0
- package/dist/src/v2/activation/canonical.js.map +1 -0
- package/dist/src/v2/activation/index.d.ts +4 -0
- package/dist/src/v2/activation/index.d.ts.map +1 -0
- package/dist/src/v2/activation/index.js +11 -0
- package/dist/src/v2/activation/index.js.map +1 -0
- package/dist/src/v2/activation/types.d.ts +268 -0
- package/dist/src/v2/activation/types.d.ts.map +1 -0
- package/dist/src/v2/activation/types.js +198 -0
- package/dist/src/v2/activation/types.js.map +1 -0
- package/dist/src/v2/activation/verify.d.ts +132 -0
- package/dist/src/v2/activation/verify.d.ts.map +1 -0
- package/dist/src/v2/activation/verify.js +406 -0
- package/dist/src/v2/activation/verify.js.map +1 -0
- package/dist/src/v2/authority-state/fencing.d.ts +49 -0
- package/dist/src/v2/authority-state/fencing.d.ts.map +1 -0
- package/dist/src/v2/authority-state/fencing.js +92 -0
- package/dist/src/v2/authority-state/fencing.js.map +1 -0
- package/dist/src/v2/authority-state/index.d.ts +7 -0
- package/dist/src/v2/authority-state/index.d.ts.map +1 -0
- package/dist/src/v2/authority-state/index.js +14 -0
- package/dist/src/v2/authority-state/index.js.map +1 -0
- package/dist/src/v2/authority-state/marker.d.ts +70 -0
- package/dist/src/v2/authority-state/marker.d.ts.map +1 -0
- package/dist/src/v2/authority-state/marker.js +122 -0
- package/dist/src/v2/authority-state/marker.js.map +1 -0
- package/dist/src/v2/authority-state/report.d.ts +55 -0
- package/dist/src/v2/authority-state/report.d.ts.map +1 -0
- package/dist/src/v2/authority-state/report.js +51 -0
- package/dist/src/v2/authority-state/report.js.map +1 -0
- package/dist/src/v2/authority-state/retained.d.ts +82 -0
- package/dist/src/v2/authority-state/retained.d.ts.map +1 -0
- package/dist/src/v2/authority-state/retained.js +93 -0
- package/dist/src/v2/authority-state/retained.js.map +1 -0
- package/dist/src/v2/authority-state/types.d.ts +198 -0
- package/dist/src/v2/authority-state/types.d.ts.map +1 -0
- package/dist/src/v2/authority-state/types.js +103 -0
- package/dist/src/v2/authority-state/types.js.map +1 -0
- package/dist/src/v2/authority-state/withdrawal.d.ts +80 -0
- package/dist/src/v2/authority-state/withdrawal.d.ts.map +1 -0
- package/dist/src/v2/authority-state/withdrawal.js +199 -0
- package/dist/src/v2/authority-state/withdrawal.js.map +1 -0
- package/dist/src/v2/bounds/canonical.d.ts +30 -0
- package/dist/src/v2/bounds/canonical.d.ts.map +1 -0
- package/dist/src/v2/bounds/canonical.js +69 -0
- package/dist/src/v2/bounds/canonical.js.map +1 -0
- package/dist/src/v2/bounds/evaluate.d.ts +107 -0
- package/dist/src/v2/bounds/evaluate.d.ts.map +1 -0
- package/dist/src/v2/bounds/evaluate.js +315 -0
- package/dist/src/v2/bounds/evaluate.js.map +1 -0
- package/dist/src/v2/bounds/index.d.ts +6 -0
- package/dist/src/v2/bounds/index.d.ts.map +1 -0
- package/dist/src/v2/bounds/index.js +13 -0
- package/dist/src/v2/bounds/index.js.map +1 -0
- package/dist/src/v2/bounds/purpose.d.ts +2 -0
- package/dist/src/v2/bounds/purpose.d.ts.map +1 -0
- package/dist/src/v2/bounds/purpose.js +23 -0
- package/dist/src/v2/bounds/purpose.js.map +1 -0
- package/dist/src/v2/bounds/record.d.ts +78 -0
- package/dist/src/v2/bounds/record.d.ts.map +1 -0
- package/dist/src/v2/bounds/record.js +170 -0
- package/dist/src/v2/bounds/record.js.map +1 -0
- package/dist/src/v2/bounds/types.d.ts +275 -0
- package/dist/src/v2/bounds/types.d.ts.map +1 -0
- package/dist/src/v2/bounds/types.js +124 -0
- package/dist/src/v2/bounds/types.js.map +1 -0
- package/dist/src/v2/capability-binding/binding.d.ts +67 -0
- package/dist/src/v2/capability-binding/binding.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/binding.js +267 -0
- package/dist/src/v2/capability-binding/binding.js.map +1 -0
- package/dist/src/v2/capability-binding/digest.d.ts +33 -0
- package/dist/src/v2/capability-binding/digest.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/digest.js +55 -0
- package/dist/src/v2/capability-binding/digest.js.map +1 -0
- package/dist/src/v2/capability-binding/identifier.d.ts +103 -0
- package/dist/src/v2/capability-binding/identifier.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/identifier.js +281 -0
- package/dist/src/v2/capability-binding/identifier.js.map +1 -0
- package/dist/src/v2/capability-binding/index.d.ts +6 -0
- package/dist/src/v2/capability-binding/index.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/index.js +13 -0
- package/dist/src/v2/capability-binding/index.js.map +1 -0
- package/dist/src/v2/capability-binding/pins.d.ts +30 -0
- package/dist/src/v2/capability-binding/pins.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/pins.js +109 -0
- package/dist/src/v2/capability-binding/pins.js.map +1 -0
- package/dist/src/v2/capability-binding/types.d.ts +213 -0
- package/dist/src/v2/capability-binding/types.d.ts.map +1 -0
- package/dist/src/v2/capability-binding/types.js +150 -0
- package/dist/src/v2/capability-binding/types.js.map +1 -0
- package/dist/src/v2/chain-selection/index.d.ts +4 -0
- package/dist/src/v2/chain-selection/index.d.ts.map +1 -0
- package/dist/src/v2/chain-selection/index.js +11 -0
- package/dist/src/v2/chain-selection/index.js.map +1 -0
- package/dist/src/v2/chain-selection/select.d.ts +62 -0
- package/dist/src/v2/chain-selection/select.d.ts.map +1 -0
- package/dist/src/v2/chain-selection/select.js +390 -0
- package/dist/src/v2/chain-selection/select.js.map +1 -0
- package/dist/src/v2/chain-selection/types.d.ts +189 -0
- package/dist/src/v2/chain-selection/types.d.ts.map +1 -0
- package/dist/src/v2/chain-selection/types.js +81 -0
- package/dist/src/v2/chain-selection/types.js.map +1 -0
- package/dist/src/v2/lifecycle-state/index.d.ts +4 -0
- package/dist/src/v2/lifecycle-state/index.d.ts.map +1 -0
- package/dist/src/v2/lifecycle-state/index.js +10 -0
- package/dist/src/v2/lifecycle-state/index.js.map +1 -0
- package/dist/src/v2/lifecycle-state/map.d.ts +52 -0
- package/dist/src/v2/lifecycle-state/map.d.ts.map +1 -0
- package/dist/src/v2/lifecycle-state/map.js +122 -0
- package/dist/src/v2/lifecycle-state/map.js.map +1 -0
- package/dist/src/v2/lifecycle-state/state.d.ts +60 -0
- package/dist/src/v2/lifecycle-state/state.d.ts.map +1 -0
- package/dist/src/v2/lifecycle-state/state.js +157 -0
- package/dist/src/v2/lifecycle-state/state.js.map +1 -0
- package/dist/src/v2/lifecycle-state/types.d.ts +163 -0
- package/dist/src/v2/lifecycle-state/types.d.ts.map +1 -0
- package/dist/src/v2/lifecycle-state/types.js +121 -0
- package/dist/src/v2/lifecycle-state/types.js.map +1 -0
- package/dist/src/v2/status-coverage/decide.d.ts +52 -0
- package/dist/src/v2/status-coverage/decide.d.ts.map +1 -0
- package/dist/src/v2/status-coverage/decide.js +398 -0
- package/dist/src/v2/status-coverage/decide.js.map +1 -0
- package/dist/src/v2/status-coverage/index.d.ts +3 -0
- package/dist/src/v2/status-coverage/index.d.ts.map +1 -0
- package/dist/src/v2/status-coverage/index.js +10 -0
- package/dist/src/v2/status-coverage/index.js.map +1 -0
- package/dist/src/v2/status-coverage/types.d.ts +258 -0
- package/dist/src/v2/status-coverage/types.d.ts.map +1 -0
- package/dist/src/v2/status-coverage/types.js +127 -0
- package/dist/src/v2/status-coverage/types.js.map +1 -0
- package/dist/src/v2/suspension/evaluate.d.ts +88 -0
- package/dist/src/v2/suspension/evaluate.d.ts.map +1 -0
- package/dist/src/v2/suspension/evaluate.js +404 -0
- package/dist/src/v2/suspension/evaluate.js.map +1 -0
- package/dist/src/v2/suspension/index.d.ts +3 -0
- package/dist/src/v2/suspension/index.d.ts.map +1 -0
- package/dist/src/v2/suspension/index.js +10 -0
- package/dist/src/v2/suspension/index.js.map +1 -0
- package/dist/src/v2/suspension/types.d.ts +243 -0
- package/dist/src/v2/suspension/types.d.ts.map +1 -0
- package/dist/src/v2/suspension/types.js +135 -0
- package/dist/src/v2/suspension/types.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type { AuthorityRevocationV1 } from '../authority-revocation/types.js';
|
|
2
|
+
/** What a marker is counted within. Comparing two markers from different scopes orders
|
|
3
|
+
* nothing, so the comparison reports `unplaceable` rather than inventing an order.
|
|
4
|
+
*
|
|
5
|
+
* The proposed text names none of these. They exist because the fixture that forced this
|
|
6
|
+
* module had to pick one (it picked a global integer on a state view) and recorded that
|
|
7
|
+
* the choice was not read from the text. Carrying the scope makes that choice visible in
|
|
8
|
+
* the record instead of implicit in the deployment. Proposed. */
|
|
9
|
+
export declare const STATE_MARKER_SCOPES: readonly ['global', 'per_delegation', 'per_principal', 'per_store'];
|
|
10
|
+
export type StateMarkerScope = (typeof STATE_MARKER_SCOPES)[number];
|
|
11
|
+
/** A monotonic generation marker on authority state.
|
|
12
|
+
*
|
|
13
|
+
* `value` is a canonical unsigned decimal integer, the same convention the seven-facet
|
|
14
|
+
* authority vector already uses for spend quantities: no sign, no leading zero, no
|
|
15
|
+
* separators, arbitrary width. It is a string rather than a number so a marker past
|
|
16
|
+
* 2^53 - 1 stays exact, and it is compared as an integer, never lexically.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here is signed and nothing here is a wire field. No delegation, revocation or
|
|
19
|
+
* store in this SDK carries a marker, and none is being given one: a marker is state the
|
|
20
|
+
* caller has about a state source, handed in at comparison time. Proposed. */
|
|
21
|
+
export interface StateMarker {
|
|
22
|
+
readonly value: string;
|
|
23
|
+
readonly scope: StateMarkerScope;
|
|
24
|
+
/** Which delegation, principal or store this marker is counted within. Required on every
|
|
25
|
+
* scope except `global`, where it is absent. */
|
|
26
|
+
readonly scope_ref?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The result of placing a presented marker against what a verifier has established.
|
|
29
|
+
*
|
|
30
|
+
* - `forward` the presented marker advanced, or held equal. Read the view normally.
|
|
31
|
+
* - `regressed` the presented marker went backwards against an established high-water
|
|
32
|
+
* mark. CAND-08's refusal case.
|
|
33
|
+
* - `unplaceable` there is nothing to compare against, or the two markers are counted in
|
|
34
|
+
* different scopes. **Deliberately not a verdict.** A high-water mark has
|
|
35
|
+
* to start somewhere and neither the proposed text nor draft-03 says
|
|
36
|
+
* whether a first read is trusted or refused. Both are defensible and the
|
|
37
|
+
* outcomes differ, so this module reports the fact and the caller
|
|
38
|
+
* decides. See `UnplaceableDisposition`. */
|
|
39
|
+
export declare const MONOTONICITY_OUTCOMES: readonly ['forward', 'regressed', 'unplaceable'];
|
|
40
|
+
export type MonotonicityOutcome = (typeof MONOTONICITY_OUTCOMES)[number];
|
|
41
|
+
/** What a caller wants done with an `unplaceable` presented view. Required, with no
|
|
42
|
+
* default, because the SDK picking one would be the SDK deciding a question its own
|
|
43
|
+
* concept source records as undecided. */
|
|
44
|
+
export declare const UNPLACEABLE_DISPOSITIONS: readonly ['read_presented', 'refuse'];
|
|
45
|
+
export type UnplaceableDisposition = (typeof UNPLACEABLE_DISPOSITIONS)[number];
|
|
46
|
+
/** What a verifier has established about authority state, as TWO separate inputs.
|
|
47
|
+
*
|
|
48
|
+
* Splitting them is the whole point of this type. Two verifiers can hold the same
|
|
49
|
+
* high-water mark and give different answers about the same restored view: the one that
|
|
50
|
+
* retained the revocation records it observed can establish a revocation from records and
|
|
51
|
+
* answers `revoked`, and the one that retained only the number cannot, and answers
|
|
52
|
+
* `unknown`, which draft-03 section 3.3 makes indeterminate. The proposed text does not
|
|
53
|
+
* distinguish those two verifiers at all, and the distinction turns out to be the
|
|
54
|
+
* substance of the rollback question. An API taking "the epoch" as one value cannot
|
|
55
|
+
* express it.
|
|
56
|
+
*
|
|
57
|
+
* `records` is not a store and does not behave like one. It can answer `revoked` and it
|
|
58
|
+
* can answer `unknown`. It can never answer `active`: a retained record set says nothing
|
|
59
|
+
* about the delegations it does not mention, which is the same reason absence from an
|
|
60
|
+
* `AuthorityRevocationStore` is `unknown` rather than `active`. */
|
|
61
|
+
export interface RetainedAuthorityState {
|
|
62
|
+
/** Revocation records the verifier retained at its high-water mark. Each is re-verified
|
|
63
|
+
* against the delegation in front of it before it can produce a `revoked` answer, so a
|
|
64
|
+
* record that reached this array by some other route still cannot assert one. */
|
|
65
|
+
readonly records: readonly AuthorityRevocationV1[];
|
|
66
|
+
/** The newest marker this verifier has established, or `null` if it has established
|
|
67
|
+
* none. */
|
|
68
|
+
readonly highWaterMark: StateMarker | null;
|
|
69
|
+
}
|
|
70
|
+
/** Why a fenced write was refused.
|
|
71
|
+
*
|
|
72
|
+
* - `stale_fencing_token` the token went backwards against the highest already seen.
|
|
73
|
+
* The only one of the three the source states.
|
|
74
|
+
* - `fencing_scope_mismatch` the token is counted in a different scope from the log's, so
|
|
75
|
+
* it cannot be ordered against what the log holds.
|
|
76
|
+
* - `fencing_token_unreadable` the token is absent or not a well-formed `StateMarker`.
|
|
77
|
+
*
|
|
78
|
+
* A write path that cannot order a token is not fenced, so the second and third refuse
|
|
79
|
+
* rather than guess. Neither is in any source; both are this module's choice. */
|
|
80
|
+
export declare const FENCED_WRITE_REFUSAL_CODES: readonly ['stale_fencing_token', 'fencing_scope_mismatch', 'fencing_token_unreadable'];
|
|
81
|
+
export type FencedWriteRefusalCode = (typeof FENCED_WRITE_REFUSAL_CODES)[number];
|
|
82
|
+
/** An authority-state write carrying the token of whoever claims to be the current
|
|
83
|
+
* publisher. */
|
|
84
|
+
export interface FencedWrite<T> {
|
|
85
|
+
readonly token: StateMarker;
|
|
86
|
+
readonly payload: T;
|
|
87
|
+
}
|
|
88
|
+
/** What a fenced log reports about one write.
|
|
89
|
+
*
|
|
90
|
+
* An EQUAL token is accepted, and that is not an oversight. The rule the source states is
|
|
91
|
+
* about tokens going backwards, and an equal token has not gone backwards: it is the same
|
|
92
|
+
* holder retrying, which makes a retry idempotent. */
|
|
93
|
+
export type FencedWriteOutcome<T> = {
|
|
94
|
+
readonly accepted: true;
|
|
95
|
+
readonly published: StateMarker;
|
|
96
|
+
readonly payload: T;
|
|
97
|
+
} | {
|
|
98
|
+
readonly accepted: false;
|
|
99
|
+
readonly code: FencedWriteRefusalCode;
|
|
100
|
+
readonly published: StateMarker | null;
|
|
101
|
+
};
|
|
102
|
+
/** The record type a withdrawal carries.
|
|
103
|
+
*
|
|
104
|
+
* `proposed:` is load-bearing. Record fields, failure-class names and verifier semantics
|
|
105
|
+
* are conformance vocabulary reserved to the maintainer, and neither draft-03 nor the
|
|
106
|
+
* proposed text defines a record for withdrawing a recorded revocation or says what a
|
|
107
|
+
* verifier should do with one. This is a placeholder to argue about, not APS vocabulary. */
|
|
108
|
+
export declare const REVOCATION_WITHDRAWAL_RECORD_TYPE: 'proposed:aps:revocation-withdrawal:v0';
|
|
109
|
+
export declare const REVOCATION_WITHDRAWAL_VERSION: '0';
|
|
110
|
+
/** A record stating that a recorded revocation was published in error.
|
|
111
|
+
*
|
|
112
|
+
* It REFERENCES the revocation and never removes it. Inside an `AuthorityRevocationStore`
|
|
113
|
+
* irreversibility is already structural: the store exposes `track`, `tracks`, `get` and
|
|
114
|
+
* `insertVerifiedRevocation`, there is no removal method, and this module does not add
|
|
115
|
+
* one. Draft-03 section 3.5 states "Revocation is irreversible", and a removal method
|
|
116
|
+
* would be one call away from breaking it.
|
|
117
|
+
*
|
|
118
|
+
* NOT AUTHENTICATED BY THIS MODULE. There is no canonical preimage here, no signature
|
|
119
|
+
* field, and no verification function, deliberately: minting the signed form of a record
|
|
120
|
+
* type is the vocabulary decision this module is not entitled to make. A caller hands in a
|
|
121
|
+
* withdrawal it has already authenticated, exactly as `insertVerifiedRevocation` takes a
|
|
122
|
+
* revocation `recordAuthorityRevocation` has already verified. Whoever reaches
|
|
123
|
+
* `evaluateRevocationWithdrawal` is the party asserting the record is genuine. */
|
|
124
|
+
export interface RevocationWithdrawalV0 {
|
|
125
|
+
readonly record_type: typeof REVOCATION_WITHDRAWAL_RECORD_TYPE;
|
|
126
|
+
readonly version: typeof REVOCATION_WITHDRAWAL_VERSION;
|
|
127
|
+
/** The revocation this record withdraws: `sha256:<64 lowercase hex>`. */
|
|
128
|
+
readonly revocation_id: string;
|
|
129
|
+
/** The delegation that revocation named. Carried so a withdrawal that names a revocation
|
|
130
|
+
* of a different delegation is refusable without a second lookup. */
|
|
131
|
+
readonly delegation_id: string;
|
|
132
|
+
/** Who states the withdrawal. Whether this party may is NOT decided here. */
|
|
133
|
+
readonly withdrawn_by: string;
|
|
134
|
+
/** Canonical UTC-millisecond time, supplied by the caller, never read from a clock. */
|
|
135
|
+
readonly withdrawn_at: string;
|
|
136
|
+
/** Machine-readable ground. No grammar is fixed for one and none is invented here. */
|
|
137
|
+
readonly reason_code: string;
|
|
138
|
+
/** OPTIONAL free-text detail. Absent means the key is not present at all. */
|
|
139
|
+
readonly detail?: string;
|
|
140
|
+
}
|
|
141
|
+
/** What an injected standing resolver may answer.
|
|
142
|
+
*
|
|
143
|
+
* `unknown` is a first-class answer and is not `no_standing`. A verifier that cannot
|
|
144
|
+
* establish whether the withdrawer had standing has not established that they lacked it,
|
|
145
|
+
* and the refusal reason says which of the two happened. */
|
|
146
|
+
export declare const WITHDRAWAL_STANDINGS: readonly ['has_standing', 'no_standing', 'unknown'];
|
|
147
|
+
export type WithdrawalStanding = (typeof WITHDRAWAL_STANDINGS)[number];
|
|
148
|
+
/** Decides whether a withdrawal's author may withdraw this revocation.
|
|
149
|
+
*
|
|
150
|
+
* Injected, never hardcoded, and never read from the withdrawal record itself. Draft-03
|
|
151
|
+
* section 3.5 states "Any delegation MAY be revoked by its issuer" and the SDK enforces
|
|
152
|
+
* `revoker === issuer` for a revocation. Nothing anywhere states who may WITHDRAW one.
|
|
153
|
+
* `withdrawalSignerIsRevoker` is supplied as one resolver, is what the forcing fixture
|
|
154
|
+
* chose, and is a choice rather than a rule read from any text. */
|
|
155
|
+
export type WithdrawalStandingResolver = (withdrawal: RevocationWithdrawalV0, revocation: AuthorityRevocationV1) => WithdrawalStanding;
|
|
156
|
+
/** Why a withdrawal was accepted or refused. Stable, module-local codes. */
|
|
157
|
+
export declare const WITHDRAWAL_OUTCOME_CODES: readonly [
|
|
158
|
+
/** Accepted as a record. Accepted never means the revocation is gone. */
|
|
159
|
+
'WITHDRAWAL_ACCEPTED',
|
|
160
|
+
/** The record is not a well-formed `RevocationWithdrawalV0`. */
|
|
161
|
+
'WITHDRAWAL_SCHEMA_INVALID',
|
|
162
|
+
/** No revocation in the held set carries the `revocation_id` this record names. */
|
|
163
|
+
'WITHDRAWAL_NAMES_NO_HELD_REVOCATION',
|
|
164
|
+
/** The named revocation exists but is a revocation of a different delegation. */
|
|
165
|
+
'WITHDRAWAL_TARGET_MISMATCH',
|
|
166
|
+
/** The resolver established that this party may not withdraw this revocation. */
|
|
167
|
+
'WITHDRAWAL_SIGNER_WITHOUT_STANDING',
|
|
168
|
+
/** The resolver could not establish standing either way. Not the same finding as the
|
|
169
|
+
* one above, and reported as `not_established` rather than as a denial. */
|
|
170
|
+
'WITHDRAWAL_STANDING_NOT_ESTABLISHED'];
|
|
171
|
+
export type WithdrawalOutcomeCode = (typeof WITHDRAWAL_OUTCOME_CODES)[number];
|
|
172
|
+
/** What `evaluateRevocationWithdrawal` concludes about one withdrawal record. */
|
|
173
|
+
export interface WithdrawalEvaluation {
|
|
174
|
+
readonly accepted: boolean;
|
|
175
|
+
readonly reason_code: WithdrawalOutcomeCode;
|
|
176
|
+
/** What the resolver answered, or `null` when evaluation refused before asking it. */
|
|
177
|
+
readonly standing: WithdrawalStanding | null;
|
|
178
|
+
/** The record evaluated, unchanged. */
|
|
179
|
+
readonly withdrawal: RevocationWithdrawalV0;
|
|
180
|
+
}
|
|
181
|
+
/** The current position of one revocation together with every withdrawal referencing it.
|
|
182
|
+
*
|
|
183
|
+
* This is CAND-02 made into a shape. The revocation is present, unchanged, whether or not
|
|
184
|
+
* a withdrawal was accepted. A later finding is a new record that references the earlier
|
|
185
|
+
* one and states its own effect; it is never an edit of the earlier one and never its
|
|
186
|
+
* removal. A verifier that must report "revoked, and the revoker later said this was
|
|
187
|
+
* recorded in error" reports exactly this. */
|
|
188
|
+
export interface CorrectedRevocationView {
|
|
189
|
+
/** The revocation record, byte for byte what it was. */
|
|
190
|
+
readonly revocation: AuthorityRevocationV1;
|
|
191
|
+
/** Accepted withdrawals, in the order supplied. Non-empty does NOT make the revocation
|
|
192
|
+
* ineffective and does NOT change any chain verdict. */
|
|
193
|
+
readonly accepted: readonly WithdrawalEvaluation[];
|
|
194
|
+
/** Refused withdrawals, each with the code saying why. A withdrawal that changes nothing
|
|
195
|
+
* in silence is indistinguishable from one that was never submitted. */
|
|
196
|
+
readonly refused: readonly WithdrawalEvaluation[];
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
//
|
|
4
|
+
// PROPOSED, OPT-IN. Authority state markers, write fencing, and withdrawal of a recorded
|
|
5
|
+
// revocation.
|
|
6
|
+
//
|
|
7
|
+
// NOT REQUIRED BY draft-pidlisnyi-aps-03. The published text contains no occurrence of
|
|
8
|
+
// `epoch`, `fencing`, `snapshot`, `replica` or `restore`, and defines no record for
|
|
9
|
+
// withdrawing a revocation. What it does fix, and what this module is careful not to
|
|
10
|
+
// disturb, is section 3.3: "Verification returns one of valid, invalid, indeterminate, or
|
|
11
|
+
// unsupported with a stable failure code", and section 3.5: "Revocation is irreversible."
|
|
12
|
+
// `AuthorityValidationState`, `AuthorityValidationResult`, `AuthorityRevocationStore` and
|
|
13
|
+
// everything `verifyAuthorityDelegationChain` returns are unchanged, and a caller that does
|
|
14
|
+
// not import this module sees exactly today's behaviour.
|
|
15
|
+
//
|
|
16
|
+
// Concept source: the aeoess/agent-authority-lifecycle concept document
|
|
17
|
+
// (AUTHORITY-LIFECYCLE.md, the `Authority epoch` concept and invariants L3, L7 and L11;
|
|
18
|
+
// OPEN-QUESTIONS.md, `Authority rollback`) and its invariant candidates CAND-08 (no silent
|
|
19
|
+
// restoration from rollback or stale state) and CAND-02 (later evidence does not rewrite
|
|
20
|
+
// earlier evidence). Every one of those is proposed, not specified. Nothing here claims
|
|
21
|
+
// otherwise, and `OPEN-QUESTIONS.md` keeps open both the mechanism and what a verifier
|
|
22
|
+
// should return after a restore.
|
|
23
|
+
//
|
|
24
|
+
// Three deliberate non-decisions are encoded as types rather than as behaviour:
|
|
25
|
+
//
|
|
26
|
+
// 1. The proposed text says an authority epoch is "where a system uses generations" and
|
|
27
|
+
// stops. It does not say who advances one, whether it is global or per delegation,
|
|
28
|
+
// whether it is signed, or what evidence carries it. `StateMarker` is therefore an
|
|
29
|
+
// opaque comparable supplied by the caller, and this module defines only the comparison.
|
|
30
|
+
// 2. A verifier with no prior observation has nothing to compare against. That is
|
|
31
|
+
// `unplaceable`, and it is not a verdict. The caller says what to do with it.
|
|
32
|
+
// 3. Who may withdraw a revocation is not stated anywhere. Standing is resolved through an
|
|
33
|
+
// injected callback and never read from the record asserting it.
|
|
34
|
+
/** What a marker is counted within. Comparing two markers from different scopes orders
|
|
35
|
+
* nothing, so the comparison reports `unplaceable` rather than inventing an order.
|
|
36
|
+
*
|
|
37
|
+
* The proposed text names none of these. They exist because the fixture that forced this
|
|
38
|
+
* module had to pick one (it picked a global integer on a state view) and recorded that
|
|
39
|
+
* the choice was not read from the text. Carrying the scope makes that choice visible in
|
|
40
|
+
* the record instead of implicit in the deployment. Proposed. */
|
|
41
|
+
export const STATE_MARKER_SCOPES = ['global', 'per_delegation', 'per_principal', 'per_store'];
|
|
42
|
+
/** The result of placing a presented marker against what a verifier has established.
|
|
43
|
+
*
|
|
44
|
+
* - `forward` the presented marker advanced, or held equal. Read the view normally.
|
|
45
|
+
* - `regressed` the presented marker went backwards against an established high-water
|
|
46
|
+
* mark. CAND-08's refusal case.
|
|
47
|
+
* - `unplaceable` there is nothing to compare against, or the two markers are counted in
|
|
48
|
+
* different scopes. **Deliberately not a verdict.** A high-water mark has
|
|
49
|
+
* to start somewhere and neither the proposed text nor draft-03 says
|
|
50
|
+
* whether a first read is trusted or refused. Both are defensible and the
|
|
51
|
+
* outcomes differ, so this module reports the fact and the caller
|
|
52
|
+
* decides. See `UnplaceableDisposition`. */
|
|
53
|
+
export const MONOTONICITY_OUTCOMES = ['forward', 'regressed', 'unplaceable'];
|
|
54
|
+
/** What a caller wants done with an `unplaceable` presented view. Required, with no
|
|
55
|
+
* default, because the SDK picking one would be the SDK deciding a question its own
|
|
56
|
+
* concept source records as undecided. */
|
|
57
|
+
export const UNPLACEABLE_DISPOSITIONS = ['read_presented', 'refuse'];
|
|
58
|
+
/** Why a fenced write was refused.
|
|
59
|
+
*
|
|
60
|
+
* - `stale_fencing_token` the token went backwards against the highest already seen.
|
|
61
|
+
* The only one of the three the source states.
|
|
62
|
+
* - `fencing_scope_mismatch` the token is counted in a different scope from the log's, so
|
|
63
|
+
* it cannot be ordered against what the log holds.
|
|
64
|
+
* - `fencing_token_unreadable` the token is absent or not a well-formed `StateMarker`.
|
|
65
|
+
*
|
|
66
|
+
* A write path that cannot order a token is not fenced, so the second and third refuse
|
|
67
|
+
* rather than guess. Neither is in any source; both are this module's choice. */
|
|
68
|
+
export const FENCED_WRITE_REFUSAL_CODES = [
|
|
69
|
+
'stale_fencing_token',
|
|
70
|
+
'fencing_scope_mismatch',
|
|
71
|
+
'fencing_token_unreadable',
|
|
72
|
+
];
|
|
73
|
+
/** The record type a withdrawal carries.
|
|
74
|
+
*
|
|
75
|
+
* `proposed:` is load-bearing. Record fields, failure-class names and verifier semantics
|
|
76
|
+
* are conformance vocabulary reserved to the maintainer, and neither draft-03 nor the
|
|
77
|
+
* proposed text defines a record for withdrawing a recorded revocation or says what a
|
|
78
|
+
* verifier should do with one. This is a placeholder to argue about, not APS vocabulary. */
|
|
79
|
+
export const REVOCATION_WITHDRAWAL_RECORD_TYPE = 'proposed:aps:revocation-withdrawal:v0';
|
|
80
|
+
export const REVOCATION_WITHDRAWAL_VERSION = '0';
|
|
81
|
+
/** What an injected standing resolver may answer.
|
|
82
|
+
*
|
|
83
|
+
* `unknown` is a first-class answer and is not `no_standing`. A verifier that cannot
|
|
84
|
+
* establish whether the withdrawer had standing has not established that they lacked it,
|
|
85
|
+
* and the refusal reason says which of the two happened. */
|
|
86
|
+
export const WITHDRAWAL_STANDINGS = ['has_standing', 'no_standing', 'unknown'];
|
|
87
|
+
/** Why a withdrawal was accepted or refused. Stable, module-local codes. */
|
|
88
|
+
export const WITHDRAWAL_OUTCOME_CODES = [
|
|
89
|
+
/** Accepted as a record. Accepted never means the revocation is gone. */
|
|
90
|
+
'WITHDRAWAL_ACCEPTED',
|
|
91
|
+
/** The record is not a well-formed `RevocationWithdrawalV0`. */
|
|
92
|
+
'WITHDRAWAL_SCHEMA_INVALID',
|
|
93
|
+
/** No revocation in the held set carries the `revocation_id` this record names. */
|
|
94
|
+
'WITHDRAWAL_NAMES_NO_HELD_REVOCATION',
|
|
95
|
+
/** The named revocation exists but is a revocation of a different delegation. */
|
|
96
|
+
'WITHDRAWAL_TARGET_MISMATCH',
|
|
97
|
+
/** The resolver established that this party may not withdraw this revocation. */
|
|
98
|
+
'WITHDRAWAL_SIGNER_WITHOUT_STANDING',
|
|
99
|
+
/** The resolver could not establish standing either way. Not the same finding as the
|
|
100
|
+
* one above, and reported as `not_established` rather than as a denial. */
|
|
101
|
+
'WITHDRAWAL_STANDING_NOT_ESTABLISHED',
|
|
102
|
+
];
|
|
103
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,yFAAyF;AACzF,cAAc;AACd,EAAE;AACF,uFAAuF;AACvF,oFAAoF;AACpF,qFAAqF;AACrF,0FAA0F;AAC1F,0FAA0F;AAC1F,0FAA0F;AAC1F,4FAA4F;AAC5F,yDAAyD;AACzD,EAAE;AACF,wEAAwE;AACxE,wFAAwF;AACxF,2FAA2F;AAC3F,yFAAyF;AACzF,wFAAwF;AACxF,uFAAuF;AACvF,iCAAiC;AACjC,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,yFAAyF;AACzF,uFAAuF;AACvF,uFAAuF;AACvF,6FAA6F;AAC7F,mFAAmF;AACnF,kFAAkF;AAClF,4FAA4F;AAC5F,qEAAqE;AAIrE;;;;;;kEAMkE;AAClE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,WAAW,CAAU,CAAA;AAsBtG;;;;;;;;;;8DAU8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,CAAU,CAAA;AAIrF;;2CAE2C;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAU,CAAA;AA6B7E;;;;;;;;;kFASkF;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,qBAAqB;IACrB,wBAAwB;IACxB,0BAA0B;CAClB,CAAA;AAoBV;;;;;6FAK6F;AAC7F,MAAM,CAAC,MAAM,iCAAiC,GAAG,uCAAgD,CAAA;AACjG,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAY,CAAA;AAkCzD;;;;6DAI6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAA;AAgBvF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,yEAAyE;IACzE,qBAAqB;IACrB,gEAAgE;IAChE,2BAA2B;IAC3B,mFAAmF;IACnF,qCAAqC;IACrC,iFAAiF;IACjF,4BAA4B;IAC5B,iFAAiF;IACjF,oCAAoC;IACpC;gFAC4E;IAC5E,qCAAqC;CAC7B,CAAA"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AuthorityRevocationV1 } from '../authority-revocation/types.js';
|
|
2
|
+
import { type CorrectedRevocationView, type RevocationWithdrawalV0, type WithdrawalEvaluation, type WithdrawalStanding, type WithdrawalStandingResolver } from './types.js';
|
|
3
|
+
export declare function isWithdrawalStanding(value: unknown): value is WithdrawalStanding;
|
|
4
|
+
export interface RevocationWithdrawalInput {
|
|
5
|
+
readonly revocation_id: string;
|
|
6
|
+
readonly delegation_id: string;
|
|
7
|
+
readonly withdrawn_by: string;
|
|
8
|
+
readonly withdrawn_at: string;
|
|
9
|
+
readonly reason_code: string;
|
|
10
|
+
readonly detail?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build a `RevocationWithdrawalV0`.
|
|
14
|
+
*
|
|
15
|
+
* A shape constructor and nothing more. It does not sign, does not canonicalize, and does
|
|
16
|
+
* not compute an identifier, because minting the signed form of a record type is a
|
|
17
|
+
* conformance-vocabulary decision reserved to the maintainer and this module is not making
|
|
18
|
+
* it. `record_type` carries the `proposed:` namespace for the same reason.
|
|
19
|
+
*
|
|
20
|
+
* An absent `detail` is absent, never `null`: the key is not present at all, matching how
|
|
21
|
+
* the revocation record treats its own optional detail.
|
|
22
|
+
*/
|
|
23
|
+
export declare function revocationWithdrawal(input: RevocationWithdrawalInput): RevocationWithdrawalV0;
|
|
24
|
+
/** A standing resolver that accepts a withdrawal only from the party the revocation itself
|
|
25
|
+
* names as revoker.
|
|
26
|
+
*
|
|
27
|
+
* Supplied because it is the rule the forcing fixture chose and it needs to be runnable.
|
|
28
|
+
* IT IS A CHOICE, NOT A RULE READ FROM ANY TEXT. Draft-03 section 3.5 names the issuer as
|
|
29
|
+
* the party who may revoke; nothing in draft-03 or in the proposed text says who may
|
|
30
|
+
* withdraw a revocation, and the concept document's own `Lifecycle standing` entry says
|
|
31
|
+
* the party who may change an artifact "is not always the issuer". A deployment whose
|
|
32
|
+
* authority model gives a security function, a successor or a quorum standing to correct a
|
|
33
|
+
* publication error should pass its own resolver instead of this one. */
|
|
34
|
+
export declare const withdrawalSignerIsRevoker: WithdrawalStandingResolver;
|
|
35
|
+
/**
|
|
36
|
+
* Decide whether one withdrawal record is accepted against a set of held revocations.
|
|
37
|
+
*
|
|
38
|
+
* Four questions, kept separate on purpose, each with its own code:
|
|
39
|
+
*
|
|
40
|
+
* 1. Is the record a well-formed withdrawal? `WITHDRAWAL_SCHEMA_INVALID`.
|
|
41
|
+
* 2. Does it name a revocation the held set actually contains?
|
|
42
|
+
* `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`.
|
|
43
|
+
* 3. Does that revocation revoke the delegation this record names?
|
|
44
|
+
* `WITHDRAWAL_TARGET_MISMATCH`.
|
|
45
|
+
* 4. May this party withdraw it? Asked of the injected resolver, never of the record.
|
|
46
|
+
* `WITHDRAWAL_SIGNER_WITHOUT_STANDING` when the resolver establishes they may not, and
|
|
47
|
+
* `WITHDRAWAL_STANDING_NOT_ESTABLISHED` when it cannot establish either way.
|
|
48
|
+
*
|
|
49
|
+
* The last split is the wording rule, executable: a standing question the verifier could
|
|
50
|
+
* not answer is not established, and that is not the same finding as a party established to
|
|
51
|
+
* lack standing. Both refuse the withdrawal, and a caller reporting the refusal has to be
|
|
52
|
+
* able to say which one happened.
|
|
53
|
+
*
|
|
54
|
+
* AUTHENTICATION IS THE CALLER'S. This function never checks a signature, because a
|
|
55
|
+
* withdrawal has no signed form in this SDK, on purpose; see `RevocationWithdrawalV0`.
|
|
56
|
+
* Whoever calls it is the party asserting the record is genuine, exactly as whoever calls
|
|
57
|
+
* `insertVerifiedRevocation` asserts the revocation was verified.
|
|
58
|
+
*
|
|
59
|
+
* NOTHING HERE REMOVES A REVOCATION, on any path. An accepted withdrawal is a record about
|
|
60
|
+
* a record. The held set handed in is not mutated and no store is touched.
|
|
61
|
+
*/
|
|
62
|
+
export declare function evaluateRevocationWithdrawal(withdrawal: RevocationWithdrawalV0, heldRevocations: readonly AuthorityRevocationV1[], resolveStanding: WithdrawalStandingResolver): WithdrawalEvaluation;
|
|
63
|
+
/**
|
|
64
|
+
* The current position of one revocation together with every withdrawal referencing it.
|
|
65
|
+
*
|
|
66
|
+
* This is the field that did not exist. A verifier that must report "revoked, and the
|
|
67
|
+
* revoker later said this was recorded in error" had nowhere to put the second half, in
|
|
68
|
+
* either reference SDK or in the proposed text, so it could only report the first half and
|
|
69
|
+
* drop the rest.
|
|
70
|
+
*
|
|
71
|
+
* `revocation` is present and unchanged whether or not anything was accepted. Accepted
|
|
72
|
+
* withdrawals are listed, refused ones are listed with their codes, and neither list makes
|
|
73
|
+
* the revocation ineffective: a later finding is a new record that references the earlier
|
|
74
|
+
* one and states its own effect, never an edit of it and never its removal.
|
|
75
|
+
*
|
|
76
|
+
* Withdrawals naming a different revocation are not silently dropped. They are evaluated,
|
|
77
|
+
* refused `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`, and appear in `refused`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function correctedRevocationView(revocation: AuthorityRevocationV1, withdrawals: readonly RevocationWithdrawalV0[], resolveStanding: WithdrawalStandingResolver): CorrectedRevocationView;
|
|
80
|
+
//# sourceMappingURL=withdrawal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withdrawal.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/withdrawal.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAE7E,OAAO,EAIL,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,YAAY,CAAA;AAInB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,sBAAsB,CA8C7F;AAED;;;;;;;;;0EAS0E;AAC1E,eAAO,MAAM,yBAAyB,EAAE,0BACyC,CAAA;AAgBjF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,sBAAsB,EAClC,eAAe,EAAE,SAAS,qBAAqB,EAAE,EACjD,eAAe,EAAE,0BAA0B,GAC1C,oBAAoB,CAqDtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,SAAS,sBAAsB,EAAE,EAC9C,eAAe,EAAE,0BAA0B,GAC1C,uBAAuB,CAUzB"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
//
|
|
4
|
+
// PROPOSED, OPT-IN. Withdrawal, or correction, of a recorded revocation.
|
|
5
|
+
// See ./types.ts for the specification position. Concept source:
|
|
6
|
+
// aeoess/agent-authority-lifecycle, invariant candidate CAND-02 (later evidence does not
|
|
7
|
+
// rewrite earlier evidence) and invariant L3 (reauthorization creates new authority).
|
|
8
|
+
// Proposed.
|
|
9
|
+
//
|
|
10
|
+
// THE ONE SENTENCE THIS FILE EXISTS FOR. A corrected false revocation is a separate record,
|
|
11
|
+
// not a resurrection. Draft-03 section 3.5 states "Revocation is irreversible", and nothing
|
|
12
|
+
// below relaxes that: an accepted withdrawal leaves the revocation held, leaves it
|
|
13
|
+
// verifying byte for byte, and leaves every chain verdict exactly where it was. What the
|
|
14
|
+
// withdrawal changes is what a verifier can REPORT, which had no representation at all.
|
|
15
|
+
//
|
|
16
|
+
// Continuity after a correction still needs a fresh grant from a principal who currently
|
|
17
|
+
// holds authority. This module mints no grant and no authority of any kind.
|
|
18
|
+
import { AuthorityStateError } from './marker.js';
|
|
19
|
+
import { REVOCATION_WITHDRAWAL_RECORD_TYPE, REVOCATION_WITHDRAWAL_VERSION, WITHDRAWAL_STANDINGS, } from './types.js';
|
|
20
|
+
const ID = /^sha256:[0-9a-f]{64}$/;
|
|
21
|
+
export function isWithdrawalStanding(value) {
|
|
22
|
+
return typeof value === 'string' && WITHDRAWAL_STANDINGS.includes(value);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build a `RevocationWithdrawalV0`.
|
|
26
|
+
*
|
|
27
|
+
* A shape constructor and nothing more. It does not sign, does not canonicalize, and does
|
|
28
|
+
* not compute an identifier, because minting the signed form of a record type is a
|
|
29
|
+
* conformance-vocabulary decision reserved to the maintainer and this module is not making
|
|
30
|
+
* it. `record_type` carries the `proposed:` namespace for the same reason.
|
|
31
|
+
*
|
|
32
|
+
* An absent `detail` is absent, never `null`: the key is not present at all, matching how
|
|
33
|
+
* the revocation record treats its own optional detail.
|
|
34
|
+
*/
|
|
35
|
+
export function revocationWithdrawal(input) {
|
|
36
|
+
if (input === null || typeof input !== 'object') {
|
|
37
|
+
throw new AuthorityStateError('WITHDRAWAL_MALFORMED', 'a withdrawal input must be an object');
|
|
38
|
+
}
|
|
39
|
+
for (const field of ['revocation_id', 'delegation_id']) {
|
|
40
|
+
if (typeof input[field] !== 'string' || !ID.test(input[field])) {
|
|
41
|
+
throw new AuthorityStateError('WITHDRAWAL_ID_NONCANONICAL', `${field} must be sha256:<64 lowercase hex>`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const field of ['withdrawn_by', 'withdrawn_at', 'reason_code']) {
|
|
45
|
+
if (typeof input[field] !== 'string' || input[field].length === 0) {
|
|
46
|
+
throw new AuthorityStateError('WITHDRAWAL_FIELD_REQUIRED', `${field} must be a non-empty string`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (input.detail !== undefined && (typeof input.detail !== 'string' || input.detail.length === 0)) {
|
|
50
|
+
throw new AuthorityStateError('WITHDRAWAL_DETAIL_INVALID', 'detail must be a non-empty string when present');
|
|
51
|
+
}
|
|
52
|
+
const record = {
|
|
53
|
+
record_type: REVOCATION_WITHDRAWAL_RECORD_TYPE,
|
|
54
|
+
version: REVOCATION_WITHDRAWAL_VERSION,
|
|
55
|
+
revocation_id: input.revocation_id,
|
|
56
|
+
delegation_id: input.delegation_id,
|
|
57
|
+
withdrawn_by: input.withdrawn_by,
|
|
58
|
+
withdrawn_at: input.withdrawn_at,
|
|
59
|
+
reason_code: input.reason_code,
|
|
60
|
+
};
|
|
61
|
+
if (input.detail !== undefined)
|
|
62
|
+
record.detail = input.detail;
|
|
63
|
+
return Object.freeze(record);
|
|
64
|
+
}
|
|
65
|
+
/** A standing resolver that accepts a withdrawal only from the party the revocation itself
|
|
66
|
+
* names as revoker.
|
|
67
|
+
*
|
|
68
|
+
* Supplied because it is the rule the forcing fixture chose and it needs to be runnable.
|
|
69
|
+
* IT IS A CHOICE, NOT A RULE READ FROM ANY TEXT. Draft-03 section 3.5 names the issuer as
|
|
70
|
+
* the party who may revoke; nothing in draft-03 or in the proposed text says who may
|
|
71
|
+
* withdraw a revocation, and the concept document's own `Lifecycle standing` entry says
|
|
72
|
+
* the party who may change an artifact "is not always the issuer". A deployment whose
|
|
73
|
+
* authority model gives a security function, a successor or a quorum standing to correct a
|
|
74
|
+
* publication error should pass its own resolver instead of this one. */
|
|
75
|
+
export const withdrawalSignerIsRevoker = (withdrawal, revocation) => withdrawal.withdrawn_by === revocation.revoker ? 'has_standing' : 'no_standing';
|
|
76
|
+
function malformed(withdrawal) {
|
|
77
|
+
const w = withdrawal;
|
|
78
|
+
if (w === null || typeof w !== 'object')
|
|
79
|
+
return true;
|
|
80
|
+
if (w.record_type !== REVOCATION_WITHDRAWAL_RECORD_TYPE)
|
|
81
|
+
return true;
|
|
82
|
+
if (w.version !== REVOCATION_WITHDRAWAL_VERSION)
|
|
83
|
+
return true;
|
|
84
|
+
if (typeof w.revocation_id !== 'string' || !ID.test(w.revocation_id))
|
|
85
|
+
return true;
|
|
86
|
+
if (typeof w.delegation_id !== 'string' || !ID.test(w.delegation_id))
|
|
87
|
+
return true;
|
|
88
|
+
for (const field of ['withdrawn_by', 'withdrawn_at', 'reason_code']) {
|
|
89
|
+
const value = w[field];
|
|
90
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Decide whether one withdrawal record is accepted against a set of held revocations.
|
|
97
|
+
*
|
|
98
|
+
* Four questions, kept separate on purpose, each with its own code:
|
|
99
|
+
*
|
|
100
|
+
* 1. Is the record a well-formed withdrawal? `WITHDRAWAL_SCHEMA_INVALID`.
|
|
101
|
+
* 2. Does it name a revocation the held set actually contains?
|
|
102
|
+
* `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`.
|
|
103
|
+
* 3. Does that revocation revoke the delegation this record names?
|
|
104
|
+
* `WITHDRAWAL_TARGET_MISMATCH`.
|
|
105
|
+
* 4. May this party withdraw it? Asked of the injected resolver, never of the record.
|
|
106
|
+
* `WITHDRAWAL_SIGNER_WITHOUT_STANDING` when the resolver establishes they may not, and
|
|
107
|
+
* `WITHDRAWAL_STANDING_NOT_ESTABLISHED` when it cannot establish either way.
|
|
108
|
+
*
|
|
109
|
+
* The last split is the wording rule, executable: a standing question the verifier could
|
|
110
|
+
* not answer is not established, and that is not the same finding as a party established to
|
|
111
|
+
* lack standing. Both refuse the withdrawal, and a caller reporting the refusal has to be
|
|
112
|
+
* able to say which one happened.
|
|
113
|
+
*
|
|
114
|
+
* AUTHENTICATION IS THE CALLER'S. This function never checks a signature, because a
|
|
115
|
+
* withdrawal has no signed form in this SDK, on purpose; see `RevocationWithdrawalV0`.
|
|
116
|
+
* Whoever calls it is the party asserting the record is genuine, exactly as whoever calls
|
|
117
|
+
* `insertVerifiedRevocation` asserts the revocation was verified.
|
|
118
|
+
*
|
|
119
|
+
* NOTHING HERE REMOVES A REVOCATION, on any path. An accepted withdrawal is a record about
|
|
120
|
+
* a record. The held set handed in is not mutated and no store is touched.
|
|
121
|
+
*/
|
|
122
|
+
export function evaluateRevocationWithdrawal(withdrawal, heldRevocations, resolveStanding) {
|
|
123
|
+
if (malformed(withdrawal)) {
|
|
124
|
+
return Object.freeze({
|
|
125
|
+
accepted: false,
|
|
126
|
+
reason_code: 'WITHDRAWAL_SCHEMA_INVALID',
|
|
127
|
+
standing: null,
|
|
128
|
+
withdrawal,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const target = (heldRevocations ?? []).find(r => r?.revocation_id === withdrawal.revocation_id);
|
|
132
|
+
if (target === undefined) {
|
|
133
|
+
return Object.freeze({
|
|
134
|
+
accepted: false,
|
|
135
|
+
reason_code: 'WITHDRAWAL_NAMES_NO_HELD_REVOCATION',
|
|
136
|
+
standing: null,
|
|
137
|
+
withdrawal,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (target.delegation_id !== withdrawal.delegation_id) {
|
|
141
|
+
return Object.freeze({
|
|
142
|
+
accepted: false,
|
|
143
|
+
reason_code: 'WITHDRAWAL_TARGET_MISMATCH',
|
|
144
|
+
standing: null,
|
|
145
|
+
withdrawal,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
let standing;
|
|
149
|
+
try {
|
|
150
|
+
standing = resolveStanding(withdrawal, target);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
standing = 'unknown';
|
|
154
|
+
}
|
|
155
|
+
if (!isWithdrawalStanding(standing))
|
|
156
|
+
standing = 'unknown';
|
|
157
|
+
if (standing === 'has_standing') {
|
|
158
|
+
return Object.freeze({
|
|
159
|
+
accepted: true,
|
|
160
|
+
reason_code: 'WITHDRAWAL_ACCEPTED',
|
|
161
|
+
standing,
|
|
162
|
+
withdrawal,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
accepted: false,
|
|
167
|
+
reason_code: standing === 'no_standing'
|
|
168
|
+
? 'WITHDRAWAL_SIGNER_WITHOUT_STANDING'
|
|
169
|
+
: 'WITHDRAWAL_STANDING_NOT_ESTABLISHED',
|
|
170
|
+
standing,
|
|
171
|
+
withdrawal,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* The current position of one revocation together with every withdrawal referencing it.
|
|
176
|
+
*
|
|
177
|
+
* This is the field that did not exist. A verifier that must report "revoked, and the
|
|
178
|
+
* revoker later said this was recorded in error" had nowhere to put the second half, in
|
|
179
|
+
* either reference SDK or in the proposed text, so it could only report the first half and
|
|
180
|
+
* drop the rest.
|
|
181
|
+
*
|
|
182
|
+
* `revocation` is present and unchanged whether or not anything was accepted. Accepted
|
|
183
|
+
* withdrawals are listed, refused ones are listed with their codes, and neither list makes
|
|
184
|
+
* the revocation ineffective: a later finding is a new record that references the earlier
|
|
185
|
+
* one and states its own effect, never an edit of it and never its removal.
|
|
186
|
+
*
|
|
187
|
+
* Withdrawals naming a different revocation are not silently dropped. They are evaluated,
|
|
188
|
+
* refused `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`, and appear in `refused`.
|
|
189
|
+
*/
|
|
190
|
+
export function correctedRevocationView(revocation, withdrawals, resolveStanding) {
|
|
191
|
+
const held = [revocation];
|
|
192
|
+
const evaluations = (withdrawals ?? []).map(w => evaluateRevocationWithdrawal(w, held, resolveStanding));
|
|
193
|
+
return Object.freeze({
|
|
194
|
+
revocation,
|
|
195
|
+
accepted: Object.freeze(evaluations.filter(e => e.accepted)),
|
|
196
|
+
refused: Object.freeze(evaluations.filter(e => !e.accepted)),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=withdrawal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withdrawal.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/withdrawal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AuthorityBoundFulfilment, AuthorityBoundFulfilmentBody, AuthorityExhaustion, AuthorityExhaustionBody } from './types.js';
|
|
2
|
+
/** Domain tags. Each is a distinct tag followed by one zero byte, the same discipline
|
|
3
|
+
* `AuthorityDelegationV1` and `AuthorityRevocationV1` follow, so bytes minted for one
|
|
4
|
+
* construction can never be read as bytes minted for another. The `PROPOSED-` prefix is
|
|
5
|
+
* part of the tag: if any of this is ever specified, the specified construction will use a
|
|
6
|
+
* different tag and records minted under this one will not verify under it. That is the
|
|
7
|
+
* intended behaviour, not a migration problem to solve later. */
|
|
8
|
+
export declare const AUTHORITY_BOUND_FULFILMENT_SIGNATURE_DOMAIN = "PROPOSED-APS-AUTHORITY-BOUND-FULFILMENT-SIGNATURE-V0\0";
|
|
9
|
+
export declare const AUTHORITY_EXHAUSTION_ID_DOMAIN = "PROPOSED-APS-AUTHORITY-EXHAUSTION-ID-V0\0";
|
|
10
|
+
export declare const AUTHORITY_EXHAUSTION_SIGNATURE_DOMAIN = "PROPOSED-APS-AUTHORITY-EXHAUSTION-SIGNATURE-V0\0";
|
|
11
|
+
/** Exact Ed25519 preimage for a fulfilment attestation: the domain tag plus RFC 8785 JCS of
|
|
12
|
+
* the record with `signature` absent. */
|
|
13
|
+
export declare function authorityBoundFulfilmentSignatureInput(body: AuthorityBoundFulfilmentBody): string;
|
|
14
|
+
/** Write-boundary twin. Use when ISSUING. The verification path keeps calling the
|
|
15
|
+
* unrestricted form, so a record minted before the write rule still verifies. */
|
|
16
|
+
export declare function authorityBoundFulfilmentSignatureInputForWrite(body: AuthorityBoundFulfilmentBody): string;
|
|
17
|
+
export declare function signAuthorityBoundFulfilment(body: AuthorityBoundFulfilmentBody, privateKeyHex: string): string;
|
|
18
|
+
export declare function verifyAuthorityBoundFulfilmentSignature(record: AuthorityBoundFulfilment, publicKeyHex: string): boolean;
|
|
19
|
+
/** Exact preimage for `exhaustion_id`: the ID domain tag plus JCS of the body. */
|
|
20
|
+
export declare function authorityExhaustionIdInput(body: AuthorityExhaustionBody): string;
|
|
21
|
+
export declare function computeAuthorityExhaustionId(body: AuthorityExhaustionBody): string;
|
|
22
|
+
export declare function computeAuthorityExhaustionIdForWrite(body: AuthorityExhaustionBody): string;
|
|
23
|
+
/** Exact Ed25519 preimage for the exhaustion record: the signature domain tag plus JCS of
|
|
24
|
+
* the record with `signature` absent. `exhaustion_id` IS inside this preimage, so the
|
|
25
|
+
* identifier is signed rather than being an unauthenticated label beside the signature. */
|
|
26
|
+
export declare function authorityExhaustionSignatureInput(record: Omit<AuthorityExhaustion, 'signature'>): string;
|
|
27
|
+
export declare function authorityExhaustionSignatureInputForWrite(record: Omit<AuthorityExhaustion, 'signature'>): string;
|
|
28
|
+
export declare function signAuthorityExhaustion(record: Omit<AuthorityExhaustion, 'signature'>, privateKeyHex: string): string;
|
|
29
|
+
export declare function verifyAuthorityExhaustionSignature(record: AuthorityExhaustion, publicKeyHex: string): boolean;
|
|
30
|
+
//# sourceMappingURL=canonical.d.ts.map
|