ccp-core 0.4.0 → 0.5.1
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/README.md +49 -2
- package/dist/decision.d.ts +2 -1
- package/dist/decision.js +7 -2
- package/dist/grants.d.ts +6 -0
- package/dist/grants.js +3 -3
- package/dist/identity.d.ts +150 -0
- package/dist/identity.js +495 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/requester.js +1 -1
- package/dist/runtime.d.ts +157 -6
- package/dist/runtime.js +437 -18
- package/package.json +1 -1
package/dist/runtime.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type VerifiedManifest } from "./consumer.js";
|
|
2
|
+
import { type AdmissionRequest, type AdmissionResult, type VerifiedIdentity, type VerifiedPolicy, type VerifyIdentityOptions } from "./identity.js";
|
|
3
|
+
import { AuditStore, Grant, GrantStore, LimitStore, ManifestStore, PendingRequest, PendingStore, ReplayStore } from "./stores.js";
|
|
2
4
|
import { utcnow } from "./time.js";
|
|
3
5
|
export { utcnow };
|
|
4
6
|
export interface Decision {
|
|
@@ -18,23 +20,80 @@ export declare class SchemaRegistry {
|
|
|
18
20
|
}
|
|
19
21
|
export type IntentExecutor = (params: any, access: HostAccess) => any;
|
|
20
22
|
export type HostFunction = (...args: any[]) => any;
|
|
23
|
+
export type HostClass = "read" | "write" | "disclose" | "control" | "compute";
|
|
24
|
+
export type HostRisk = "read" | "write" | "disclose" | "irreversible";
|
|
25
|
+
export type HostPlacement = "local" | "remote" | "delegated";
|
|
26
|
+
export type ConfirmationFloor = "none" | "per_action";
|
|
27
|
+
export type Idempotency = "pure" | "caller_key" | "atomic" | "none";
|
|
28
|
+
/**
|
|
29
|
+
* A host contract (§26.4). Core hosts may omit it; every extension host must
|
|
30
|
+
* declare at least `class`, which fixes the risk and confirmation floor.
|
|
31
|
+
*/
|
|
32
|
+
export interface HostProfile {
|
|
33
|
+
class?: HostClass;
|
|
34
|
+
risk?: HostRisk;
|
|
35
|
+
minConfirmation?: ConfirmationFloor;
|
|
36
|
+
idempotency?: Idempotency;
|
|
37
|
+
/** May this host send data off the device? Defaults to false. */
|
|
38
|
+
network?: boolean;
|
|
39
|
+
/** Placements this host can serve. Defaults to `["local"]`. */
|
|
40
|
+
placement?: HostPlacement[];
|
|
41
|
+
/** Data categories this host may transmit. Defaults to none. */
|
|
42
|
+
fields?: string[];
|
|
43
|
+
}
|
|
44
|
+
export interface NormalizedHostProfile {
|
|
45
|
+
class: HostClass;
|
|
46
|
+
risk: HostRisk;
|
|
47
|
+
minConfirmation: ConfirmationFloor;
|
|
48
|
+
idempotency: Idempotency;
|
|
49
|
+
network: boolean;
|
|
50
|
+
placement: HostPlacement[];
|
|
51
|
+
fields: string[];
|
|
52
|
+
}
|
|
53
|
+
interface HostEntry {
|
|
54
|
+
fn: HostFunction;
|
|
55
|
+
profile: NormalizedHostProfile;
|
|
56
|
+
}
|
|
57
|
+
/** The only hosts that may be registered without an explicit profile. */
|
|
58
|
+
export declare const CORE_HOSTS: ReadonlySet<string>;
|
|
59
|
+
export declare class HostProfileError extends Error {
|
|
60
|
+
readonly code = "invalid_request";
|
|
61
|
+
constructor(message: string);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate and normalize a host profile (§26.4).
|
|
65
|
+
*
|
|
66
|
+
* Extension hosts (anything outside the core six) must declare a class; the
|
|
67
|
+
* rest of the contract follows from it unless explicitly overridden. A
|
|
68
|
+
* `write`, `control`, or `compute` host can never suppress confirmation, and
|
|
69
|
+
* an `irreversible` risk cannot either.
|
|
70
|
+
*/
|
|
71
|
+
export declare function validateHostProfile(name: string, profile?: HostProfile): NormalizedHostProfile;
|
|
72
|
+
/** The grant's data-egress ceiling, enforced on every host call. */
|
|
73
|
+
export interface EgressPolicy {
|
|
74
|
+
network: boolean;
|
|
75
|
+
fields: ReadonlySet<string>;
|
|
76
|
+
}
|
|
21
77
|
export declare class HostAccess {
|
|
22
78
|
private readonly registry;
|
|
79
|
+
private readonly policy;
|
|
23
80
|
private _granted;
|
|
24
|
-
constructor(registry: HostRegistry, granted: string[]);
|
|
81
|
+
constructor(registry: HostRegistry, granted: string[], policy?: EgressPolicy);
|
|
25
82
|
call(name: string, ...args: any[]): any;
|
|
26
83
|
has(name: string): boolean;
|
|
27
84
|
}
|
|
28
85
|
export declare class HostRegistry {
|
|
29
86
|
private _hosts;
|
|
30
87
|
private _intents;
|
|
31
|
-
registerHost(name: string, fn: HostFunction): void;
|
|
88
|
+
registerHost(name: string, fn: HostFunction, profile?: HostProfile): void;
|
|
32
89
|
registerIntent(name: string, fn: IntentExecutor): void;
|
|
33
90
|
host(name: string): HostFunction | undefined;
|
|
91
|
+
/** Metadata used to enforce placement, egress, and confirmation (§12). */
|
|
92
|
+
hostMeta(name: string): HostEntry | undefined;
|
|
34
93
|
hasHost(name: string): boolean;
|
|
35
94
|
intent(name: string): IntentExecutor | undefined;
|
|
36
95
|
hasIntent(name: string): boolean;
|
|
37
|
-
access(granted: string[]): HostAccess;
|
|
96
|
+
access(granted: string[], policy?: EgressPolicy): HostAccess;
|
|
38
97
|
}
|
|
39
98
|
export interface RuntimeOptions {
|
|
40
99
|
grants?: GrantStore;
|
|
@@ -46,7 +105,28 @@ export interface RuntimeOptions {
|
|
|
46
105
|
hosts?: HostRegistry;
|
|
47
106
|
audit?: AuditStore;
|
|
48
107
|
clock?: () => string;
|
|
49
|
-
supportedCcp?: string;
|
|
108
|
+
supportedCcp?: string | readonly string[];
|
|
109
|
+
}
|
|
110
|
+
export interface AdmitRequestOptions {
|
|
111
|
+
policy: VerifiedPolicy;
|
|
112
|
+
request: AdmissionRequest;
|
|
113
|
+
/** Verified provider manifest that defines the admitted intent. */
|
|
114
|
+
manifest: VerifiedManifest | string;
|
|
115
|
+
confirmation?: Record<string, "none" | "per_action">;
|
|
116
|
+
}
|
|
117
|
+
export interface AdmitRequestResult {
|
|
118
|
+
result: AdmissionResult;
|
|
119
|
+
grant?: Grant;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Reserved suspension reason for a requester key change (§7.4). A grant
|
|
123
|
+
* suspended this way cannot be resumed; the consumer re-introduces the
|
|
124
|
+
* contact and creates a new grant.
|
|
125
|
+
*/
|
|
126
|
+
export declare const IDENTITY_CHANGED_REASON = "identity_changed";
|
|
127
|
+
export interface VerifyContactOptions extends VerifyIdentityOptions {
|
|
128
|
+
/** Local contact the document is being verified for. */
|
|
129
|
+
contactId: string;
|
|
50
130
|
}
|
|
51
131
|
export declare class Runtime {
|
|
52
132
|
readonly grants: GrantStore;
|
|
@@ -55,7 +135,7 @@ export declare class Runtime {
|
|
|
55
135
|
readonly hosts: HostRegistry;
|
|
56
136
|
readonly audit: AuditStore;
|
|
57
137
|
readonly clock: () => string;
|
|
58
|
-
readonly supportedCcp: string;
|
|
138
|
+
readonly supportedCcp: string | readonly string[];
|
|
59
139
|
readonly replay: ReplayStore;
|
|
60
140
|
readonly limits: LimitStore;
|
|
61
141
|
readonly pendingStore: PendingStore;
|
|
@@ -63,7 +143,78 @@ export declare class Runtime {
|
|
|
63
143
|
submit(document: string, publicKey: Uint8Array): Promise<Decision>;
|
|
64
144
|
confirm(pendingId: string, approved: boolean): Promise<Decision>;
|
|
65
145
|
pending(pendingId: string): Promise<PendingRequest | undefined>;
|
|
146
|
+
/**
|
|
147
|
+
* Pause one grant (§9.4.1). Configuration, limits, and history are kept.
|
|
148
|
+
*/
|
|
149
|
+
pauseGrant(id: string, reason?: string): Promise<Grant>;
|
|
150
|
+
/**
|
|
151
|
+
* Suspend one grant (§9.4.2). Used for security events such as a requester
|
|
152
|
+
* key change; resumption requires an explicit `resumeGrant`.
|
|
153
|
+
*/
|
|
154
|
+
suspendGrant(id: string, reason?: string): Promise<Grant>;
|
|
155
|
+
/**
|
|
156
|
+
* Resume a paused or suspended grant (§9.4.3).
|
|
157
|
+
*
|
|
158
|
+
* Re-checks revocation, expiry, and the approved manifest before restoring
|
|
159
|
+
* authority. A revoked or expired grant cannot be resumed.
|
|
160
|
+
*/
|
|
161
|
+
resumeGrant(id: string): Promise<Grant>;
|
|
162
|
+
/**
|
|
163
|
+
* Revoke one grant by id (§9.4.4). Permanent: the grant is not resumable and
|
|
164
|
+
* a new approval is required.
|
|
165
|
+
*
|
|
166
|
+
* Policy-created grants reuse their deterministic id, so revoking here also
|
|
167
|
+
* stops an admission rule from re-creating the same access (§25.8.3).
|
|
168
|
+
*/
|
|
169
|
+
revokeGrant(id: string, reason?: string): Promise<Grant>;
|
|
170
|
+
/**
|
|
171
|
+
* Suspend every active grant bound to a contact (§7.4, §9.4.2).
|
|
172
|
+
* Returns the number of grants affected.
|
|
173
|
+
*/
|
|
174
|
+
suspendContact(contactId: string, reason?: string): Promise<number>;
|
|
175
|
+
/**
|
|
176
|
+
* Verify an identity document for a known contact (§7.4, §25.8.4).
|
|
177
|
+
*
|
|
178
|
+
* On `identity_changed` — a valid signature from a different key — the
|
|
179
|
+
* contact's grants are suspended before the error is rethrown. A bad
|
|
180
|
+
* signature never suspends anything, so an attacker cannot force a
|
|
181
|
+
* suspension by sending garbage.
|
|
182
|
+
*/
|
|
183
|
+
verifyContactIdentity(document: string, options: VerifyContactOptions): Promise<VerifiedIdentity>;
|
|
184
|
+
/**
|
|
185
|
+
* Admit a request under a reviewed policy (§25.8.3).
|
|
186
|
+
*
|
|
187
|
+
* `allow` creates or reuses the grant with the policy's deterministic id,
|
|
188
|
+
* records the admitting rule in the audit log, and leaves the request to
|
|
189
|
+
* proceed through `submit` normally. Revoked ids are consulted from the
|
|
190
|
+
* grant store, so a revocation is never undone here.
|
|
191
|
+
*/
|
|
192
|
+
admitRequest(options: AdmitRequestOptions): Promise<AdmitRequestResult>;
|
|
193
|
+
/**
|
|
194
|
+
* Resolve the grant for this request.
|
|
195
|
+
*
|
|
196
|
+
* A requester may hold several grants over one manifest digest (for
|
|
197
|
+
* example, a manual grant and a policy-created one). The store lookup is
|
|
198
|
+
* the fast path; when it lands on a grant that does not enable the intent,
|
|
199
|
+
* prefer a grant that does. Revocation remains per grant (§25.8.3).
|
|
200
|
+
*/
|
|
201
|
+
private resolveGrant;
|
|
202
|
+
private transition;
|
|
203
|
+
private setGrantState;
|
|
66
204
|
private execute;
|
|
205
|
+
/**
|
|
206
|
+
* Enforce the grant's placement and egress ceilings before execution (§12).
|
|
207
|
+
* A host that needs network access cannot run under a grant that denies it.
|
|
208
|
+
*/
|
|
209
|
+
private deploymentError;
|
|
210
|
+
/** True when a required host declares a per-action confirmation floor. */
|
|
211
|
+
private hostFloor;
|
|
212
|
+
private egressPolicy;
|
|
67
213
|
private grantStateError;
|
|
214
|
+
/**
|
|
215
|
+
* Surface a recorded pause/suspend/revoke reason (§9.4.2). The reason is
|
|
216
|
+
* local and must not contain secrets; hosts choose what to record.
|
|
217
|
+
*/
|
|
218
|
+
private stateDetail;
|
|
68
219
|
private reject;
|
|
69
220
|
}
|