@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.
@@ -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;