@janssenproject/cedarling_wasm 2.1.0-nodejs → 2.3.0-nodejs

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 CHANGED
@@ -53,7 +53,9 @@ async function main() {
53
53
  await initWasm(); // Initialize the WebAssembly module
54
54
 
55
55
  let instance = await init(BOOTSTRAP_CONFIG);
56
- let result = await instance.authorize_unsigned(REQUEST_UNSIGNED);
56
+ // authorize calls take the request as a JSON string: it crosses the
57
+ // JS/WASM boundary as one string copy parsed by serde_json
58
+ let result = await instance.authorize_unsigned(JSON.stringify(REQUEST_UNSIGNED));
57
59
  console.log("result:", result);
58
60
  }
59
61
  main().catch(console.error);
@@ -110,12 +112,13 @@ export class Cedarling {
110
112
  * residual-dependent requests fail closed with `Decision::Deny` and surface
111
113
  * residual policy ids in `response.diagnostics.reason`.
112
114
  */
113
- authorize_unsigned(request: any): Promise<AuthorizeResult>;
115
+ authorize_unsigned(request: string): Promise<AuthorizeResult>;
114
116
  /**
115
117
  * Authorize multi-issuer request.
116
118
  * Makes authorization decision based on multiple JWT tokens from different issuers
119
+ * The request is passed as a JSON string.
117
120
  */
118
- authorize_multi_issuer(request: any): Promise<MultiIssuerAuthorizeResult>;
121
+ authorize_multi_issuer(request: string): Promise<MultiIssuerAuthorizeResult>;
119
122
  /**
120
123
  * Get logs and remove them from the storage.
121
124
  * Returns `Array` of `Map`
@@ -418,6 +421,10 @@ Cedarling supports multiple ways to load policy stores. **In WASM environments,
418
421
  // Option 1: Fetch policy store from URL (simple)
419
422
  const BOOTSTRAP_CONFIG = {
420
423
  CEDARLING_POLICY_STORE_URI: "https://example.com/policy-store.cjar",
424
+ // Optional: re-fetch every 60s and atomically swap on change.
425
+ // Default is 0 (load-once-at-startup). See "Refreshing the policy store"
426
+ // in docs/cedarling/reference/cedarling-properties.md for details.
427
+ CEDARLING_POLICY_STORE_REFRESH_INTERVAL: 60,
421
428
  // ... other config
422
429
  };
423
430
  const cedarling = await init(BOOTSTRAP_CONFIG);
@@ -56,6 +56,116 @@ export class AuthorizeResultResponse {
56
56
  readonly diagnostics: Diagnostics;
57
57
  }
58
58
 
59
+ /**
60
+ * WASM wrapper for
61
+ * `cedarling::BatchAuthorizeResponse<Result<MultiIssuerAuthorizeResult, BatchItemError>>`.
62
+ * Same shape as [`BatchAuthorizeUnsignedResponse`] with multi-issuer results.
63
+ */
64
+ export class BatchAuthorizeMultiIssuerResponse {
65
+ private constructor();
66
+ free(): void;
67
+ [Symbol.dispose](): void;
68
+ /**
69
+ * Shared correlation id stamped on every per-item decision log entry.
70
+ */
71
+ readonly batch_id: string;
72
+ /**
73
+ * Per-item results in input order — each slot is a
74
+ * [`BatchItemMultiIssuerResult`].
75
+ */
76
+ readonly results: BatchItemMultiIssuerResult[];
77
+ }
78
+
79
+ /**
80
+ * WASM wrapper for `cedarling::BatchAuthorizeResponse<Result<AuthorizeResult, BatchItemError>>`.
81
+ *
82
+ * Carries a shared `batch_id` (UUIDv7) alongside per-item results. Each result
83
+ * is a [`BatchItemUnsignedResult`] — Cedar decision on `is_ok()`, per-item
84
+ * build failure on `error`. `results[i]` corresponds to `items[i]`.
85
+ */
86
+ export class BatchAuthorizeUnsignedResponse {
87
+ private constructor();
88
+ free(): void;
89
+ [Symbol.dispose](): void;
90
+ /**
91
+ * Shared correlation id stamped on every per-item decision log entry.
92
+ */
93
+ readonly batch_id: string;
94
+ /**
95
+ * Per-item results in input order — each slot is a
96
+ * [`BatchItemUnsignedResult`].
97
+ */
98
+ readonly results: BatchItemUnsignedResult[];
99
+ }
100
+
101
+ /**
102
+ * Per-item build failure surfaced inside a batch response at `results[i]`
103
+ * when Cedar couldn't be reached for that item.
104
+ */
105
+ export class BatchItemError {
106
+ private constructor();
107
+ free(): void;
108
+ [Symbol.dispose](): void;
109
+ /**
110
+ * Stable variant slug — `action_parse`, `resource_build`, `context_build`,
111
+ * `principal_build`, `schema_validation`, `multi_issuer_entity`,
112
+ * `request_validation`.
113
+ */
114
+ readonly category: string;
115
+ /**
116
+ * Position of the failing item in the original `items` vector.
117
+ */
118
+ readonly item_index: number;
119
+ /**
120
+ * Human-readable diagnostic. Safe to log.
121
+ */
122
+ readonly message: string;
123
+ }
124
+
125
+ /**
126
+ * Multi-issuer analog of [`BatchItemUnsignedResult`].
127
+ */
128
+ export class BatchItemMultiIssuerResult {
129
+ private constructor();
130
+ free(): void;
131
+ [Symbol.dispose](): void;
132
+ /**
133
+ * The multi-issuer decision if `is_ok()`; throws otherwise.
134
+ */
135
+ unwrap(): MultiIssuerAuthorizeResult;
136
+ /**
137
+ * The per-item error if `!is_ok()`; `undefined` otherwise.
138
+ */
139
+ readonly error: BatchItemError | undefined;
140
+ /**
141
+ * `true` when Cedar evaluated this item.
142
+ */
143
+ readonly is_ok: boolean;
144
+ }
145
+
146
+ /**
147
+ * One slot in a batch response's `results` array. Callers switch on
148
+ * `is_ok()` — on `true`, read `unwrap()`; on `false`, read `error()`.
149
+ */
150
+ export class BatchItemUnsignedResult {
151
+ private constructor();
152
+ free(): void;
153
+ [Symbol.dispose](): void;
154
+ /**
155
+ * The Cedar decision if `is_ok()`; throws otherwise.
156
+ */
157
+ unwrap(): AuthorizeResult;
158
+ /**
159
+ * The per-item error if `!is_ok()`; `undefined` otherwise.
160
+ */
161
+ readonly error: BatchItemError | undefined;
162
+ /**
163
+ * `true` when Cedar evaluated this item (Allow or Deny); `false` when it
164
+ * failed to build.
165
+ */
166
+ readonly is_ok: boolean;
167
+ }
168
+
59
169
  /**
60
170
  * The instance of the Cedarling application.
61
171
  */
@@ -63,11 +173,103 @@ export class Cedarling {
63
173
  private constructor();
64
174
  free(): void;
65
175
  [Symbol.dispose](): void;
176
+ /**
177
+ * Collect every value of the annotation `key` across the given policies,
178
+ * preserving duplicates. Unknown policy IDs are silently skipped.
179
+ *
180
+ * # Arguments
181
+ *
182
+ * * `policy_ids` - List of policy IDs to search. Typically
183
+ * `result.response.diagnostics.reason` from an authorization result.
184
+ * * `key` - The annotation key to collect values for (e.g. `"redirect"`).
185
+ *
186
+ * # Example
187
+ *
188
+ * ```javascript
189
+ * const redirects = cedarling.annotation_values(result.response.diagnostics.reason, "redirect");
190
+ * // ["/upgrade"]
191
+ * ```
192
+ */
193
+ annotation_values(policy_ids: string[], key: string): string[];
194
+ /**
195
+ * Return the annotations of each given policy, grouped by policy ID
196
+ * the loss-free companion to `annotations_map`. Unknown policy IDs are
197
+ * silently skipped.
198
+ *
199
+ * # Arguments
200
+ *
201
+ * * `policy_ids` - List of policy IDs whose annotations should be returned
202
+ * grouped by policy ID. Typically `result.response.diagnostics.reason` from
203
+ * an authorization result.
204
+ *
205
+ * # Example
206
+ *
207
+ * ```javascript
208
+ * const byPolicy = cedarling.annotations_by_policy(result.response.diagnostics.reason);
209
+ * // { "5": { redirect: "/upgrade", tier: "premium" } }
210
+ * ```
211
+ */
212
+ annotations_by_policy(policy_ids: string[]): any;
213
+ /**
214
+ * Merge the annotations (`@key("value")`) of the given policies into a single object.
215
+ *
216
+ * Intended for resolving the determining policies of an authorization decision:
217
+ * pass `result.response.diagnostics.reason`.
218
+ *
219
+ * Lossy: if the same annotation key appears on several policies, one value wins
220
+ * arbitrarily. Use `annotation_values` / `annotations_by_policy` when duplicates
221
+ * matter. Unknown policy IDs are silently skipped.
222
+ *
223
+ * # Arguments
224
+ *
225
+ * * `policy_ids` - List of policy IDs whose annotations should be merged into
226
+ * a single object. Typically `result.response.diagnostics.reason` from an
227
+ * authorization result.
228
+ *
229
+ * # Example
230
+ *
231
+ * ```javascript
232
+ * const annotations = cedarling.annotations_map(result.response.diagnostics.reason);
233
+ * // { redirect: "/upgrade", tier: "premium" }
234
+ * ```
235
+ */
236
+ annotations_map(policy_ids: string[]): any;
66
237
  /**
67
238
  * Authorize multi-issuer request.
68
- * Makes authorization decision based on multiple JWT tokens from different issuers
239
+ * Makes authorization decision based on multiple JWT tokens from different issuers.
240
+ *
241
+ * # Arguments
242
+ *
243
+ * * `request` - JSON string representation of [`AuthorizeMultiIssuerRequest`].
244
+ *
245
+ * # Example
246
+ *
247
+ * ```javascript
248
+ * const result = await cedarling.authorize_multi_issuer(JSON.stringify(request));
249
+ * ```
250
+ */
251
+ authorize_multi_issuer(request: string): Promise<MultiIssuerAuthorizeResult>;
252
+ /**
253
+ * Authorize a batch of multi-issuer requests against one shared token set.
254
+ *
255
+ * Tokens are validated and token/issuer entities are built once, then
256
+ * each item is evaluated in input order. Batch-level failures (validation,
257
+ * JWT verification, status-list refresh) reject the whole call; per-item
258
+ * failures are returned as `BatchItemError` results and exposed by WASM
259
+ * with `is_ok=false` and `error`, while genuine Cedar denials remain
260
+ * `AuthorizeResult` values with `decision=false`.
261
+ *
262
+ * # Arguments
263
+ *
264
+ * * `request` - JSON string representation of [`BatchAuthorizeMultiIssuerRequest`].
265
+ *
266
+ * # Example
267
+ *
268
+ * ```javascript
269
+ * const result = await cedarling.authorize_multi_issuer_batch(JSON.stringify(batchRequest));
270
+ * ```
69
271
  */
70
- authorize_multi_issuer(request: any): Promise<MultiIssuerAuthorizeResult>;
272
+ authorize_multi_issuer_batch(request: string): Promise<BatchAuthorizeMultiIssuerResponse>;
71
273
  /**
72
274
  * Authorize an unsigned request carrying an optional single principal.
73
275
  * Makes an authorization decision based on the [`RequestUnsigned`].
@@ -76,8 +278,39 @@ export class Cedarling {
76
278
  * partial evaluation; residual-dependent requests fail closed with
77
279
  * `Decision::Deny` and surface residual policy ids in
78
280
  * `response.diagnostics.reason`.
281
+ *
282
+ * # Arguments
283
+ *
284
+ * * `request` - JSON string representation of [`RequestUnsigned`].
285
+ *
286
+ * # Example
287
+ *
288
+ * ```javascript
289
+ * const result = await cedarling.authorize_unsigned(JSON.stringify(request));
290
+ * ```
291
+ */
292
+ authorize_unsigned(request: string): Promise<AuthorizeResult>;
293
+ /**
294
+ * Authorize a batch of unsigned requests against one shared principal.
295
+ *
296
+ * Setup work (principal build + pushed-data snapshot) runs once and each
297
+ * item is evaluated in input order. Results are returned inside a
298
+ * [`BatchAuthorizeUnsignedResponse`] carrying the shared `batch_id`.
299
+ * Batch-level failures (validation, principal parse) reject the whole
300
+ * call; per-item failures are returned as `BatchItemError` results and
301
+ * exposed by WASM with `is_ok=false` and `error`, while genuine Cedar
302
+ * denials remain `AuthorizeResult` values with `decision=false`.
303
+ * # Arguments
304
+ *
305
+ * * `request` - JSON string representation of [`BatchAuthorizeUnsignedRequest`].
306
+ *
307
+ * # Example
308
+ *
309
+ * ```javascript
310
+ * const result = await cedarling.authorize_unsigned_batch(JSON.stringify(batchRequest));
311
+ * ```
79
312
  */
80
- authorize_unsigned(request: any): Promise<AuthorizeResult>;
313
+ authorize_unsigned_batch(request: string): Promise<BatchAuthorizeUnsignedResponse>;
81
314
  /**
82
315
  * Clear all entries from the data store.
83
316
  *