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/dist/runtime.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import { AuditStore, GrantStore, LimitStore, ManifestStore, PendingRequest, PendingStore, ReplayStore } from "./stores.js";
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
  }