agent-passport-system 7.0.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/SECURITY.md +11 -0
- 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 +52 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +282 -1
- 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-revocation/canonical.d.ts +46 -0
- package/dist/src/v2/authority-revocation/canonical.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/canonical.js +68 -0
- package/dist/src/v2/authority-revocation/canonical.js.map +1 -0
- package/dist/src/v2/authority-revocation/index.d.ts +9 -0
- package/dist/src/v2/authority-revocation/index.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/index.js +11 -0
- package/dist/src/v2/authority-revocation/index.js.map +1 -0
- package/dist/src/v2/authority-revocation/issue.d.ts +54 -0
- package/dist/src/v2/authority-revocation/issue.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/issue.js +111 -0
- package/dist/src/v2/authority-revocation/issue.js.map +1 -0
- package/dist/src/v2/authority-revocation/record.d.ts +69 -0
- package/dist/src/v2/authority-revocation/record.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/record.js +51 -0
- package/dist/src/v2/authority-revocation/record.js.map +1 -0
- package/dist/src/v2/authority-revocation/resolver.d.ts +30 -0
- package/dist/src/v2/authority-revocation/resolver.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/resolver.js +52 -0
- package/dist/src/v2/authority-revocation/resolver.js.map +1 -0
- package/dist/src/v2/authority-revocation/schema.d.ts +15 -0
- package/dist/src/v2/authority-revocation/schema.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/schema.js +107 -0
- package/dist/src/v2/authority-revocation/schema.js.map +1 -0
- package/dist/src/v2/authority-revocation/store.d.ts +55 -0
- package/dist/src/v2/authority-revocation/store.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/store.js +69 -0
- package/dist/src/v2/authority-revocation/store.js.map +1 -0
- package/dist/src/v2/authority-revocation/types.d.ts +136 -0
- package/dist/src/v2/authority-revocation/types.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/types.js +11 -0
- package/dist/src/v2/authority-revocation/types.js.map +1 -0
- package/dist/src/v2/authority-revocation/verify.d.ts +38 -0
- package/dist/src/v2/authority-revocation/verify.d.ts.map +1 -0
- package/dist/src/v2/authority-revocation/verify.js +139 -0
- package/dist/src/v2/authority-revocation/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/receipt-core/composite.d.ts +69 -3
- package/dist/src/v2/receipt-core/composite.d.ts.map +1 -1
- package/dist/src/v2/receipt-core/composite.js +75 -9
- package/dist/src/v2/receipt-core/composite.js.map +1 -1
- package/dist/src/v2/receipt-core/predecessor.d.ts +95 -0
- package/dist/src/v2/receipt-core/predecessor.d.ts.map +1 -0
- package/dist/src/v2/receipt-core/predecessor.js +115 -0
- package/dist/src/v2/receipt-core/predecessor.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 +10 -7
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { AuthorityDelegationV1 } from '../authority-delegation/types.js';
|
|
2
|
+
/** Draft-native direct revocation of an AuthorityDelegationV1, draft-03 section 3.5.1.
|
|
3
|
+
*
|
|
4
|
+
* Distinct from the pre-draft `RevocationRecord` in src/types/passport.ts, which carries
|
|
5
|
+
* a raw public key in `revokedBy`, a free-text `reason`, no cascade transaction identity,
|
|
6
|
+
* no nonce, no record_type and no domain-separated preimage. That record cannot represent
|
|
7
|
+
* section 3.5.1 evidence and is not reused here. The two models stay distinguishable. */
|
|
8
|
+
export declare const AUTHORITY_REVOCATION_RECORD_TYPE: 'aps:authority-revocation:v1';
|
|
9
|
+
export declare const AUTHORITY_REVOCATION_VERSION: '1.0';
|
|
10
|
+
/** The content over which `revocation_id` is computed: the record with `revocation_id`
|
|
11
|
+
* and `signature` absent. `revoked_at` is inside it, as section 3.5.1 requires of the
|
|
12
|
+
* revocation time. */
|
|
13
|
+
export interface AuthorityRevocationBodyV1 {
|
|
14
|
+
record_type: typeof AUTHORITY_REVOCATION_RECORD_TYPE;
|
|
15
|
+
version: typeof AUTHORITY_REVOCATION_VERSION;
|
|
16
|
+
/** Content address of the revoked delegation: `sha256:<64 lowercase hex>`. */
|
|
17
|
+
delegation_id: string;
|
|
18
|
+
/** The revoking authority. Section 3.5 names exactly one party for a direct
|
|
19
|
+
* revocation, the target delegation's issuer, so a valid record has
|
|
20
|
+
* `revoker === delegation.issuer` for the delegation it names. */
|
|
21
|
+
revoker: string;
|
|
22
|
+
/** Which key signed. A non-empty string, and nothing more is required of its shape: no
|
|
23
|
+
* local rule relates it to `revoker`. Whether the method belongs to the issuer is
|
|
24
|
+
* decided only by key resolution against the target delegation's `issuer` at
|
|
25
|
+
* `revoked_at`, which verifyAuthorityRevocation() performs. */
|
|
26
|
+
verification_method: string;
|
|
27
|
+
/** Canonical UTC-millisecond revocation time, supplied by the caller, never read from
|
|
28
|
+
* a clock inside issuance. */
|
|
29
|
+
revoked_at: string;
|
|
30
|
+
/** Machine-readable reason. A non-empty string; section 3.5.1 fixes no grammar for one
|
|
31
|
+
* and none is invented here. */
|
|
32
|
+
reason_code: string;
|
|
33
|
+
/** OPTIONAL free-text detail. Absent means the key is not present at all: JCS has no
|
|
34
|
+
* canonical form for undefined, so an absent detail is never serialized as null. */
|
|
35
|
+
detail?: string;
|
|
36
|
+
/** The transaction identity shared by every record one cascade produces. Deterministic
|
|
37
|
+
* and content-bound; see cascadeTransactionId() in canonical.ts. */
|
|
38
|
+
cascade_transaction_id: string;
|
|
39
|
+
/** 16 random bytes as 32 lowercase hexadecimal characters. */
|
|
40
|
+
nonce: string;
|
|
41
|
+
}
|
|
42
|
+
export interface AuthorityRevocationV1 extends AuthorityRevocationBodyV1 {
|
|
43
|
+
/** `sha256:<64 lowercase hex>` over the ID domain tag and JCS of the body. */
|
|
44
|
+
revocation_id: string;
|
|
45
|
+
/** Raw 64-byte Ed25519 signature as 128 lowercase hexadecimal characters. */
|
|
46
|
+
signature: string;
|
|
47
|
+
}
|
|
48
|
+
export type AuthorityRevocationFailureCode = 'SCHEMA_INVALID' | 'UNSUPPORTED_RECORD_TYPE' | 'UNSUPPORTED_VERSION' | 'NONCANONICAL_VALUE'
|
|
49
|
+
/** revocation_id does not recompute from the record's own body. */
|
|
50
|
+
| 'ID_MISMATCH'
|
|
51
|
+
/** cascade_transaction_id does not recompute from the record's own body. */
|
|
52
|
+
| 'CASCADE_TRANSACTION_MISMATCH'
|
|
53
|
+
/** The delegation handed in is not the one this record names. */
|
|
54
|
+
| 'TARGET_MISMATCH'
|
|
55
|
+
/** The delegation handed in does not recompute its own delegation_id, so its `issuer`
|
|
56
|
+
* is not an authenticated field and the revoker check cannot be made against it. */
|
|
57
|
+
| 'TARGET_ID_MISMATCH'
|
|
58
|
+
/** `revoker` is not the target delegation's `issuer`. */
|
|
59
|
+
| 'REVOKER_NOT_ISSUER' | 'KEY_RESOLUTION_FAILED' | 'KEY_SCHEME_UNSUPPORTED' | 'KEY_NOT_FOUND' | 'KEY_AMBIGUOUS' | 'KEY_UNREACHABLE' | 'KEY_MATERIAL_MALFORMED' | 'SIGNATURE_INVALID';
|
|
60
|
+
export interface AuthorityRevocationFailure {
|
|
61
|
+
code: AuthorityRevocationFailureCode;
|
|
62
|
+
message: string;
|
|
63
|
+
}
|
|
64
|
+
export interface AuthorityRevocationVerificationResult {
|
|
65
|
+
state: 'valid' | 'invalid' | 'indeterminate' | 'unsupported';
|
|
66
|
+
valid: boolean;
|
|
67
|
+
failures: AuthorityRevocationFailure[];
|
|
68
|
+
}
|
|
69
|
+
/** What a store's first-write primitive reports: whether this call was the write that
|
|
70
|
+
* took the first-wins slot, and what the store holds for the target now.
|
|
71
|
+
*
|
|
72
|
+
* `inserted` is the only way a caller learns which of the two happened. `stored` is the
|
|
73
|
+
* record passed in when `inserted` is true and the record already held when it is false,
|
|
74
|
+
* so a caller that must distinguish them reads `inserted` rather than comparing bytes. */
|
|
75
|
+
export interface AuthorityRevocationInsertion {
|
|
76
|
+
inserted: boolean;
|
|
77
|
+
stored: AuthorityRevocationV1;
|
|
78
|
+
}
|
|
79
|
+
/** The read and write boundary a revocation resolver needs.
|
|
80
|
+
*
|
|
81
|
+
* Nothing in this interface promises durability. An implementation backed by process
|
|
82
|
+
* memory, a file, or a replicated database all satisfy it; only the implementation says
|
|
83
|
+
* which. Section 3.5.1 makes the cascade-completion record depend on the last
|
|
84
|
+
* descendant's revocation being PERSISTENT, and no method here establishes persistence,
|
|
85
|
+
* which is one reason no completion record is issued in this module.
|
|
86
|
+
*
|
|
87
|
+
* This interface carries no method that takes an arbitrary, unverified record.
|
|
88
|
+
* `insertVerifiedRevocation` is a persistence primitive, not an entry point: the only
|
|
89
|
+
* supported way to move a candidate revocation into a store is
|
|
90
|
+
* recordAuthorityRevocation() in record.ts, which verifies first and calls the primitive
|
|
91
|
+
* only on a `valid` result. See that function for why the split exists. */
|
|
92
|
+
export interface AuthorityRevocationStore {
|
|
93
|
+
/** Whether `delegationId` is inside this store's view at all.
|
|
94
|
+
*
|
|
95
|
+
* This is what keeps absence from meaning "active". A store that has never heard of a
|
|
96
|
+
* delegation cannot say the delegation is unrevoked; it can only say it does not know.
|
|
97
|
+
* A store whose view covers the delegation and holds no revocation for it can. */
|
|
98
|
+
tracks(delegationId: string): boolean;
|
|
99
|
+
/** The revocation recorded for `delegationId`, or undefined when none is recorded. */
|
|
100
|
+
get(delegationId: string): AuthorityRevocationV1 | undefined;
|
|
101
|
+
/** Persistence primitive. Writes `revocation` only when this store holds no record for
|
|
102
|
+
* `revocation.delegation_id`, and reports what it holds for that target now.
|
|
103
|
+
*
|
|
104
|
+
* ACCEPTS ONLY A RECORD ALREADY VERIFIED AGAINST ITS TARGET DELEGATION by
|
|
105
|
+
* recordAuthorityRevocation(). It performs no verification, and none is possible here:
|
|
106
|
+
* verification needs the target delegation and a key resolver, neither of which a store
|
|
107
|
+
* has. An implementation is a write path, not a trust boundary, and a caller that
|
|
108
|
+
* reaches past recordAuthorityRevocation() to this method is the one asserting the
|
|
109
|
+
* record was verified.
|
|
110
|
+
*
|
|
111
|
+
* First verified revocation for a delegation wins. Revocation is irreversible (INV-5),
|
|
112
|
+
* so a later call naming a delegation that already has a record does not replace it:
|
|
113
|
+
* `inserted` is false and `stored` is the record already held, unchanged. The check for
|
|
114
|
+
* an existing record and the write MUST be one indivisible operation, so that two
|
|
115
|
+
* callers racing on the same delegation cannot both observe `inserted: true`.
|
|
116
|
+
*
|
|
117
|
+
* For a DURABLE implementation that means the first write MUST be an atomic conditional
|
|
118
|
+
* insert keyed by `delegation_id` — an insert the storage engine itself makes succeed
|
|
119
|
+
* for exactly one of two concurrent callers, such as a unique-constrained primary key,
|
|
120
|
+
* a compare-and-set, or an insert-if-absent. Reading the existing record and then
|
|
121
|
+
* writing does NOT satisfy this contract: under concurrency two callers can both read
|
|
122
|
+
* an empty slot before either writes, both report `inserted: true`, and the second
|
|
123
|
+
* write displaces the first, which makes the recorded revocation time, reason and
|
|
124
|
+
* revoker mutable after the fact and breaks first-wins and INV-5. The in-memory
|
|
125
|
+
* reference meets the contract only because its read and write are one synchronous
|
|
126
|
+
* statement sequence on a single-threaded runtime; that is a property of that runtime,
|
|
127
|
+
* not a pattern a durable store may copy.
|
|
128
|
+
*
|
|
129
|
+
* Brings its target into the tracked view: recording a revocation for a delegation is a
|
|
130
|
+
* statement that this store has an opinion about that delegation. */
|
|
131
|
+
insertVerifiedRevocation(revocation: AuthorityRevocationV1): AuthorityRevocationInsertion;
|
|
132
|
+
}
|
|
133
|
+
/** What a gateway eventually supplies to the chain verifier. Interface only; no gateway
|
|
134
|
+
* implementation lives in this repository. */
|
|
135
|
+
export type AuthorityRevocationLookup = (delegation: AuthorityDelegationV1) => AuthorityRevocationV1 | undefined;
|
|
136
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-revocation/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAE7E;;;;;0FAK0F;AAC1F,eAAO,MAAM,gCAAgC,EAAG,6BAAsC,CAAA;AACtF,eAAO,MAAM,4BAA4B,EAAG,KAAc,CAAA;AAE1D;;uBAEuB;AACvB,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,OAAO,gCAAgC,CAAA;IACpD,OAAO,EAAE,OAAO,4BAA4B,CAAA;IAC5C,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAA;IACrB;;uEAEmE;IACnE,OAAO,EAAE,MAAM,CAAA;IACf;;;oEAGgE;IAChE,mBAAmB,EAAE,MAAM,CAAA;IAC3B;mCAC+B;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB;qCACiC;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB;yFACqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;yEACqE;IACrE,sBAAsB,EAAE,MAAM,CAAA;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAA;IACrB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,8BAA8B,GACtC,gBAAgB,GAChB,yBAAyB,GACzB,qBAAqB,GACrB,oBAAoB;AACtB,mEAAmE;GACjE,aAAa;AACf,4EAA4E;GAC1E,8BAA8B;AAChC,iEAAiE;GAC/D,iBAAiB;AACnB;qFACqF;GACnF,oBAAoB;AACtB,yDAAyD;GACvD,oBAAoB,GACpB,uBAAuB,GACvB,wBAAwB,GACxB,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,wBAAwB,GACxB,mBAAmB,CAAA;AAEvB,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,8BAA8B,CAAA;IACpC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,CAAA;IAC5D,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,0BAA0B,EAAE,CAAA;CACvC;AAED;;;;;2FAK2F;AAC3F,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,qBAAqB,CAAA;CAC9B;AAED;;;;;;;;;;;;4EAY4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC;;;;uFAImF;IACnF,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACrC,sFAAsF;IACtF,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAA;IAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0EA6BsE;IACtE,wBAAwB,CAAC,UAAU,EAAE,qBAAqB,GAAG,4BAA4B,CAAA;CAC1F;AAED;+CAC+C;AAC/C,MAAM,MAAM,yBAAyB,GAAG,CACtC,UAAU,EAAE,qBAAqB,KAC9B,qBAAqB,GAAG,SAAS,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/** Draft-native direct revocation of an AuthorityDelegationV1, draft-03 section 3.5.1.
|
|
4
|
+
*
|
|
5
|
+
* Distinct from the pre-draft `RevocationRecord` in src/types/passport.ts, which carries
|
|
6
|
+
* a raw public key in `revokedBy`, a free-text `reason`, no cascade transaction identity,
|
|
7
|
+
* no nonce, no record_type and no domain-separated preimage. That record cannot represent
|
|
8
|
+
* section 3.5.1 evidence and is not reused here. The two models stay distinguishable. */
|
|
9
|
+
export const AUTHORITY_REVOCATION_RECORD_TYPE = 'aps:authority-revocation:v1';
|
|
10
|
+
export const AUTHORITY_REVOCATION_VERSION = '1.0';
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/v2/authority-revocation/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AAItC;;;;;0FAK0F;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAAG,6BAAsC,CAAA;AACtF,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAc,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { VerificationKeyResolver } from '../authority-delegation/types.js';
|
|
2
|
+
import type { AuthorityRevocationVerificationResult } from './types.js';
|
|
3
|
+
export interface AuthorityRevocationVerificationOptions {
|
|
4
|
+
/** Resolves the key that signed the revocation, selected at the revocation's own
|
|
5
|
+
* `revoked_at`, per draft section 2.4: the key current at verification time is not
|
|
6
|
+
* necessarily the one that signed this record. */
|
|
7
|
+
resolveVerificationKey: VerificationKeyResolver;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Verify one draft-03 section 3.5.1 direct revocation against the delegation it names.
|
|
11
|
+
*
|
|
12
|
+
* A revocation is never judged alone. Whether a record is a revocation of THIS delegation
|
|
13
|
+
* and whether its signer was allowed to revoke are both questions about the target, so the
|
|
14
|
+
* target is a required argument and every authorization fact is read from it.
|
|
15
|
+
*
|
|
16
|
+
* Checks, in order, returning at the first that fails:
|
|
17
|
+
*
|
|
18
|
+
* 1. closed schema and canonical values on the revocation
|
|
19
|
+
* 2. `cascade_transaction_id` recomputes from the record's own origin content
|
|
20
|
+
* 3. `revocation_id` recomputes from the record's own body
|
|
21
|
+
* 4. closed schema and canonical values on the target delegation
|
|
22
|
+
* 5. the target's `delegation_id` recomputes from the target's own body
|
|
23
|
+
* 6. the revocation's `delegation_id` equals the target's
|
|
24
|
+
* 7. the revocation's `revoker` equals the TARGET's `issuer` (draft section 3.5)
|
|
25
|
+
* 8. the revoker's key resolves, at the revocation's `revoked_at`
|
|
26
|
+
* 9. the Ed25519 signature verifies over the domain-tagged preimage
|
|
27
|
+
*
|
|
28
|
+
* Step 8 hands the resolver `target.issuer`, read from the target delegation, not the
|
|
29
|
+
* `revoker` the record carries. The two are equal by step 7, and reading the target's
|
|
30
|
+
* member is what makes the authorization external to the record: no field inside a
|
|
31
|
+
* revocation selects the key that authorizes it.
|
|
32
|
+
*
|
|
33
|
+
* Fails closed. Anything unrecognized, any resolver that throws, any shape this schema
|
|
34
|
+
* does not claim, produces invalid, indeterminate or unsupported, never valid. This
|
|
35
|
+
* function does not throw.
|
|
36
|
+
*/
|
|
37
|
+
export declare function verifyAuthorityRevocation(candidate: unknown, delegation: unknown, options: AuthorityRevocationVerificationOptions): AuthorityRevocationVerificationResult;
|
|
38
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-revocation/verify.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAGV,uBAAuB,EACxB,MAAM,kCAAkC,CAAA;AASzC,OAAO,KAAK,EAIV,qCAAqC,EACtC,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,sCAAsC;IACrD;;uDAEmD;IACnD,sBAAsB,EAAE,uBAAuB,CAAA;CAChD;AA6DD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,OAAO,EAClB,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,sCAAsC,GAC9C,qCAAqC,CA0DvC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { authorityDelegationBody, computeAuthorityDelegationId, } from '../authority-delegation/canonical.js';
|
|
4
|
+
import { snapshotPlainData } from '../authority-delegation/plain-data.js';
|
|
5
|
+
import { validateAuthorityDelegationShape } from '../authority-delegation/schema.js';
|
|
6
|
+
import { authorityRevocationBody, authorityRevocationCascadeOrigin, computeAuthorityRevocationCascadeTransactionId, computeAuthorityRevocationId, verifyAuthorityRevocationSignature, } from './canonical.js';
|
|
7
|
+
import { validateAuthorityRevocationShape } from './schema.js';
|
|
8
|
+
const KEY_MATERIAL = /^[0-9a-fA-F]{64}$/;
|
|
9
|
+
const UNSUPPORTED_CODES = new Set([
|
|
10
|
+
'UNSUPPORTED_RECORD_TYPE',
|
|
11
|
+
'UNSUPPORTED_VERSION',
|
|
12
|
+
]);
|
|
13
|
+
function result(state, failures) {
|
|
14
|
+
return { state, valid: state === 'valid', failures };
|
|
15
|
+
}
|
|
16
|
+
function invalid(code, message) {
|
|
17
|
+
return result('invalid', [{ code, message }]);
|
|
18
|
+
}
|
|
19
|
+
function indeterminate(code, message) {
|
|
20
|
+
return result('indeterminate', [{ code, message }]);
|
|
21
|
+
}
|
|
22
|
+
/** Map a resolver's answer onto the draft's section 2.5 outcomes, or null when it
|
|
23
|
+
* resolved usable key material. An unsupported identifier scheme is unsupported;
|
|
24
|
+
* everything else that is not a usable key is indeterminate, never SIGNATURE_INVALID,
|
|
25
|
+
* because in those branches no signature was checked at all. */
|
|
26
|
+
function keyResolutionFailure(resolved) {
|
|
27
|
+
if (typeof resolved === 'string') {
|
|
28
|
+
return KEY_MATERIAL.test(resolved)
|
|
29
|
+
? null
|
|
30
|
+
: indeterminate('KEY_MATERIAL_MALFORMED', 'resolved key material is not a 32-byte Ed25519 public key');
|
|
31
|
+
}
|
|
32
|
+
if (resolved && typeof resolved === 'object' && typeof resolved.outcome === 'string') {
|
|
33
|
+
switch (resolved.outcome) {
|
|
34
|
+
case 'unsupported_scheme':
|
|
35
|
+
return result('unsupported', [{ code: 'KEY_SCHEME_UNSUPPORTED', message: 'identifier scheme is not supported by the resolver' }]);
|
|
36
|
+
case 'not_found':
|
|
37
|
+
return indeterminate('KEY_NOT_FOUND', 'revoker or key was not found');
|
|
38
|
+
case 'ambiguous':
|
|
39
|
+
return indeterminate('KEY_AMBIGUOUS', 'key resolution was ambiguous');
|
|
40
|
+
case 'unreachable':
|
|
41
|
+
return indeterminate('KEY_UNREACHABLE', 'key material was unreachable');
|
|
42
|
+
case 'malformed':
|
|
43
|
+
return indeterminate('KEY_MATERIAL_MALFORMED', 'resolved key material is structurally malformed');
|
|
44
|
+
default:
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return indeterminate('KEY_RESOLUTION_FAILED', 'revoker verification key could not be resolved');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Verify one draft-03 section 3.5.1 direct revocation against the delegation it names.
|
|
52
|
+
*
|
|
53
|
+
* A revocation is never judged alone. Whether a record is a revocation of THIS delegation
|
|
54
|
+
* and whether its signer was allowed to revoke are both questions about the target, so the
|
|
55
|
+
* target is a required argument and every authorization fact is read from it.
|
|
56
|
+
*
|
|
57
|
+
* Checks, in order, returning at the first that fails:
|
|
58
|
+
*
|
|
59
|
+
* 1. closed schema and canonical values on the revocation
|
|
60
|
+
* 2. `cascade_transaction_id` recomputes from the record's own origin content
|
|
61
|
+
* 3. `revocation_id` recomputes from the record's own body
|
|
62
|
+
* 4. closed schema and canonical values on the target delegation
|
|
63
|
+
* 5. the target's `delegation_id` recomputes from the target's own body
|
|
64
|
+
* 6. the revocation's `delegation_id` equals the target's
|
|
65
|
+
* 7. the revocation's `revoker` equals the TARGET's `issuer` (draft section 3.5)
|
|
66
|
+
* 8. the revoker's key resolves, at the revocation's `revoked_at`
|
|
67
|
+
* 9. the Ed25519 signature verifies over the domain-tagged preimage
|
|
68
|
+
*
|
|
69
|
+
* Step 8 hands the resolver `target.issuer`, read from the target delegation, not the
|
|
70
|
+
* `revoker` the record carries. The two are equal by step 7, and reading the target's
|
|
71
|
+
* member is what makes the authorization external to the record: no field inside a
|
|
72
|
+
* revocation selects the key that authorizes it.
|
|
73
|
+
*
|
|
74
|
+
* Fails closed. Anything unrecognized, any resolver that throws, any shape this schema
|
|
75
|
+
* does not claim, produces invalid, indeterminate or unsupported, never valid. This
|
|
76
|
+
* function does not throw.
|
|
77
|
+
*/
|
|
78
|
+
export function verifyAuthorityRevocation(candidate, delegation, options) {
|
|
79
|
+
const read = (key) => {
|
|
80
|
+
try {
|
|
81
|
+
return options ? options[key] : undefined;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const resolveVerificationKey = read('resolveVerificationKey');
|
|
88
|
+
const snapshot = snapshotPlainData(candidate);
|
|
89
|
+
const shapeFailures = validateAuthorityRevocationShape(snapshot);
|
|
90
|
+
if (shapeFailures.length > 0) {
|
|
91
|
+
const unsupported = shapeFailures.every(item => UNSUPPORTED_CODES.has(item.code));
|
|
92
|
+
return result(unsupported ? 'unsupported' : 'invalid', shapeFailures);
|
|
93
|
+
}
|
|
94
|
+
const revocation = snapshot;
|
|
95
|
+
const body = authorityRevocationBody(revocation);
|
|
96
|
+
const origin = authorityRevocationCascadeOrigin(body);
|
|
97
|
+
if (computeAuthorityRevocationCascadeTransactionId(origin) !== revocation.cascade_transaction_id) {
|
|
98
|
+
return invalid('CASCADE_TRANSACTION_MISMATCH', 'cascade_transaction_id does not recompute from the record');
|
|
99
|
+
}
|
|
100
|
+
if (computeAuthorityRevocationId(body) !== revocation.revocation_id) {
|
|
101
|
+
return invalid('ID_MISMATCH', 'revocation content address does not match its body');
|
|
102
|
+
}
|
|
103
|
+
const target = snapshotPlainData(delegation);
|
|
104
|
+
const targetFailures = validateAuthorityDelegationShape(target);
|
|
105
|
+
if (targetFailures.length > 0) {
|
|
106
|
+
return invalid('SCHEMA_INVALID', `target delegation invalid (${targetFailures[0].code})`);
|
|
107
|
+
}
|
|
108
|
+
if (computeAuthorityDelegationId(authorityDelegationBody(target)) !== target.delegation_id) {
|
|
109
|
+
return invalid('TARGET_ID_MISMATCH', 'target delegation content address does not match its body');
|
|
110
|
+
}
|
|
111
|
+
if (revocation.delegation_id !== target.delegation_id) {
|
|
112
|
+
return invalid('TARGET_MISMATCH', 'revocation does not name this delegation');
|
|
113
|
+
}
|
|
114
|
+
// Draft section 3.5: a delegation may be revoked by its issuer, and by nobody else this
|
|
115
|
+
// document names.
|
|
116
|
+
if (revocation.revoker !== target.issuer) {
|
|
117
|
+
return invalid('REVOKER_NOT_ISSUER', 'revoker is not the target delegation issuer');
|
|
118
|
+
}
|
|
119
|
+
if (typeof resolveVerificationKey !== 'function') {
|
|
120
|
+
return indeterminate('KEY_RESOLUTION_FAILED', 'no verification key resolver was supplied');
|
|
121
|
+
}
|
|
122
|
+
let resolved = null;
|
|
123
|
+
try {
|
|
124
|
+
// target.issuer, not revocation.revoker: the authorizing identity comes from the
|
|
125
|
+
// record being revoked.
|
|
126
|
+
resolved = resolveVerificationKey(target.issuer, revocation.verification_method, revocation.revoked_at);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
resolved = null;
|
|
130
|
+
}
|
|
131
|
+
const keyFailure = keyResolutionFailure(resolved);
|
|
132
|
+
if (keyFailure)
|
|
133
|
+
return keyFailure;
|
|
134
|
+
if (!verifyAuthorityRevocationSignature(revocation, resolved)) {
|
|
135
|
+
return invalid('SIGNATURE_INVALID', 'Ed25519 signature is invalid');
|
|
136
|
+
}
|
|
137
|
+
return result('valid', []);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../../src/v2/authority-revocation/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { FencedWrite, FencedWriteOutcome, StateMarker } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An authority-state publication log with a fencing gate on every write.
|
|
4
|
+
*
|
|
5
|
+
* Generic in the payload on purpose: this class orders writes and stores nothing about
|
|
6
|
+
* authority itself. The payload is whatever the deployment publishes as a state view, a
|
|
7
|
+
* store handle, a snapshot identifier or a record set. The SDK has no opinion about it.
|
|
8
|
+
*
|
|
9
|
+
* The gate, in one line each:
|
|
10
|
+
*
|
|
11
|
+
* - a token BELOW the highest already accepted is refused, `stale_fencing_token`
|
|
12
|
+
* - a token EQUAL to it is accepted, because equal has not gone backwards: the same holder
|
|
13
|
+
* is retrying, and the retry is idempotent
|
|
14
|
+
* - a token ABOVE it is accepted, and so is a token the log has never seen before, as long
|
|
15
|
+
* as it does not go backwards. The gate fences state that is behind, not state that
|
|
16
|
+
* merely differs
|
|
17
|
+
* - a token counted in a DIFFERENT SCOPE from the log's is refused,
|
|
18
|
+
* `fencing_scope_mismatch`, and an absent or malformed token is refused
|
|
19
|
+
* `fencing_token_unreadable`. Two markers from different scopes order nothing, and a
|
|
20
|
+
* write path that cannot order a token is not fenced. Neither refusal is in any source;
|
|
21
|
+
* both are this module's choice, and they are kept apart because an unreadable token is
|
|
22
|
+
* a different finding from a backwards one
|
|
23
|
+
*
|
|
24
|
+
* A refused write changes nothing: not the published payload, not the highest token. That
|
|
25
|
+
* is the property the whole class exists for, and a caller reads `accepted` to learn which
|
|
26
|
+
* of the two happened rather than comparing payloads.
|
|
27
|
+
*
|
|
28
|
+
* NOT DURABLE, NOT CONCURRENT, NOT A LOCK SERVICE. This holds one token and one payload in
|
|
29
|
+
* this process's heap. It acquires no lock, contacts no lock service, and its check-then-set
|
|
30
|
+
* is one synchronous statement sequence, which is safe on this runtime and is a property of
|
|
31
|
+
* the runtime rather than a pattern a durable store may copy. The same warning
|
|
32
|
+
* `InMemoryAuthorityRevocationStore` carries applies here for the same reason.
|
|
33
|
+
*/
|
|
34
|
+
export declare class FencedAuthorityStateLog<T> {
|
|
35
|
+
private highest;
|
|
36
|
+
private payload;
|
|
37
|
+
private written;
|
|
38
|
+
/** The highest token accepted so far, or `null` when nothing has been published. */
|
|
39
|
+
highestToken(): StateMarker | null;
|
|
40
|
+
/** What is published now. `undefined` when no write has landed, which a caller must tell
|
|
41
|
+
* apart from a write that landed carrying `undefined`; `hasPublished()` is how. */
|
|
42
|
+
published(): T | undefined;
|
|
43
|
+
hasPublished(): boolean;
|
|
44
|
+
/** Submit a write. See the class doc for the four outcomes. Never throws for a malformed
|
|
45
|
+
* token: an unreadable token is one that cannot be shown to have moved forward, so it is
|
|
46
|
+
* refused. */
|
|
47
|
+
write(write: FencedWrite<T>): FencedWriteOutcome<T>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=fencing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fencing.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/fencing.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IACpC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAAQ;IAEvB,oFAAoF;IACpF,YAAY,IAAI,WAAW,GAAG,IAAI,CAEjC;IAED;wFACoF;IACpF,SAAS,IAAI,CAAC,GAAG,SAAS,CAEzB;IAED,YAAY,IAAI,OAAO,CAEtB;IAED;;mBAEe;IACf,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAmBlD;CACF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
//
|
|
4
|
+
// PROPOSED, OPT-IN. Fencing on the authority-state WRITE path.
|
|
5
|
+
// See ./types.ts for the specification position. Proposed.
|
|
6
|
+
//
|
|
7
|
+
// WHY THIS IS A SEPARATE AXIS FROM THE READ PATH. A read-side high-water mark protects one
|
|
8
|
+
// verifier that has already seen the newer state. It does nothing for a verifier that has
|
|
9
|
+
// seen nothing, reading a published view that a stale writer republished underneath it. A
|
|
10
|
+
// partition that resolves the wrong way rolls authority back with no restore involved, and
|
|
11
|
+
// the read path never sees a regression because the published state simply IS the old
|
|
12
|
+
// state. So the check has to exist where the write lands.
|
|
13
|
+
//
|
|
14
|
+
// The rule implemented here is the one Kleppmann's "How to do distributed locking" states:
|
|
15
|
+
// the storage server takes an active role in checking tokens and rejects any write on which
|
|
16
|
+
// the token has gone backwards. `OPEN-QUESTIONS.md` names authority rollback as open and
|
|
17
|
+
// names an append-only revocation log a restore must replay as the other candidate
|
|
18
|
+
// mechanism in the same sentence. That one is NOT modelled here. Neither is specified.
|
|
19
|
+
import { compareStateMarker, sameScope } from './marker.js';
|
|
20
|
+
/**
|
|
21
|
+
* An authority-state publication log with a fencing gate on every write.
|
|
22
|
+
*
|
|
23
|
+
* Generic in the payload on purpose: this class orders writes and stores nothing about
|
|
24
|
+
* authority itself. The payload is whatever the deployment publishes as a state view, a
|
|
25
|
+
* store handle, a snapshot identifier or a record set. The SDK has no opinion about it.
|
|
26
|
+
*
|
|
27
|
+
* The gate, in one line each:
|
|
28
|
+
*
|
|
29
|
+
* - a token BELOW the highest already accepted is refused, `stale_fencing_token`
|
|
30
|
+
* - a token EQUAL to it is accepted, because equal has not gone backwards: the same holder
|
|
31
|
+
* is retrying, and the retry is idempotent
|
|
32
|
+
* - a token ABOVE it is accepted, and so is a token the log has never seen before, as long
|
|
33
|
+
* as it does not go backwards. The gate fences state that is behind, not state that
|
|
34
|
+
* merely differs
|
|
35
|
+
* - a token counted in a DIFFERENT SCOPE from the log's is refused,
|
|
36
|
+
* `fencing_scope_mismatch`, and an absent or malformed token is refused
|
|
37
|
+
* `fencing_token_unreadable`. Two markers from different scopes order nothing, and a
|
|
38
|
+
* write path that cannot order a token is not fenced. Neither refusal is in any source;
|
|
39
|
+
* both are this module's choice, and they are kept apart because an unreadable token is
|
|
40
|
+
* a different finding from a backwards one
|
|
41
|
+
*
|
|
42
|
+
* A refused write changes nothing: not the published payload, not the highest token. That
|
|
43
|
+
* is the property the whole class exists for, and a caller reads `accepted` to learn which
|
|
44
|
+
* of the two happened rather than comparing payloads.
|
|
45
|
+
*
|
|
46
|
+
* NOT DURABLE, NOT CONCURRENT, NOT A LOCK SERVICE. This holds one token and one payload in
|
|
47
|
+
* this process's heap. It acquires no lock, contacts no lock service, and its check-then-set
|
|
48
|
+
* is one synchronous statement sequence, which is safe on this runtime and is a property of
|
|
49
|
+
* the runtime rather than a pattern a durable store may copy. The same warning
|
|
50
|
+
* `InMemoryAuthorityRevocationStore` carries applies here for the same reason.
|
|
51
|
+
*/
|
|
52
|
+
export class FencedAuthorityStateLog {
|
|
53
|
+
highest = null;
|
|
54
|
+
payload = undefined;
|
|
55
|
+
written = false;
|
|
56
|
+
/** The highest token accepted so far, or `null` when nothing has been published. */
|
|
57
|
+
highestToken() {
|
|
58
|
+
return this.highest;
|
|
59
|
+
}
|
|
60
|
+
/** What is published now. `undefined` when no write has landed, which a caller must tell
|
|
61
|
+
* apart from a write that landed carrying `undefined`; `hasPublished()` is how. */
|
|
62
|
+
published() {
|
|
63
|
+
return this.payload;
|
|
64
|
+
}
|
|
65
|
+
hasPublished() {
|
|
66
|
+
return this.written;
|
|
67
|
+
}
|
|
68
|
+
/** Submit a write. See the class doc for the four outcomes. Never throws for a malformed
|
|
69
|
+
* token: an unreadable token is one that cannot be shown to have moved forward, so it is
|
|
70
|
+
* refused. */
|
|
71
|
+
write(write) {
|
|
72
|
+
const token = write?.token;
|
|
73
|
+
// Read the token on its own first. An unreadable token is a different finding from a
|
|
74
|
+
// stale one, and collapsing them would report a backwards move that never happened.
|
|
75
|
+
if (compareStateMarker(token, token) !== 'forward') {
|
|
76
|
+
return { accepted: false, code: 'fencing_token_unreadable', published: this.highest };
|
|
77
|
+
}
|
|
78
|
+
if (this.highest !== null) {
|
|
79
|
+
if (!sameScope(this.highest, token)) {
|
|
80
|
+
return { accepted: false, code: 'fencing_scope_mismatch', published: this.highest };
|
|
81
|
+
}
|
|
82
|
+
if (compareStateMarker(this.highest, token) !== 'forward') {
|
|
83
|
+
return { accepted: false, code: 'stale_fencing_token', published: this.highest };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this.highest = token;
|
|
87
|
+
this.payload = write.payload;
|
|
88
|
+
this.written = true;
|
|
89
|
+
return { accepted: true, published: token, payload: write.payload };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=fencing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fencing.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/fencing.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,+DAA+D;AAC/D,2DAA2D;AAC3D,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,0FAA0F;AAC1F,2FAA2F;AAC3F,sFAAsF;AACtF,0DAA0D;AAC1D,EAAE;AACF,2FAA2F;AAC3F,4FAA4F;AAC5F,yFAAyF;AACzF,mFAAmF;AACnF,uFAAuF;AAEvF,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,OAAO,uBAAuB;IAC1B,OAAO,GAAuB,IAAI,CAAA;IAClC,OAAO,GAAkB,SAAS,CAAA;IAClC,OAAO,GAAG,KAAK,CAAA;IAEvB,oFAAoF;IACpF,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;wFACoF;IACpF,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;mBAEe;IACf,KAAK,CAAC,KAAqB;QACzB,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAA;QAC1B,qFAAqF;QACrF,oFAAoF;QACpF,IAAI,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;QACvF,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;YACrF,CAAC;YACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;YAClF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;IACrE,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/index.ts"],"names":[],"mappings":"AAQA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright (c) 2026 Tymofii Pidlisnyi
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
//
|
|
4
|
+
// PROPOSED, OPT-IN authority state markers, write fencing and revocation withdrawal.
|
|
5
|
+
// Nothing here is required by draft-pidlisnyi-aps-03 and nothing here changes any existing
|
|
6
|
+
// exported behaviour. Concept source: aeoess/agent-authority-lifecycle, invariant candidates
|
|
7
|
+
// CAND-08 and CAND-02.
|
|
8
|
+
export * from './types.js';
|
|
9
|
+
export * from './marker.js';
|
|
10
|
+
export * from './retained.js';
|
|
11
|
+
export * from './fencing.js';
|
|
12
|
+
export * from './withdrawal.js';
|
|
13
|
+
export * from './report.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,qFAAqF;AACrF,2FAA2F;AAC3F,6FAA6F;AAC7F,uBAAuB;AAEvB,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type MonotonicityOutcome, type StateMarker, type StateMarkerScope, type UnplaceableDisposition } from './types.js';
|
|
2
|
+
/** Thrown when a caller asks for a marker the vocabulary does not allow. A shape rule
|
|
3
|
+
* broken at construction is a programming error, not a verdict. Mirrors
|
|
4
|
+
* `LifecycleStateError` in src/v2/lifecycle-state/. */
|
|
5
|
+
export declare class AuthorityStateError extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
constructor(code: string, message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function isStateMarkerScope(value: unknown): value is StateMarkerScope;
|
|
10
|
+
export declare function isMonotonicityOutcome(value: unknown): value is MonotonicityOutcome;
|
|
11
|
+
export declare function isUnplaceableDisposition(value: unknown): value is UnplaceableDisposition;
|
|
12
|
+
export interface StateMarkerInput {
|
|
13
|
+
readonly value: string;
|
|
14
|
+
readonly scope: StateMarkerScope;
|
|
15
|
+
readonly scope_ref?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build a `StateMarker`, enforcing its shape rules.
|
|
19
|
+
*
|
|
20
|
+
* 1. `value` is a canonical unsigned decimal integer, as a string. A number would lose
|
|
21
|
+
* exactness past 2^53 - 1 and would admit `1.0`, `1e3` and `-1`, none of which orders
|
|
22
|
+
* the way a generation counter has to.
|
|
23
|
+
* 2. `scope` is one of the four. There is no fifth and there is no default: which thing a
|
|
24
|
+
* generation is counted within is the choice the proposed text does not make, so it has
|
|
25
|
+
* to be stated rather than assumed.
|
|
26
|
+
* 3. `scope_ref` is present and non-empty exactly when `scope` is not `global`. A
|
|
27
|
+
* per-delegation marker that does not say which delegation cannot be compared against
|
|
28
|
+
* anything.
|
|
29
|
+
*
|
|
30
|
+
* Proposed. Concept source: aeoess/agent-authority-lifecycle, `Authority epoch`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stateMarker(input: StateMarkerInput): StateMarker;
|
|
33
|
+
/** Whether two markers are counted in the same thing and can therefore be ordered. */
|
|
34
|
+
export declare function sameScope(a: StateMarker, b: StateMarker): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Place a presented marker against what a verifier has established.
|
|
37
|
+
*
|
|
38
|
+
* | established | presented | outcome |
|
|
39
|
+
* |-------------|--------------------|---------------|
|
|
40
|
+
* | `null` | any | `unplaceable` |
|
|
41
|
+
* | any | `null` | `unplaceable` |
|
|
42
|
+
* | any | a different scope | `unplaceable` |
|
|
43
|
+
* | m | >= m | `forward` |
|
|
44
|
+
* | m | < m | `regressed` |
|
|
45
|
+
*
|
|
46
|
+
* Equal is `forward`, not a third thing: a view that has not moved has not gone backwards.
|
|
47
|
+
*
|
|
48
|
+
* `unplaceable` is where the honesty of the whole module sits. It is returned for a first
|
|
49
|
+
* read and for a cross-scope comparison, it is NOT a verdict, and nothing downstream turns
|
|
50
|
+
* it into one on its own. The proposed text gives a verifier with no prior observation
|
|
51
|
+
* nothing to compare against and does not say whether such a read is trusted or refused.
|
|
52
|
+
*
|
|
53
|
+
* Comparison is integer, through BigInt, never lexical: "10" is after "9".
|
|
54
|
+
*
|
|
55
|
+
* Never throws for a malformed marker. A marker this function cannot read is one it cannot
|
|
56
|
+
* place, which is `unplaceable`, and throwing on the read path of a state comparison would
|
|
57
|
+
* turn a data problem into a crash in a verifier.
|
|
58
|
+
*/
|
|
59
|
+
export declare function compareStateMarker(established: StateMarker | null | undefined, presented: StateMarker | null | undefined): MonotonicityOutcome;
|
|
60
|
+
/**
|
|
61
|
+
* The high-water mark a verifier holds after reading a presented view.
|
|
62
|
+
*
|
|
63
|
+
* It only ever moves forward. A regressed view does not lower it, an unplaceable view does
|
|
64
|
+
* not replace it, and a verifier that had none adopts the presented one. This is the
|
|
65
|
+
* "monotonicity against what the verifier has established" limb of CAND-08, which is
|
|
66
|
+
* weaker than a rule against global truth and is the honest strength available: a verifier
|
|
67
|
+
* that has never seen the newer state cannot detect a regression and is not at fault.
|
|
68
|
+
*/
|
|
69
|
+
export declare function advanceHighWaterMark(established: StateMarker | null | undefined, presented: StateMarker | null | undefined): StateMarker | null;
|
|
70
|
+
//# sourceMappingURL=marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/marker.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC5B,MAAM,YAAY,CAAA;AAEnB;;wDAEwD;AACxD,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAIxC;CACF;AAMD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAElF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAExF;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAgChE;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,OAAO,CAEjE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,SAAS,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACxC,mBAAmB,CAMrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EAC3C,SAAS,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GACxC,WAAW,GAAG,IAAI,CAIpB"}
|