@aws/dogwood-wasm 0.0.0-stage → 1.1.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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +217 -2
- package/THIRD-PARTY-NOTICES +4960 -0
- package/dogwood_wasm.d.ts +597 -0
- package/dogwood_wasm.js +895 -0
- package/dogwood_wasm_bg.wasm +0 -0
- package/package.json +18 -4
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A Dogwood field value. JSON values map to their Dogwood counterparts;
|
|
6
|
+
* non-integer numbers become decimals. Two tagged forms cover what JSON
|
|
7
|
+
* cannot express:
|
|
8
|
+
*
|
|
9
|
+
* - `{ __entity: { type, id } }` — an entity reference
|
|
10
|
+
* - `{ __decimal: "1.50" }` — a decimal with exact text preserved (a JS
|
|
11
|
+
* number would round-trip `1.50` as `1.5`)
|
|
12
|
+
*/
|
|
13
|
+
export type DogwoodValue =
|
|
14
|
+
| null
|
|
15
|
+
| boolean
|
|
16
|
+
| number
|
|
17
|
+
| string
|
|
18
|
+
| DogwoodValue[]
|
|
19
|
+
| { __entity: EntityRef }
|
|
20
|
+
| { __decimal: string }
|
|
21
|
+
| { [key: string]: DogwoodValue };
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/** How the plain-text renderer lays out a phrase's children (a hint only). */
|
|
26
|
+
export type Layout = "Inline" | "Block" | "Hanging";
|
|
27
|
+
/** One node of an informalized policy: `template` has `{0}`, `{1}`, … slots for `children`. */
|
|
28
|
+
export interface Phrase {
|
|
29
|
+
template: string;
|
|
30
|
+
children: Phrase[];
|
|
31
|
+
/** `[start, end)` byte range of the originating `.dw` node; absent for synthesized framing. */
|
|
32
|
+
span?: [number, number];
|
|
33
|
+
layout: Layout;
|
|
34
|
+
}
|
|
35
|
+
/** A policy set's informalization: an optional event-schema preamble, then one phrase tree per rule. */
|
|
36
|
+
export interface Informalization {
|
|
37
|
+
/** Event-schema pins that restrict every temporal clause; absent if none apply. */
|
|
38
|
+
preamble?: Phrase;
|
|
39
|
+
rules: Phrase[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/** The structured payload attached to a thrown Dogwood error as `.diagnostic`. */
|
|
45
|
+
export interface DogwoodDiagnostic {
|
|
46
|
+
severity: Severity;
|
|
47
|
+
code?: string;
|
|
48
|
+
message: string;
|
|
49
|
+
labels?: Label[];
|
|
50
|
+
help?: string;
|
|
51
|
+
spanned: boolean;
|
|
52
|
+
/** Follow-on findings (e.g. the 2nd..Nth of a batch of parse errors). */
|
|
53
|
+
related?: Diagnostic[];
|
|
54
|
+
}
|
|
55
|
+
export interface DogwoodError extends Error {
|
|
56
|
+
diagnostic: DogwoodDiagnostic;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A per-policy summary from a successful parse (pre-lowering, schema-free).
|
|
62
|
+
*/
|
|
63
|
+
export interface PolicySummary {
|
|
64
|
+
/**
|
|
65
|
+
* Number of `temporal { … }` leaves in the policy.
|
|
66
|
+
*/
|
|
67
|
+
temporal_count: number;
|
|
68
|
+
/**
|
|
69
|
+
* Whether the policy uses any temporal clause.
|
|
70
|
+
*/
|
|
71
|
+
uses_temporal: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Every information-provider invocation, as `Ns::Fn` keys.
|
|
74
|
+
*/
|
|
75
|
+
provider_invocations: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Provider invocations naming a provider not declared in the service
|
|
78
|
+
* schema — a pre-lowering warning surfaced structurally.
|
|
79
|
+
*/
|
|
80
|
+
undeclared_providers: string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A structured entity reference, deserialized from `{ type, id }`.
|
|
85
|
+
*/
|
|
86
|
+
export interface EntityRef {
|
|
87
|
+
/**
|
|
88
|
+
* Entity type, namespace included (`"Drupe::User"`).
|
|
89
|
+
*/
|
|
90
|
+
type: string;
|
|
91
|
+
/**
|
|
92
|
+
* The raw, un-escaped entity id.
|
|
93
|
+
*/
|
|
94
|
+
id: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* One decision point's verdict, with its determining rules and any evaluation
|
|
99
|
+
* errors. History-only events (which yield no decision) contribute no entry.
|
|
100
|
+
*/
|
|
101
|
+
export interface TimepointVerdict {
|
|
102
|
+
/**
|
|
103
|
+
* 0-based index of this decision point in the decision stream.
|
|
104
|
+
*/
|
|
105
|
+
index: number;
|
|
106
|
+
/**
|
|
107
|
+
* The event's wall-clock timestamp.
|
|
108
|
+
*/
|
|
109
|
+
timestamp: number;
|
|
110
|
+
verdict: Verdict;
|
|
111
|
+
/**
|
|
112
|
+
* The `.dw` rule indices that determined the decision (empty for an
|
|
113
|
+
* implicit deny).
|
|
114
|
+
*/
|
|
115
|
+
determining_rules: number[];
|
|
116
|
+
/**
|
|
117
|
+
* Any evaluation errors folded into this decision (a fail-closed deny
|
|
118
|
+
* carries them here).
|
|
119
|
+
*/
|
|
120
|
+
errors: string[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* One diagnostic finding, owned and serializable — the CLI's projection of
|
|
125
|
+
* a frontend `miette::Diagnostic`. Used for the non-fatal channel (validation
|
|
126
|
+
* errors/warnings); the fatal channel is [`OpError`], which wraps one of
|
|
127
|
+
* these plus the source text for rendering.
|
|
128
|
+
*/
|
|
129
|
+
export interface Diagnostic {
|
|
130
|
+
severity: Severity;
|
|
131
|
+
/**
|
|
132
|
+
* The diagnostic's stable code (e.g. `"temporal"`), if it has one.
|
|
133
|
+
*/
|
|
134
|
+
code?: string;
|
|
135
|
+
message: string;
|
|
136
|
+
/**
|
|
137
|
+
* The labelled spans, in the order the diagnostic reports them. Empty for
|
|
138
|
+
* a span-less finding (e.g. an event-schema error that carries only a
|
|
139
|
+
* message).
|
|
140
|
+
*/
|
|
141
|
+
labels: Label[];
|
|
142
|
+
help?: string;
|
|
143
|
+
/**
|
|
144
|
+
* Whether this finding has any source-anchored span. `false` means the CLI
|
|
145
|
+
* cannot underline a snippet for it — only the message is available.
|
|
146
|
+
*/
|
|
147
|
+
spanned: boolean;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* One entity supplied to a decision: its identity plus the attributes and
|
|
152
|
+
* direct parents a policy may read (`principal.dept`, `principal in Group`).
|
|
153
|
+
*/
|
|
154
|
+
export interface EntityInput {
|
|
155
|
+
/**
|
|
156
|
+
* Entity type, namespace included (`"Drupe::User"`).
|
|
157
|
+
*/
|
|
158
|
+
type: string;
|
|
159
|
+
/**
|
|
160
|
+
* The raw, un-escaped entity id.
|
|
161
|
+
*/
|
|
162
|
+
id: string;
|
|
163
|
+
/**
|
|
164
|
+
* Attributes, `name -> value`. Validated against the action schema at
|
|
165
|
+
* decision time, so a wrong-typed attribute fails closed.
|
|
166
|
+
*/
|
|
167
|
+
attrs?: Record<string, DogwoodValue>;
|
|
168
|
+
/**
|
|
169
|
+
* **Direct** parents (`memberOf` edges). Cedar computes the transitive
|
|
170
|
+
* closure, so only direct parents are supplied.
|
|
171
|
+
*/
|
|
172
|
+
parents?: EntityRef[];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* One event fed to a [`DogwoodAuthorizer`] — the JS analog of the frontend's
|
|
177
|
+
* `Event`, and a mirror of the `.log` wire format's components.
|
|
178
|
+
*/
|
|
179
|
+
export interface EventInput {
|
|
180
|
+
/**
|
|
181
|
+
* The **fully qualified** Cedar action id — `"Drupe::Action::Read"`.
|
|
182
|
+
* Split on the **last** `::`, so an action id containing an interior `::`
|
|
183
|
+
* is not supported (Cedar permits it; Dogwood's own `Event::builder` has
|
|
184
|
+
* the same restriction).
|
|
185
|
+
*
|
|
186
|
+
* Must name an action the schema declares — see
|
|
187
|
+
* [`actions`](DogwoodAuthorizer::actions). A *bare* id (`"Read"`) would
|
|
188
|
+
* otherwise parse and then not resolve, denying with an empty
|
|
189
|
+
* [`errors`](AuthorizerDecision::errors) and so being indistinguishable
|
|
190
|
+
* from "policy said no"; it is rejected instead, with the qualified id
|
|
191
|
+
* suggested.
|
|
192
|
+
*/
|
|
193
|
+
action: string;
|
|
194
|
+
/**
|
|
195
|
+
* The event kind. `"request"` (the default) is a decision point;
|
|
196
|
+
* `"response"` / `"error"` are history-only — they update temporal state
|
|
197
|
+
* and return `undefined`. Which kinds exist, and which decide, is set by
|
|
198
|
+
* the event schema — see [`eventKinds`](DogwoodAuthorizer::event_kinds) and
|
|
199
|
+
* [`decisionKinds`](DogwoodAuthorizer::decision_kinds).
|
|
200
|
+
*
|
|
201
|
+
* A kind the schema does not declare is **rejected**. Left to the engine it
|
|
202
|
+
* would be treated as history-only, so a typo (`"requst"`) would silently
|
|
203
|
+
* yield no decision forever instead of failing loudly.
|
|
204
|
+
*/
|
|
205
|
+
kind?: string;
|
|
206
|
+
/**
|
|
207
|
+
* Wall-clock timestamp, in **seconds** — the unit the temporal windows are
|
|
208
|
+
* defined in (`1h` is 3600). From JS that means
|
|
209
|
+
* `Math.floor(Date.now() / 1000)`, *not* `Date.now()`: passing
|
|
210
|
+
* milliseconds silently inflates every window by 1000×, so a `within 1h`
|
|
211
|
+
* predicate would match only events from the last 3.6 seconds.
|
|
212
|
+
*
|
|
213
|
+
* Timestamps order events for the temporal operators, so this must be
|
|
214
|
+
* **non-decreasing** across calls on one instance — one instance is one
|
|
215
|
+
* ordered history. A timestamp before the previous event's is rejected
|
|
216
|
+
* rather than silently producing wrong temporal answers; see
|
|
217
|
+
* [`lastTimestamp`](DogwoodAuthorizer::last_timestamp).
|
|
218
|
+
*/
|
|
219
|
+
timestamp?: number;
|
|
220
|
+
/**
|
|
221
|
+
* The request principal. Setting it makes the event request-wrapping.
|
|
222
|
+
*/
|
|
223
|
+
principal?: EntityRef;
|
|
224
|
+
/**
|
|
225
|
+
* The request resource. Setting it makes the event request-wrapping.
|
|
226
|
+
*/
|
|
227
|
+
resource?: EntityRef;
|
|
228
|
+
/**
|
|
229
|
+
* The **durable temporal record**: `group -> { name -> value }`, read by
|
|
230
|
+
* temporal predicates in later events. Distinct from
|
|
231
|
+
* [`context`](Self::context) — see the module docs.
|
|
232
|
+
*/
|
|
233
|
+
logged?: Record<string, Record<string, DogwoodValue>>;
|
|
234
|
+
/**
|
|
235
|
+
* The **per-decision Cedar request context**: `group -> { name -> value }`,
|
|
236
|
+
* read by a policy as `context.<group>.<name>`. Never persisted.
|
|
237
|
+
*/
|
|
238
|
+
context?: Record<string, Record<string, DogwoodValue>>;
|
|
239
|
+
/**
|
|
240
|
+
* The entity store for this decision — attributes and hierarchy for any
|
|
241
|
+
* entity the policy names.
|
|
242
|
+
*/
|
|
243
|
+
entities?: EntityInput[];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* One labelled span within the source a diagnostic points at: a byte range
|
|
248
|
+
* and an optional per-label message. Offsets index the `.dw` (or schema)
|
|
249
|
+
* source text the CLI passed in.
|
|
250
|
+
*/
|
|
251
|
+
export interface Label {
|
|
252
|
+
/**
|
|
253
|
+
* Byte offset of the label's start in the source.
|
|
254
|
+
*/
|
|
255
|
+
start: number;
|
|
256
|
+
/**
|
|
257
|
+
* Byte length of the labelled span.
|
|
258
|
+
*/
|
|
259
|
+
len: number;
|
|
260
|
+
/**
|
|
261
|
+
* The label's own message, if it carries one.
|
|
262
|
+
*/
|
|
263
|
+
message?: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* The Cedar artifacts produced by lowering a `.dw` policy set.
|
|
268
|
+
*/
|
|
269
|
+
export interface LowerArtifacts {
|
|
270
|
+
/**
|
|
271
|
+
* The lowered Cedar policies, rendered to `.cedar` text.
|
|
272
|
+
*/
|
|
273
|
+
cedar_policies: string;
|
|
274
|
+
/**
|
|
275
|
+
* The augmented Cedar action schema, as `.cedarschema` text.
|
|
276
|
+
*/
|
|
277
|
+
cedar_schema: string;
|
|
278
|
+
/**
|
|
279
|
+
* The augmented schema in Cedar JSON form.
|
|
280
|
+
*/
|
|
281
|
+
cedar_schema_json: string;
|
|
282
|
+
/**
|
|
283
|
+
* Whether the exported Cedar fully reproduces the policy semantics.
|
|
284
|
+
* `false` when temporal/provider fields were hoisted (those need Dogwood
|
|
285
|
+
* at authorize time — the Cedar alone is not self-sufficient).
|
|
286
|
+
*/
|
|
287
|
+
self_contained: boolean;
|
|
288
|
+
/**
|
|
289
|
+
* The hoisted temporal leaf ids (`context.<id>` slots), for reference.
|
|
290
|
+
*/
|
|
291
|
+
temporal_fields: string[];
|
|
292
|
+
/**
|
|
293
|
+
* The hoisted provider field ids (`context.providers.<id>` slots).
|
|
294
|
+
*/
|
|
295
|
+
provider_fields: string[];
|
|
296
|
+
/**
|
|
297
|
+
* The event kinds that are decision points.
|
|
298
|
+
*/
|
|
299
|
+
decision_kinds: string[];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* The decision for one event: the verdict plus why.
|
|
304
|
+
*/
|
|
305
|
+
export interface AuthorizerDecision {
|
|
306
|
+
/**
|
|
307
|
+
* 0-based index of this decision in the authorizer's decision stream
|
|
308
|
+
* (history-only events do not advance it).
|
|
309
|
+
*/
|
|
310
|
+
index: number;
|
|
311
|
+
/**
|
|
312
|
+
* The event's timestamp, echoed back.
|
|
313
|
+
*/
|
|
314
|
+
timestamp: number;
|
|
315
|
+
verdict: Verdict;
|
|
316
|
+
/**
|
|
317
|
+
* `true` exactly when `verdict === "allow"`: the policy allowed **and**
|
|
318
|
+
* evaluation raised no errors. Stricter than Dogwood's own
|
|
319
|
+
* `Response::allowed`, which is Cedar's decision alone — Cedar skips a
|
|
320
|
+
* rule whose condition errors, so an errored `forbid` would otherwise let
|
|
321
|
+
* a `permit` through.
|
|
322
|
+
*/
|
|
323
|
+
allowed: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* The `.dw` rule indices that determined the decision. Empty for an
|
|
326
|
+
* implicit deny (no rule matched) and for a fail-closed deny (`errors`
|
|
327
|
+
* non-empty).
|
|
328
|
+
*/
|
|
329
|
+
determining_rules: number[];
|
|
330
|
+
/**
|
|
331
|
+
* Evaluation errors folded into this decision. Any error forces a deny,
|
|
332
|
+
* so a non-empty `errors` means *something went wrong*, not *policy said
|
|
333
|
+
* no*.
|
|
334
|
+
*/
|
|
335
|
+
errors: string[];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* The per-timepoint verdict stream from replaying a trace.
|
|
340
|
+
*/
|
|
341
|
+
export interface ReplayReport {
|
|
342
|
+
verdicts: TimepointVerdict[];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The result of `check-parse`: the policy set parsed and macro-expanded, with
|
|
347
|
+
* per-policy structural summaries. Syntax and macro errors only — schema-
|
|
348
|
+
* dependent checks (unknown attributes, type errors) are deferred to
|
|
349
|
+
* `validate`.
|
|
350
|
+
*/
|
|
351
|
+
export interface CheckParseReport {
|
|
352
|
+
policy_count: number;
|
|
353
|
+
policies: PolicySummary[];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* The result of `explain`: the policy set's deterministic informalization —
|
|
358
|
+
* the structured [`Informalization`] (one phrase tree per rule, each phrase
|
|
359
|
+
* carrying its `.dw` span) and the same rendered as indented plain text.
|
|
360
|
+
*/
|
|
361
|
+
export interface ExplainReport {
|
|
362
|
+
/**
|
|
363
|
+
* The phrase trees (JSON consumers walk this; spans are `[start, end)`
|
|
364
|
+
* byte offsets into the `.dw` source).
|
|
365
|
+
*/
|
|
366
|
+
informalization: Informalization;
|
|
367
|
+
/**
|
|
368
|
+
* The plain-text rendering (what human mode prints).
|
|
369
|
+
*/
|
|
370
|
+
text: string;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* The result of `validate`: whether the policy set type-checks against the
|
|
375
|
+
* schema, plus every finding. A fatal parse/lower error is returned as the
|
|
376
|
+
* `Err` channel instead; this report covers the type-check phase, which
|
|
377
|
+
* accumulates all findings rather than stopping at the first.
|
|
378
|
+
*/
|
|
379
|
+
export interface ValidateReport {
|
|
380
|
+
/**
|
|
381
|
+
* True iff there are no validation errors (warnings do not fail).
|
|
382
|
+
*/
|
|
383
|
+
passed: boolean;
|
|
384
|
+
/**
|
|
385
|
+
* True iff there are neither errors nor warnings.
|
|
386
|
+
*/
|
|
387
|
+
passed_without_warnings: boolean;
|
|
388
|
+
errors: Diagnostic[];
|
|
389
|
+
warnings: Diagnostic[];
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* The result of a standalone schema check: whether the artifact is
|
|
394
|
+
* well-formed, and any warnings (a valid-but-suspect schema).
|
|
395
|
+
*/
|
|
396
|
+
export interface SchemaCheckReport {
|
|
397
|
+
/**
|
|
398
|
+
* The artifact kind that was checked (`"action"`, `"event"`, `"providers"`).
|
|
399
|
+
*/
|
|
400
|
+
kind: string;
|
|
401
|
+
/**
|
|
402
|
+
* True iff the artifact parsed and is well-formed.
|
|
403
|
+
*/
|
|
404
|
+
ok: boolean;
|
|
405
|
+
/**
|
|
406
|
+
* Non-fatal warnings (from the action-schema and providers checks).
|
|
407
|
+
*/
|
|
408
|
+
warnings: string[];
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The severity of a [`Diagnostic`], projected from `miette::Severity`
|
|
413
|
+
* (which defaults to `Error` when a diagnostic does not specify one).
|
|
414
|
+
*/
|
|
415
|
+
export type Severity = "error" | "warning" | "advice";
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Whether a decision point allowed or denied — the CLI's own verdict type
|
|
419
|
+
* (not cedar's `Decision`, which is not ours to serialize).
|
|
420
|
+
*/
|
|
421
|
+
export type Verdict = "allow" | "deny";
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* A **stateful, live** Dogwood authorizer: lower a policy set once, then feed
|
|
426
|
+
* events as they happen and get a decision per event, with temporal history
|
|
427
|
+
* accumulating across calls.
|
|
428
|
+
*
|
|
429
|
+
* This is the counterpart to the one-shot [`replay`](crate::replay): same
|
|
430
|
+
* engine and same lowering, but the caller drives the loop. Because it holds
|
|
431
|
+
* temporal state, one instance corresponds to one history — see
|
|
432
|
+
* [`reset`](DogwoodAuthorizer::reset).
|
|
433
|
+
*/
|
|
434
|
+
export class DogwoodAuthorizer {
|
|
435
|
+
free(): void;
|
|
436
|
+
[Symbol.dispose](): void;
|
|
437
|
+
/**
|
|
438
|
+
* Authorize one event.
|
|
439
|
+
*
|
|
440
|
+
* Returns the [`AuthorizerDecision`] for a decision-kind event (by
|
|
441
|
+
* default, `kind: "request"`), or `undefined` for a history-only event —
|
|
442
|
+
* which still updates temporal history, and is how a host records the
|
|
443
|
+
* `response` half of a call so later policies can correlate against it.
|
|
444
|
+
*
|
|
445
|
+
* Throws a `DogwoodError` if the event is malformed (a missing `action`, a
|
|
446
|
+
* bad `__entity` tag, a wrong-typed field), **too large** (a value nested
|
|
447
|
+
* deeper than 128 levels, or past the size limits in `bounds`), or
|
|
448
|
+
* **rejected** by
|
|
449
|
+
* [`check`](Self::check) — an action or kind the schema does not declare, or
|
|
450
|
+
* a timestamp before the previous event's. Either way the instance is left
|
|
451
|
+
* **usable** and the temporal history untouched: the event is validated
|
|
452
|
+
* before it is observed, so a failed call is a no-op and the next call
|
|
453
|
+
* decides normally.
|
|
454
|
+
*
|
|
455
|
+
* A *policy* problem is never thrown: an evaluation failure comes back as a
|
|
456
|
+
* fail-closed `deny` with the cause in
|
|
457
|
+
* [`errors`](AuthorizerDecision::errors).
|
|
458
|
+
*
|
|
459
|
+
* The parameter is taken as a `JsValue` and deserialized here rather than
|
|
460
|
+
* declared as `EventInput` directly, which is load-bearing: wasm-bindgen
|
|
461
|
+
* acquires the `&mut self` borrow *before* converting arguments, so a
|
|
462
|
+
* conversion that fails propagates the exception without releasing the
|
|
463
|
+
* borrow — permanently poisoning the instance (every later call, `free()`
|
|
464
|
+
* included, then fails with "recursive use of an object"). Converting
|
|
465
|
+
* inside the body means the failure is an ordinary `Err` return and the
|
|
466
|
+
* borrow is released. `unchecked_param_type` keeps the TypeScript
|
|
467
|
+
* signature `EventInput`.
|
|
468
|
+
*/
|
|
469
|
+
isAuthorized(event: EventInput): AuthorizerDecision | undefined;
|
|
470
|
+
/**
|
|
471
|
+
* Lower `source` against `actionSchema` and build a fresh authorizer with
|
|
472
|
+
* empty temporal history. Throws a `DogwoodError` (with `.diagnostic`) on
|
|
473
|
+
* a parse, macro, lowering, or schema failure — the same error contract as
|
|
474
|
+
* every other operation in these bindings.
|
|
475
|
+
*
|
|
476
|
+
* The trailing arguments are the optional service-schema overrides
|
|
477
|
+
* (event-schema DSL text, `providers.json` text, macro-library text);
|
|
478
|
+
* omit them for the defaults.
|
|
479
|
+
*/
|
|
480
|
+
constructor(source: string, action_schema: string, event_schema?: string | null, providers?: string | null, macros?: string | null);
|
|
481
|
+
/**
|
|
482
|
+
* Drop all accumulated temporal history and start over, re-lowering the
|
|
483
|
+
* original sources. Cheaper than constructing a new instance only in that
|
|
484
|
+
* the caller need not keep the sources around; the lowering cost is the
|
|
485
|
+
* same. The decision index restarts at 0.
|
|
486
|
+
*/
|
|
487
|
+
reset(): void;
|
|
488
|
+
/**
|
|
489
|
+
* Every **fully qualified** action id this instance can decide
|
|
490
|
+
* (`["Drupe::Action::Read", …]`) — the actions the action schema declares.
|
|
491
|
+
* An event naming anything else is rejected, so a host that maps its own
|
|
492
|
+
* operation names onto Cedar actions can check the mapping against this
|
|
493
|
+
* once at startup rather than discovering a gap one denied request at a
|
|
494
|
+
* time.
|
|
495
|
+
*/
|
|
496
|
+
readonly actions: string[];
|
|
497
|
+
/**
|
|
498
|
+
* How many decisions this instance has returned — the `index` the next
|
|
499
|
+
* decision will carry.
|
|
500
|
+
*/
|
|
501
|
+
readonly decisionCount: number;
|
|
502
|
+
/**
|
|
503
|
+
* The event kinds that are decision points under this instance's event
|
|
504
|
+
* schema (`["request"]` by default) — the kinds for which
|
|
505
|
+
* [`isAuthorized`](Self::is_authorized) returns a decision rather than
|
|
506
|
+
* `undefined`.
|
|
507
|
+
*
|
|
508
|
+
* A kind in [`eventKinds`](Self::event_kinds) but not here is history-only:
|
|
509
|
+
* it is accepted, it updates temporal state, and it yields no verdict.
|
|
510
|
+
*/
|
|
511
|
+
readonly decisionKinds: string[];
|
|
512
|
+
/**
|
|
513
|
+
* Every event kind this instance's event schema declares, decision points
|
|
514
|
+
* and history-only alike (`["error", "request", "response"]` by default).
|
|
515
|
+
* Any other kind is rejected — see [`isAuthorized`](Self::is_authorized).
|
|
516
|
+
*/
|
|
517
|
+
readonly eventKinds: string[];
|
|
518
|
+
/**
|
|
519
|
+
* The timestamp of the most recent event observed, or `undefined` before
|
|
520
|
+
* the first (and after a [`reset`](Self::reset)). The next event's
|
|
521
|
+
* timestamp must be at least this.
|
|
522
|
+
*
|
|
523
|
+
* Widened to `f64` so the TypeScript type is `number`, matching
|
|
524
|
+
* [`AuthorizerDecision::timestamp`] and the `timestamp` a host passes in.
|
|
525
|
+
* An `i64` would come back a `BigInt`, which compares false against every
|
|
526
|
+
* plain number it is likely to be compared with (`5n == 5` is true but
|
|
527
|
+
* `5n === 5` is false, and mixed arithmetic throws) — a needless trap on a
|
|
528
|
+
* value that is a count of seconds and so nowhere near `f64`'s exact-integer
|
|
529
|
+
* limit.
|
|
530
|
+
*/
|
|
531
|
+
readonly lastTimestamp: number | undefined;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Check a Cedar action schema (`.cedarschema`) in isolation.
|
|
536
|
+
*/
|
|
537
|
+
export function checkActionSchema(source: string): SchemaCheckReport;
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Check an event-schema DSL (`.dwschema`) in isolation.
|
|
541
|
+
*/
|
|
542
|
+
export function checkEventSchema(source: string): SchemaCheckReport;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Parse and macro-expand a `.dw` policy set, reporting syntax/macro errors and
|
|
546
|
+
* per-policy structural summaries. Needs no action schema.
|
|
547
|
+
*/
|
|
548
|
+
export function checkParse(source: string, event_schema?: string | null, providers?: string | null, macros?: string | null): CheckParseReport;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Check an information-provider declarations file (`providers.json`) in
|
|
552
|
+
* isolation.
|
|
553
|
+
*/
|
|
554
|
+
export function checkProviders(json: string): SchemaCheckReport;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Parse (with macro expansion) and informalize a `.dw` policy set into
|
|
558
|
+
* deterministic semi-English, rule by rule. The action schema is optional:
|
|
559
|
+
* with it, the single declared namespace is dropped from names. Nothing is
|
|
560
|
+
* validated — an invalid-but-parsable policy is still explained.
|
|
561
|
+
*/
|
|
562
|
+
export function explain(source: string, action_schema?: string | null, event_schema?: string | null, providers?: string | null, macros?: string | null): ExplainReport;
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Module start hook, invoked automatically on load. In a development build
|
|
566
|
+
* (feature `dev`, `npm run build:dev`) it installs a panic hook so a Rust panic
|
|
567
|
+
* surfaces as a readable `console.error`; a release build installs nothing,
|
|
568
|
+
* and a panic aborts with an opaque `unreachable` without logging its message.
|
|
569
|
+
*/
|
|
570
|
+
export function init(): void;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Lower a `.dw` policy set to Cedar and return the emitted artifacts (policies
|
|
574
|
+
* and augmented schema, in text and Cedar-JSON forms).
|
|
575
|
+
*/
|
|
576
|
+
export function lower(source: string, action_schema: string, event_schema?: string | null, providers?: string | null, macros?: string | null): LowerArtifacts;
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Generate a Cedar action schema (`.cedarschema` text) from an MCP
|
|
580
|
+
* `tools/list` manifest, layered on the embedded Drupe template.
|
|
581
|
+
*/
|
|
582
|
+
export function mcpToCedarSchema(manifest_json: string): string;
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Lower, then drive a `.log` event trace through a stateful authorizer,
|
|
586
|
+
* returning the per-decision verdict stream.
|
|
587
|
+
*
|
|
588
|
+
* Any evaluation error forces a deny, exactly as in
|
|
589
|
+
* `DogwoodAuthorizer::isAuthorized` (see [`fail_closed`]).
|
|
590
|
+
*/
|
|
591
|
+
export function replay(source: string, action_schema: string, log: string, event_schema?: string | null, providers?: string | null, macros?: string | null): ReplayReport;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Lower against the Cedar action schema and type-check. Fatal parse/lower
|
|
595
|
+
* errors throw; a successful lower with type findings returns the report.
|
|
596
|
+
*/
|
|
597
|
+
export function validate(source: string, action_schema: string, event_schema?: string | null, providers?: string | null, macros?: string | null): ValidateReport;
|