@janssenproject/cedarling_wasm 0.0.467-nodejs → 0.0.468
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 +201 -0
- package/README.md +458 -55
- package/dist/browser/index.js +3159 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/cjs/index.cjs +3140 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/edge/index.js +3089 -0
- package/dist/edge/index.js.map +7 -0
- package/dist/esm/index.js +3154 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/manual/index.js +3104 -0
- package/dist/manual/index.js.map +7 -0
- package/{cedarling_wasm.d.ts → dist/types/cjs/generated.d.ts} +225 -54
- package/dist/types/cjs/index.d.ts +6 -0
- package/dist/types/cjs/package.json +1 -0
- package/dist/types/esm/edge.d.ts +7 -0
- package/dist/types/esm/generated.d.ts +1084 -0
- package/dist/types/esm/index.d.ts +6 -0
- package/dist/types/esm/manual.d.ts +2 -0
- package/dist/types/esm/wasm.d.ts +2 -0
- package/{cedarling_wasm_bg.wasm → dist/wasm/cedarling_wasm_bg.wasm} +0 -0
- package/package.json +81 -8
- package/cedarling_wasm.js +0 -3157
package/README.md
CHANGED
|
@@ -1,87 +1,490 @@
|
|
|
1
|
-
# Cedarling
|
|
1
|
+
# Getting Started with Cedarling in a JavaScript App
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The `@janssenproject/cedarling_wasm` package brings
|
|
4
|
+
[Cedarling](https://docs.jans.io/stable/cedarling/) authorization to JavaScript and
|
|
5
|
+
TypeScript applications. Cedarling evaluates Cedar policies within your
|
|
6
|
+
application's process, whether it runs in a browser, on a server, or at the edge.
|
|
7
|
+
It determines whether a principal or token set may perform an action on a resource.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Use Cedarling to apply consistent access policies, inspect authorization decisions,
|
|
10
|
+
retain decision logs, and make application context available to policy evaluation.
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
[npm package guide](./js/README.md).
|
|
11
|
-
- For package generation, artifact qualification, and release maintenance, use
|
|
12
|
-
the [maintainer guide](./js/docs/maintainer.md).
|
|
13
|
-
- This guide covers direct development with the wasm-pack-generated binding.
|
|
12
|
+
## Installation
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
### Using the Package Manager
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
```sh
|
|
17
|
+
npm install @janssenproject/cedarling_wasm
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Choose the package entry for your application. The package ships Cedarling's
|
|
21
|
+
WebAssembly (`.wasm`) binary; the last column describes how that binary is loaded
|
|
22
|
+
and initialized. Your application's policy archive is configured separately.
|
|
23
|
+
|
|
24
|
+
| Environment | Package Entry | Packaged WASM Loading |
|
|
25
|
+
| -------------------------------------------- | --------------------------------------------------- | ----------------------------------- |
|
|
26
|
+
| Browser applications with supported bundlers | `@janssenproject/cedarling_wasm` | Automatic |
|
|
27
|
+
| Node.js 22, 24, or 26, ESM or CommonJS | `@janssenproject/cedarling_wasm` | Automatic |
|
|
28
|
+
| Cloudflare Workers and Vercel Edge | `@janssenproject/cedarling_wasm/edge` | Bundled as a precompiled module |
|
|
29
|
+
| Other ESM bundlers | `@janssenproject/cedarling_wasm/manual` and `/wasm` | Application-configured WASM loading |
|
|
30
|
+
|
|
31
|
+
Browser applications use an ESM-aware bundler. Follow
|
|
32
|
+
[Other Integration Paths](#other-integration-paths) for edge deployment and
|
|
33
|
+
application-controlled WASM loading.
|
|
34
|
+
|
|
35
|
+
### Build from Source
|
|
36
|
+
|
|
37
|
+
For local generation, package build, and qualification instructions, see the
|
|
38
|
+
[maintainer guide](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/bindings/cedarling_wasm/js/docs/maintainer.md).
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
18
41
|
|
|
19
|
-
|
|
42
|
+
### Initialization
|
|
20
43
|
|
|
21
|
-
|
|
22
|
-
|
|
44
|
+
Create a Cedarling instance with `init()`. It ensures the package's WASM binary is
|
|
45
|
+
loaded and initialized, then creates the instance using an object or `Map` of
|
|
46
|
+
canonical Cedarling bootstrap properties.
|
|
47
|
+
|
|
48
|
+
For browser or Node.js ESM applications:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { init } from "@janssenproject/cedarling_wasm";
|
|
52
|
+
|
|
53
|
+
const config = {
|
|
54
|
+
CEDARLING_APPLICATION_NAME: "task-api",
|
|
55
|
+
CEDARLING_LOG_TYPE: "memory",
|
|
56
|
+
CEDARLING_LOG_TTL: 120,
|
|
57
|
+
};
|
|
58
|
+
let cedarling;
|
|
59
|
+
try {
|
|
60
|
+
cedarling = await init({
|
|
61
|
+
...config,
|
|
62
|
+
CEDARLING_POLICY_STORE_URI: "https://example.com/policy-store.cjar",
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error("Cedarling initialization failed", error);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
23
68
|
```
|
|
24
69
|
|
|
25
|
-
|
|
70
|
+
Replace the example URL with your application's policy archive. For Node.js
|
|
71
|
+
CommonJS, use the following import and run the initialization inside an async
|
|
72
|
+
function:
|
|
26
73
|
|
|
27
|
-
```
|
|
28
|
-
|
|
74
|
+
```js
|
|
75
|
+
const { init } = require("@janssenproject/cedarling_wasm");
|
|
29
76
|
```
|
|
30
77
|
|
|
31
|
-
|
|
78
|
+
The examples below reuse `cedarling`. Run each authorization walkthrough
|
|
79
|
+
separately, with a policy store that matches its entities and attributes.
|
|
80
|
+
Handle initialization failures in your application's startup error handler.
|
|
81
|
+
See the [bootstrap-property reference](https://docs.jans.io/stable/cedarling/reference/cedarling-properties/)
|
|
82
|
+
for configuration values, defaults, and token-validation settings.
|
|
83
|
+
|
|
84
|
+
### Policy Store Sources
|
|
32
85
|
|
|
33
|
-
|
|
86
|
+
A Cedar archive (`.cjar`) packages the schema, policies, and trusted-issuer
|
|
87
|
+
configuration. Prepare policies with the
|
|
88
|
+
[Agama Lab Policy Designer](https://cloud.gluu.org/agama-lab/dashboard/policy-designer)
|
|
89
|
+
and follow the [Cedar Archive format](https://docs.jans.io/nightly/cedarling/reference/cedarling-policy-store/#cedar-archive-cjar-format)
|
|
90
|
+
for packaging.
|
|
34
91
|
|
|
35
|
-
|
|
92
|
+
#### Load a Cedar Archive from a URL
|
|
36
93
|
|
|
37
|
-
|
|
94
|
+
Set `CEDARLING_POLICY_STORE_URI` as shown in [Initialization](#initialization).
|
|
95
|
+
Cedarling downloads the archive while creating the instance. Use an absolute
|
|
96
|
+
HTTP(S) URL. For browser downloads, use the application's origin or configure the
|
|
97
|
+
archive server's CORS headers to allow the application origin.
|
|
38
98
|
|
|
39
|
-
|
|
40
|
-
|
|
99
|
+
#### Load a Cedar Archive from Bytes
|
|
100
|
+
|
|
101
|
+
Use `initFromArchiveBytes()` instead of `init()` when your application controls
|
|
102
|
+
the download. This browser example reuses `config` from Initialization and
|
|
103
|
+
fetches an archive through a same-origin application endpoint:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { initFromArchiveBytes } from "@janssenproject/cedarling_wasm";
|
|
107
|
+
|
|
108
|
+
let policyArchiveBytes;
|
|
109
|
+
let cedarling;
|
|
110
|
+
try {
|
|
111
|
+
const response = await fetch("/api/policy-store");
|
|
112
|
+
if (!response.ok) throw new Error("Policy-store download failed");
|
|
113
|
+
policyArchiveBytes = new Uint8Array(await response.arrayBuffer());
|
|
114
|
+
cedarling = await initFromArchiveBytes(config, policyArchiveBytes);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error("Policy-store download or initialization failed", error);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
41
119
|
```
|
|
42
120
|
|
|
43
|
-
|
|
121
|
+
The archive bytes supply the policy store; `config` supplies the other bootstrap
|
|
122
|
+
properties. The package still loads and initializes its own WASM binary. In
|
|
123
|
+
Node.js, use an absolute download URL. Keep upstream policy-store credentials on
|
|
124
|
+
a trusted server; browser configuration is visible to its users.
|
|
44
125
|
|
|
45
|
-
|
|
126
|
+
### Authorization
|
|
46
127
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
128
|
+
Choose token-based authorization when identity comes from JWTs, or unsigned
|
|
129
|
+
authorization when the application supplies a trusted principal. Both methods
|
|
130
|
+
accept a JSON-string request and return a promise that resolves to an authorization
|
|
131
|
+
result containing `decision` and `request_id`.
|
|
51
132
|
|
|
52
|
-
|
|
133
|
+
#### Token-Based Authorization (Multi-Issuer)
|
|
53
134
|
|
|
54
|
-
|
|
135
|
+
Use `authorizeMultiIssuer()` to evaluate tokens from one or more issuers. Your
|
|
136
|
+
policy store must define the token mappings, trusted issuers, resource schema,
|
|
137
|
+
action, and context used below. Configure token validation for those issuers;
|
|
138
|
+
the initialization example retains Cedarling's validation defaults.
|
|
55
139
|
|
|
56
|
-
|
|
140
|
+
1. Prepare the tokens.
|
|
57
141
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
142
|
+
Obtain `acmeAccessToken` and `dolphinAccessToken` from your application's
|
|
143
|
+
authentication flows. Each `mapping` must match its policy-store token
|
|
144
|
+
metadata; each `payload` is the actual JWT string.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const tokens = [
|
|
148
|
+
{ mapping: "Acme::Access_Token", payload: acmeAccessToken },
|
|
149
|
+
{ mapping: "Dolphin::Access_Token", payload: dolphinAccessToken },
|
|
150
|
+
];
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
2. Define the resource.
|
|
154
|
+
|
|
155
|
+
This example targets a document. Its type and attributes must match your schema.
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const resource = {
|
|
159
|
+
cedar_entity_mapping: { entity_type: "Task::Document", id: "document-1" },
|
|
160
|
+
owner: "alice",
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
3. Define the action.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const action = 'Task::Action::"Read"';
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
4. Define the context.
|
|
171
|
+
|
|
172
|
+
Supply request-specific data required by your policies and schema.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const context = { tenant: "example" };
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
5. Build the request.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
const request = { tokens, action, resource, context };
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
6. Perform authorization and handle the decision.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
try {
|
|
188
|
+
const result = await cedarling.authorizeMultiIssuer(JSON.stringify(request));
|
|
189
|
+
console.log(result.decision ? "Allowed" : "Denied", result.request_id);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error("Authorization failed", error);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Unsigned Authorization
|
|
196
|
+
|
|
197
|
+
Use `authorizeUnsigned()` when your application supplies the principal and its
|
|
198
|
+
attributes. Obtain those values from trusted application state. The policy store
|
|
199
|
+
for this example must define `Task::User` with a `role`, `Task::Document` with an
|
|
200
|
+
`owner`, and the `Read` action with the `tenant` context field.
|
|
201
|
+
|
|
202
|
+
1. Prepare the principal.
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const principal = {
|
|
206
|
+
cedar_entity_mapping: { entity_type: "Task::User", id: "alice" },
|
|
207
|
+
role: "member",
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
2. Define the resource.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
const resource = {
|
|
215
|
+
cedar_entity_mapping: { entity_type: "Task::Document", id: "document-1" },
|
|
216
|
+
owner: "alice",
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
3. Define the action.
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
const action = 'Task::Action::"Read"';
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
4. Define the context.
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
const context = { tenant: "example" };
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
5. Build the request.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const request = { principal, action, resource, context };
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
6. Perform authorization and handle the decision.
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
try {
|
|
242
|
+
const result = await cedarling.authorizeUnsigned(JSON.stringify(request));
|
|
243
|
+
console.log(result.decision ? "Allowed" : "Denied", result.request_id);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error("Authorization failed", error);
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
For both methods, `decision: false` is a valid denial. Malformed requests reject
|
|
250
|
+
the call. Multi-issuer authorization can continue with tokens that pass validation,
|
|
251
|
+
so policies must require the tokens needed for access. Perform the protected
|
|
252
|
+
operation only after receiving `decision: true`; enforce server-side access at the
|
|
253
|
+
server boundary.
|
|
254
|
+
|
|
255
|
+
#### Batch Authorization
|
|
256
|
+
|
|
257
|
+
Evaluate several resources with one principal or token set. Each item contains
|
|
258
|
+
an action, resource, and optional context. Reuse the values from the relevant
|
|
259
|
+
walkthrough:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
const items = [
|
|
263
|
+
{ action, resource, context },
|
|
264
|
+
{
|
|
265
|
+
action,
|
|
266
|
+
resource: {
|
|
267
|
+
...resource,
|
|
268
|
+
cedar_entity_mapping: { entity_type: "Task::Document", id: "document-2" },
|
|
269
|
+
},
|
|
270
|
+
context,
|
|
271
|
+
},
|
|
272
|
+
];
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
For the unsigned walkthrough:
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
let batch;
|
|
279
|
+
try {
|
|
280
|
+
batch = await cedarling.authorizeUnsignedBatch(
|
|
281
|
+
JSON.stringify({ principal, items }),
|
|
282
|
+
);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error("Batch authorization failed", error);
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
For the token-based walkthrough, use this call instead:
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
let batch;
|
|
293
|
+
try {
|
|
294
|
+
batch = await cedarling.authorizeMultiIssuerBatch(
|
|
295
|
+
JSON.stringify({ tokens, items }),
|
|
296
|
+
);
|
|
297
|
+
} catch (error) {
|
|
298
|
+
console.error("Batch authorization failed", error);
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
After a successful batch call, inspect each item in the same order as the
|
|
304
|
+
submitted `items`:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
for (const item of batch.results) {
|
|
308
|
+
if (item.is_ok) {
|
|
309
|
+
console.log(item.unwrap().decision ? "Allowed" : "Denied");
|
|
310
|
+
} else {
|
|
311
|
+
console.error(item.error?.category, item.error?.message);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
A valid denial has `is_ok === true` and a false decision. A per-item build error
|
|
317
|
+
has `is_ok === false`. The returned `batch_id` correlates the batch's decision logs.
|
|
318
|
+
|
|
319
|
+
### Logging
|
|
320
|
+
|
|
321
|
+
The initialization example enables memory logging and retains entries for up to 120
|
|
322
|
+
seconds. Inside either authorization walkthrough's `try` block, use the returned
|
|
323
|
+
request ID to inspect its logs:
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
const logs = cedarling.getLogsByRequestId(result.request_id);
|
|
327
|
+
console.log(logs);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Log records are plain JavaScript objects. To retrieve and clear all retained logs
|
|
331
|
+
when your application is ready to consume them:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
try {
|
|
335
|
+
const retainedLogs = cedarling.popLogs();
|
|
336
|
+
console.log(retainedLogs);
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.error("Log retrieval failed", error);
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Context Data
|
|
343
|
+
|
|
344
|
+
Store application-scoped data for policy evaluation, then retrieve or remove it:
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
try {
|
|
348
|
+
cedarling.pushDataCtx("user:alice", { plan: "pro" }, 3600n);
|
|
349
|
+
const value = cedarling.getDataCtx("user:alice");
|
|
350
|
+
console.log(value);
|
|
351
|
+
cedarling.removeDataCtx("user:alice");
|
|
352
|
+
} catch (error) {
|
|
353
|
+
console.error("Context-data operation failed", error);
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
The optional TTL is a `bigint` number of seconds; omitting it uses the configured
|
|
358
|
+
default. Retrieval returns `null` when a value is absent or expired.
|
|
359
|
+
|
|
360
|
+
### Trusted Issuer Readiness
|
|
61
361
|
|
|
62
|
-
|
|
63
|
-
|
|
362
|
+
Before token-based authorization, inspect which configured issuers loaded and
|
|
363
|
+
which failed:
|
|
64
364
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
365
|
+
```ts
|
|
366
|
+
console.log("Loaded issuers", cedarling.loadedTrustedIssuerIds());
|
|
367
|
+
console.log("Failed issuers", cedarling.failedTrustedIssuerIds());
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
To check one issuer, pass its configured identifier to
|
|
371
|
+
`cedarling.isTrustedIssuerLoadedByName(issuerId)`.
|
|
372
|
+
|
|
373
|
+
### Policy Annotations
|
|
374
|
+
|
|
375
|
+
Annotations attach metadata such as descriptions to policies using
|
|
376
|
+
`@key("value")`. They describe policies independently of their authorization rules.
|
|
377
|
+
For example, a policy in your archive can include:
|
|
378
|
+
|
|
379
|
+
```cedar
|
|
380
|
+
@description("Allows Alice to read document-1")
|
|
381
|
+
permit (
|
|
382
|
+
principal == Task::User::"alice",
|
|
383
|
+
action == Task::Action::"Read",
|
|
384
|
+
resource == Task::Document::"document-1"
|
|
385
|
+
);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Inside the unsigned walkthrough's `try` block, retrieve descriptions for the
|
|
389
|
+
determining policy IDs returned in the result:
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
const descriptions = cedarling.annotationValues(
|
|
393
|
+
result.response.diagnostics.reason,
|
|
394
|
+
"description",
|
|
395
|
+
);
|
|
396
|
+
console.log(descriptions);
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
See the [Cedar annotation reference](https://docs.cedarpolicy.com/policies/syntax-policy.html#annotations)
|
|
400
|
+
for annotation syntax and behavior.
|
|
401
|
+
|
|
402
|
+
### Shutdown
|
|
403
|
+
|
|
404
|
+
When the application finishes using a Cedarling instance, shut it down:
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
try {
|
|
408
|
+
await cedarling.shutDown();
|
|
409
|
+
} catch (error) {
|
|
410
|
+
console.error("Cedarling shutdown failed", error);
|
|
70
411
|
}
|
|
71
|
-
main().catch(console.error);
|
|
72
412
|
```
|
|
73
413
|
|
|
74
|
-
|
|
75
|
-
|
|
414
|
+
### Other Integration Paths
|
|
415
|
+
|
|
416
|
+
#### Edge Deployments
|
|
417
|
+
|
|
418
|
+
Use the ESM-only `./edge` entry in hosts whose deployment tool bundles the package's
|
|
419
|
+
WASM binary as a precompiled WebAssembly module. In Cloudflare Workers, initialize inside
|
|
420
|
+
the [request context](https://developers.cloudflare.com/workers/runtime-apis/request/#the-request-context)
|
|
421
|
+
so policy downloads can run:
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
import { init } from "@janssenproject/cedarling_wasm/edge";
|
|
425
|
+
|
|
426
|
+
export default {
|
|
427
|
+
async fetch() {
|
|
428
|
+
let cedarling;
|
|
429
|
+
try {
|
|
430
|
+
cedarling = await init({
|
|
431
|
+
CEDARLING_APPLICATION_NAME: "edge-api",
|
|
432
|
+
CEDARLING_POLICY_STORE_URI: "https://example.com/policy-store.cjar",
|
|
433
|
+
});
|
|
434
|
+
return new Response("Cedarling initialized");
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.error("Cedarling initialization failed", error);
|
|
437
|
+
return new Response("Internal server error", { status: 500 });
|
|
438
|
+
} finally {
|
|
439
|
+
try {
|
|
440
|
+
await cedarling?.shutDown();
|
|
441
|
+
} catch (error) {
|
|
442
|
+
console.error("Cedarling shutdown failed", error);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### Manual Bundler Integration
|
|
450
|
+
|
|
451
|
+
For application-controlled WASM loading, configure your ESM bundler to emit the
|
|
452
|
+
package's `./wasm` export as a URL-addressable binary asset. Configure the server
|
|
453
|
+
to serve it with the `application/wasm` content type. The example below reuses
|
|
454
|
+
`config` and `policyArchiveBytes` from
|
|
455
|
+
[Load a Cedar Archive from Bytes](#load-a-cedar-archive-from-bytes), replacing
|
|
456
|
+
that section's initialization call:
|
|
457
|
+
|
|
458
|
+
```ts
|
|
459
|
+
import initWasm, {
|
|
460
|
+
initFromArchiveBytes,
|
|
461
|
+
} from "@janssenproject/cedarling_wasm/manual";
|
|
462
|
+
import wasmUrl from "@janssenproject/cedarling_wasm/wasm";
|
|
463
|
+
|
|
464
|
+
let cedarling;
|
|
465
|
+
try {
|
|
466
|
+
await initWasm({ module_or_path: wasmUrl });
|
|
467
|
+
cedarling = await initFromArchiveBytes(config, policyArchiveBytes);
|
|
468
|
+
} catch (error) {
|
|
469
|
+
console.error("WASM loading or Cedarling initialization failed", error);
|
|
470
|
+
throw error;
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Configure the `.wasm` import to return an asset URL; the exact rule or plugin
|
|
475
|
+
depends on your bundler.
|
|
476
|
+
|
|
477
|
+
## Upgrading Existing Applications
|
|
76
478
|
|
|
77
|
-
|
|
479
|
+
Update calls such as `authorize_unsigned()` to `authorizeUnsigned()`,
|
|
480
|
+
`shut_down()` to `shutDown()`, and `json_string()` to `jsonString()`.
|
|
481
|
+
Bootstrap keys (`CEDARLING_*`), request JSON, result/data fields such as
|
|
482
|
+
`request_id`, and serialized JSON retain their names.
|
|
78
483
|
|
|
79
|
-
|
|
80
|
-
successful build. Callable JavaScript APIs use camelCase, including
|
|
81
|
-
`jsonString()`. Cedarling bootstrap properties, request JSON keys, and returned
|
|
82
|
-
data fields retain their canonical names, including snake_case fields such as
|
|
83
|
-
`request_id`.
|
|
484
|
+
## See Also
|
|
84
485
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
486
|
+
- [JavaScript tutorial](https://docs.jans.io/stable/cedarling/tutorials/javascript/)
|
|
487
|
+
- [Full API reference](https://docs.jans.io/stable/cedarling/tutorials/javascript/#defined-api)
|
|
488
|
+
- [Bootstrap-property reference](https://docs.jans.io/stable/cedarling/reference/cedarling-properties/)
|
|
489
|
+
- [Cedar Archive format](https://docs.jans.io/nightly/cedarling/reference/cedarling-policy-store/#cedar-archive-cjar-format)
|
|
490
|
+
- [Maintainer guide](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/bindings/cedarling_wasm/js/docs/maintainer.md)
|