@janssenproject/cedarling_wasm 2.4.0 → 2.5.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 +201 -0
- package/README.md +411 -517
- package/dist/browser/index.js +3346 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/cjs/index.cjs +3327 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/edge/index.js +3276 -0
- package/dist/edge/index.js.map +7 -0
- package/dist/esm/index.js +3341 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/manual/index.js +3292 -0
- package/dist/manual/index.js.map +7 -0
- package/{cedarling_wasm.d.ts → dist/types/cjs/generated.d.ts} +411 -171
- 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 +1166 -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 +80 -11
- package/cedarling_wasm.js +0 -3084
package/README.md
CHANGED
|
@@ -1,617 +1,511 @@
|
|
|
1
|
-
# Cedarling
|
|
1
|
+
# Getting Started with Cedarling in a JavaScript App
|
|
2
2
|
|
|
3
|
-
|
|
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.
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
Use Cedarling to apply consistent access policies, inspect authorization decisions,
|
|
10
|
+
retain decision logs, and make application context available to policy evaluation.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
## Installation
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
### Using the Package Manager
|
|
10
15
|
|
|
11
|
-
```
|
|
12
|
-
|
|
16
|
+
```sh
|
|
17
|
+
npm install @janssenproject/cedarling_wasm
|
|
13
18
|
```
|
|
14
19
|
|
|
15
|
-
|
|
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.
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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).
|
|
20
39
|
|
|
21
|
-
|
|
40
|
+
## Usage
|
|
22
41
|
|
|
23
|
-
|
|
42
|
+
### Initialization
|
|
24
43
|
|
|
25
|
-
|
|
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.
|
|
26
47
|
|
|
27
|
-
|
|
48
|
+
For browser or Node.js ESM applications:
|
|
28
49
|
|
|
29
|
-
```
|
|
30
|
-
|
|
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
|
+
}
|
|
31
68
|
```
|
|
32
69
|
|
|
33
|
-
|
|
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:
|
|
34
73
|
|
|
35
|
-
|
|
74
|
+
```js
|
|
75
|
+
const { init } = require("@janssenproject/cedarling_wasm");
|
|
76
|
+
```
|
|
36
77
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
41
83
|
|
|
42
|
-
|
|
84
|
+
### Policy Store Sources
|
|
43
85
|
|
|
44
|
-
|
|
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.
|
|
45
91
|
|
|
46
|
-
|
|
92
|
+
#### Load a Cedar Archive from a URL
|
|
47
93
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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.
|
|
98
|
+
|
|
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:
|
|
51
104
|
|
|
52
|
-
|
|
53
|
-
|
|
105
|
+
```ts
|
|
106
|
+
import { initFromArchiveBytes } from "@janssenproject/cedarling_wasm";
|
|
54
107
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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;
|
|
60
118
|
}
|
|
61
|
-
main().catch(console.error);
|
|
62
119
|
```
|
|
63
120
|
|
|
64
|
-
|
|
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.
|
|
65
125
|
|
|
66
|
-
###
|
|
126
|
+
### Authorization
|
|
67
127
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*/
|
|
73
|
-
export function init(config: any): Promise<Cedarling>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Create a new instance of the Cedarling application from archive bytes.
|
|
77
|
-
*
|
|
78
|
-
* This function allows loading a policy store from a Cedar Archive (.cjar)
|
|
79
|
-
* that was fetched with custom logic (e.g., with authentication headers).
|
|
80
|
-
*
|
|
81
|
-
* # Arguments
|
|
82
|
-
* * `config` - Bootstrap configuration (Map or Object). Policy store config is ignored.
|
|
83
|
-
* * `archive_bytes` - The .cjar archive bytes (Uint8Array)
|
|
84
|
-
*
|
|
85
|
-
* # Example
|
|
86
|
-
* ```javascript
|
|
87
|
-
* const response = await fetch(url, { headers: { Authorization: 'Bearer ...' } });
|
|
88
|
-
* const bytes = new Uint8Array(await response.arrayBuffer());
|
|
89
|
-
* const cedarling = await init_from_archive_bytes(config, bytes);
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
export function init_from_archive_bytes(config: any, archive_bytes: Uint8Array): Promise<Cedarling>;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The instance of the Cedarling application.
|
|
96
|
-
*/
|
|
97
|
-
export class Cedarling {
|
|
98
|
-
/**
|
|
99
|
-
* Create a new instance of the Cedarling application.
|
|
100
|
-
* Assume that config is `Object`
|
|
101
|
-
*/
|
|
102
|
-
static new(config: object): Promise<Cedarling>;
|
|
103
|
-
/**
|
|
104
|
-
* Create a new instance of the Cedarling application.
|
|
105
|
-
* Assume that config is `Map`
|
|
106
|
-
*/
|
|
107
|
-
static new_from_map(config: Map<any, any>): Promise<Cedarling>;
|
|
108
|
-
/**
|
|
109
|
-
* Authorize an unsigned request carrying an optional single principal.
|
|
110
|
-
* Makes an authorization decision based on the [`RequestUnsigned`].
|
|
111
|
-
* When `principal` is omitted / `null` the core uses Cedar partial evaluation;
|
|
112
|
-
* residual-dependent requests fail closed with `Decision::Deny` and surface
|
|
113
|
-
* residual policy ids in `response.diagnostics.reason`.
|
|
114
|
-
*/
|
|
115
|
-
authorize_unsigned(request: string): Promise<AuthorizeResult>;
|
|
116
|
-
/**
|
|
117
|
-
* Authorize multi-issuer request.
|
|
118
|
-
* Makes authorization decision based on multiple JWT tokens from different issuers
|
|
119
|
-
* The request is passed as a JSON string.
|
|
120
|
-
*/
|
|
121
|
-
authorize_multi_issuer(request: string): Promise<MultiIssuerAuthorizeResult>;
|
|
122
|
-
/**
|
|
123
|
-
* Get logs and remove them from the storage.
|
|
124
|
-
* Returns `Array` of `Map`
|
|
125
|
-
*/
|
|
126
|
-
pop_logs(): Array<any>;
|
|
127
|
-
/**
|
|
128
|
-
* Get specific log entry.
|
|
129
|
-
* Returns `Map` with values or `null`.
|
|
130
|
-
*/
|
|
131
|
-
get_log_by_id(id: string): any;
|
|
132
|
-
/**
|
|
133
|
-
* Returns a list of all log ids.
|
|
134
|
-
* Returns `Array` of `String`
|
|
135
|
-
*/
|
|
136
|
-
get_log_ids(): Array<any>;
|
|
137
|
-
/**
|
|
138
|
-
* Get logs by tag, like `log_kind` or `log level`.
|
|
139
|
-
* Tag can be `log_kind`, `log_level`.
|
|
140
|
-
*/
|
|
141
|
-
get_logs_by_tag(tag: string): any[];
|
|
142
|
-
/**
|
|
143
|
-
* Get logs by request_id.
|
|
144
|
-
* Return log entries that match the given request_id.
|
|
145
|
-
*/
|
|
146
|
-
get_logs_by_request_id(request_id: string): any[];
|
|
147
|
-
/**
|
|
148
|
-
* Get log by request_id and tag, like composite key `request_id` + `log_kind`.
|
|
149
|
-
* Tag can be `log_kind`, `log_level`.
|
|
150
|
-
* Return log entries that match the given request_id and tag.
|
|
151
|
-
*/
|
|
152
|
-
get_logs_by_request_id_and_tag(request_id: string, tag: string): any[];
|
|
153
|
-
/**
|
|
154
|
-
* Push a value into the data store with an optional TTL.
|
|
155
|
-
* If the key already exists, the value will be replaced.
|
|
156
|
-
* If TTL is not provided, the default TTL from configuration is used.
|
|
157
|
-
*
|
|
158
|
-
* # Arguments
|
|
159
|
-
* * `key` - The key for the data entry
|
|
160
|
-
* * `value` - The value to store (any JSON-serializable value)
|
|
161
|
-
* * `ttl_secs` - Optional TTL in seconds (undefined uses default from config)
|
|
162
|
-
*
|
|
163
|
-
* # Example
|
|
164
|
-
* ```javascript
|
|
165
|
-
* cedarling.push_data_ctx("user:123", { name: "John", age: 30 }, 3600);
|
|
166
|
-
* cedarling.push_data_ctx("config", { setting: "value" }); // Uses default TTL
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
push_data_ctx(key: string, value: any, ttl_secs?: number): void;
|
|
170
|
-
/**
|
|
171
|
-
* Get a value from the data store by key.
|
|
172
|
-
* Returns null if the key doesn't exist or the entry has expired.
|
|
173
|
-
*
|
|
174
|
-
* # Arguments
|
|
175
|
-
* * `key` - The key to retrieve
|
|
176
|
-
*
|
|
177
|
-
* # Example
|
|
178
|
-
* ```javascript
|
|
179
|
-
* const value = cedarling.get_data_ctx("user:123");
|
|
180
|
-
* if (value) {
|
|
181
|
-
* console.log(value.name);
|
|
182
|
-
* }
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
get_data_ctx(key: string): any;
|
|
186
|
-
/**
|
|
187
|
-
* Get a data entry with full metadata by key.
|
|
188
|
-
* Returns null if the key doesn't exist or the entry has expired.
|
|
189
|
-
* Includes metadata like creation time, expiration, access count, and type.
|
|
190
|
-
*
|
|
191
|
-
* # Arguments
|
|
192
|
-
* * `key` - The key to retrieve
|
|
193
|
-
*
|
|
194
|
-
* # Example
|
|
195
|
-
* ```javascript
|
|
196
|
-
* const entry = cedarling.get_data_entry_ctx("user:123");
|
|
197
|
-
* if (entry) {
|
|
198
|
-
* console.log(`Created: ${entry.created_at}, Access count: ${entry.access_count}`);
|
|
199
|
-
* }
|
|
200
|
-
* ```
|
|
201
|
-
*/
|
|
202
|
-
get_data_entry_ctx(key: string): any;
|
|
203
|
-
/**
|
|
204
|
-
* Remove a value from the data store by key.
|
|
205
|
-
* Returns true if the key existed and was removed, false otherwise.
|
|
206
|
-
*
|
|
207
|
-
* # Arguments
|
|
208
|
-
* * `key` - The key to remove
|
|
209
|
-
*
|
|
210
|
-
* # Example
|
|
211
|
-
* ```javascript
|
|
212
|
-
* const removed = cedarling.remove_data_ctx("user:123");
|
|
213
|
-
* ```
|
|
214
|
-
*/
|
|
215
|
-
remove_data_ctx(key: string): boolean;
|
|
216
|
-
/**
|
|
217
|
-
* Clear all entries from the data store.
|
|
218
|
-
*
|
|
219
|
-
* # Example
|
|
220
|
-
* ```javascript
|
|
221
|
-
* cedarling.clear_data_ctx();
|
|
222
|
-
* ```
|
|
223
|
-
*/
|
|
224
|
-
clear_data_ctx(): void;
|
|
225
|
-
/**
|
|
226
|
-
* List all entries with their metadata.
|
|
227
|
-
* Returns an array of data entries containing key, value, type, and timing metadata.
|
|
228
|
-
*
|
|
229
|
-
* # Example
|
|
230
|
-
* ```javascript
|
|
231
|
-
* const entries = cedarling.list_data_ctx();
|
|
232
|
-
* entries.forEach(entry => {
|
|
233
|
-
* console.log(`Key: ${entry.key}, Type: ${entry.data_type}`);
|
|
234
|
-
* });
|
|
235
|
-
* ```
|
|
236
|
-
*/
|
|
237
|
-
list_data_ctx(): any[];
|
|
238
|
-
/**
|
|
239
|
-
* Get statistics about the data store.
|
|
240
|
-
* Returns current entry count, capacity limits, and configuration state.
|
|
241
|
-
*
|
|
242
|
-
* # Example
|
|
243
|
-
* ```javascript
|
|
244
|
-
* const stats = cedarling.get_stats_ctx();
|
|
245
|
-
* console.log(`Entries: ${stats.entry_count}/${stats.max_entries}`);
|
|
246
|
-
* ```
|
|
247
|
-
*/
|
|
248
|
-
get_stats_ctx(): DataStoreStats;
|
|
249
|
-
/**
|
|
250
|
-
* Trusted issuer loading status helpers.
|
|
251
|
-
*/
|
|
252
|
-
is_trusted_issuer_loaded_by_name(issuer_id: string): boolean;
|
|
253
|
-
is_trusted_issuer_loaded_by_iss(iss_claim: string): boolean;
|
|
254
|
-
total_issuers(): number;
|
|
255
|
-
loaded_trusted_issuers_count(): number;
|
|
256
|
-
loaded_trusted_issuer_ids(): Array<string>;
|
|
257
|
-
failed_trusted_issuer_ids(): Array<string>;
|
|
258
|
-
}
|
|
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`.
|
|
259
132
|
|
|
260
|
-
|
|
261
|
-
* A WASM wrapper for the Rust `cedarling::AuthorizeResult` struct.
|
|
262
|
-
* Represents the result of an authorization request.
|
|
263
|
-
*/
|
|
264
|
-
export class AuthorizeResult {
|
|
265
|
-
/**
|
|
266
|
-
* Convert `AuthorizeResult` to json string value
|
|
267
|
-
*/
|
|
268
|
-
json_string(): string;
|
|
269
|
-
/**
|
|
270
|
-
* Cedar authorization response for the request.
|
|
271
|
-
*/
|
|
272
|
-
response: AuthorizeResultResponse;
|
|
273
|
-
/**
|
|
274
|
-
* Result of authorization
|
|
275
|
-
* true means `ALLOW`
|
|
276
|
-
* false means `Deny`
|
|
277
|
-
*
|
|
278
|
-
* this field is [`bool`] type to be compatible with [authzen Access Evaluation Decision](https://openid.github.io/authzen/#section-6.2.1).
|
|
279
|
-
*/
|
|
280
|
-
decision: boolean;
|
|
281
|
-
/**
|
|
282
|
-
* Request ID of the authorization request
|
|
283
|
-
*/
|
|
284
|
-
request_id: string;
|
|
285
|
-
}
|
|
133
|
+
#### Token-Based Authorization (Multi-Issuer)
|
|
286
134
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
export class MultiIssuerAuthorizeResult {
|
|
292
|
-
/**
|
|
293
|
-
* Convert `MultiIssuerAuthorizeResult` to json string value
|
|
294
|
-
*/
|
|
295
|
-
json_string(): string;
|
|
296
|
-
/**
|
|
297
|
-
* Result of Cedar policy authorization
|
|
298
|
-
*/
|
|
299
|
-
response: AuthorizeResultResponse;
|
|
300
|
-
/**
|
|
301
|
-
* Result of authorization
|
|
302
|
-
* true means `ALLOW`
|
|
303
|
-
* false means `Deny`
|
|
304
|
-
*/
|
|
305
|
-
decision: boolean;
|
|
306
|
-
/**
|
|
307
|
-
* Request ID of the authorization request
|
|
308
|
-
*/
|
|
309
|
-
request_id: string;
|
|
310
|
-
}
|
|
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.
|
|
311
139
|
|
|
312
|
-
|
|
313
|
-
* A WASM wrapper for the Rust `cedar_policy::Response` struct.
|
|
314
|
-
* Represents the result of an authorization request.
|
|
315
|
-
*/
|
|
316
|
-
export class AuthorizeResultResponse {
|
|
317
|
-
/**
|
|
318
|
-
* Authorization decision
|
|
319
|
-
*/
|
|
320
|
-
readonly decision: boolean;
|
|
321
|
-
/**
|
|
322
|
-
* Diagnostics providing more information on how this decision was reached
|
|
323
|
-
*/
|
|
324
|
-
readonly diagnostics: Diagnostics;
|
|
325
|
-
}
|
|
140
|
+
1. Prepare the tokens.
|
|
326
141
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
*
|
|
331
|
-
* Provides detailed information about how a policy decision was made, including policies that contributed to the decision and any errors encountered during evaluation.
|
|
332
|
-
*/
|
|
333
|
-
export class Diagnostics {
|
|
334
|
-
/**
|
|
335
|
-
* `PolicyId`s of the policies that contributed to the decision.
|
|
336
|
-
* If no policies applied to the request, this set will be empty.
|
|
337
|
-
*
|
|
338
|
-
* The ids should be treated as unordered,
|
|
339
|
-
*/
|
|
340
|
-
readonly reason: string[];
|
|
341
|
-
/**
|
|
342
|
-
* Errors that occurred during authorization. The errors should be
|
|
343
|
-
* treated as unordered, since policies may be evaluated in any order.
|
|
344
|
-
*/
|
|
345
|
-
readonly errors: PolicyEvaluationError[];
|
|
346
|
-
}
|
|
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.
|
|
347
145
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
export class PolicyEvaluationError {
|
|
355
|
-
/**
|
|
356
|
-
* Id of the policy with an error
|
|
357
|
-
*/
|
|
358
|
-
readonly id: string;
|
|
359
|
-
/**
|
|
360
|
-
* Underlying evaluation error string representation
|
|
361
|
-
*/
|
|
362
|
-
readonly error: string;
|
|
363
|
-
}
|
|
146
|
+
```ts
|
|
147
|
+
const tokens = [
|
|
148
|
+
{ mapping: "Acme::Access_Token", payload: acmeAccessToken },
|
|
149
|
+
{ mapping: "Dolphin::Access_Token", payload: dolphinAccessToken },
|
|
150
|
+
];
|
|
151
|
+
```
|
|
364
152
|
|
|
365
|
-
|
|
366
|
-
* DataStoreStats
|
|
367
|
-
* ==============
|
|
368
|
-
*
|
|
369
|
-
* Statistics about the DataStore, providing insight into the current state
|
|
370
|
-
* and usage of the data store, including memory usage metrics and capacity information.
|
|
371
|
-
*/
|
|
372
|
-
export class DataStoreStats {
|
|
373
|
-
/**
|
|
374
|
-
* Number of entries currently stored
|
|
375
|
-
*/
|
|
376
|
-
readonly entry_count: number;
|
|
377
|
-
/**
|
|
378
|
-
* Maximum number of entries allowed (0 = unlimited)
|
|
379
|
-
*/
|
|
380
|
-
readonly max_entries: number;
|
|
381
|
-
/**
|
|
382
|
-
* Maximum size per entry in bytes (0 = unlimited)
|
|
383
|
-
*/
|
|
384
|
-
readonly max_entry_size: number;
|
|
385
|
-
/**
|
|
386
|
-
* Whether metrics tracking is enabled
|
|
387
|
-
*/
|
|
388
|
-
readonly metrics_enabled: boolean;
|
|
389
|
-
/**
|
|
390
|
-
* Total size of all entries in bytes (approximate, based on JSON serialization)
|
|
391
|
-
*/
|
|
392
|
-
readonly total_size_bytes: number;
|
|
393
|
-
/**
|
|
394
|
-
* Average size per entry in bytes (0 if no entries)
|
|
395
|
-
*/
|
|
396
|
-
readonly avg_entry_size_bytes: number;
|
|
397
|
-
/**
|
|
398
|
-
* Percentage of capacity used (0.0-100.0, based on entry count)
|
|
399
|
-
*/
|
|
400
|
-
readonly capacity_usage_percent: number;
|
|
401
|
-
/**
|
|
402
|
-
* Memory usage threshold percentage (from config)
|
|
403
|
-
*/
|
|
404
|
-
readonly memory_alert_threshold: number;
|
|
405
|
-
/**
|
|
406
|
-
* Whether memory usage exceeds the alert threshold
|
|
407
|
-
*/
|
|
408
|
-
readonly memory_alert_triggered: boolean;
|
|
409
|
-
}
|
|
410
|
-
```
|
|
153
|
+
2. Define the resource.
|
|
411
154
|
|
|
412
|
-
|
|
155
|
+
This example targets a document. Its type and attributes must match your schema.
|
|
413
156
|
|
|
414
|
-
|
|
157
|
+
```ts
|
|
158
|
+
const resource = {
|
|
159
|
+
cedar_entity_mapping: { entity_type: "Task::Document", id: "document-1" },
|
|
160
|
+
owner: "alice",
|
|
161
|
+
};
|
|
162
|
+
```
|
|
415
163
|
|
|
416
|
-
|
|
164
|
+
3. Define the action.
|
|
417
165
|
|
|
418
|
-
|
|
166
|
+
```ts
|
|
167
|
+
const action = 'Task::Action::"Read"';
|
|
168
|
+
```
|
|
419
169
|
|
|
420
|
-
|
|
421
|
-
// Option 1: Fetch policy store from URL (simple)
|
|
422
|
-
const BOOTSTRAP_CONFIG = {
|
|
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,
|
|
428
|
-
// ... other config
|
|
429
|
-
};
|
|
430
|
-
const cedarling = await init(BOOTSTRAP_CONFIG);
|
|
431
|
-
|
|
432
|
-
// Option 2: Inline JSON string (for embedded policy stores)
|
|
433
|
-
// policyStoreJson is the policy store JSON as a string
|
|
434
|
-
// See: https://docs.jans.io/stable/cedarling/reference/cedarling-policy-store/
|
|
435
|
-
const policyStoreJson = '{"cedar_version":"4.0","policy_stores":{...}}';
|
|
436
|
-
const BOOTSTRAP_CONFIG = {
|
|
437
|
-
CEDARLING_POLICY_STORE_LOCAL: policyStoreJson,
|
|
438
|
-
// ... other config
|
|
439
|
-
};
|
|
440
|
-
const cedarling = await init(BOOTSTRAP_CONFIG);
|
|
441
|
-
|
|
442
|
-
// Option 3: Custom fetch with auth headers (use init_from_archive_bytes)
|
|
443
|
-
const response = await fetch("https://example.com/policy-store.cjar", {
|
|
444
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
445
|
-
});
|
|
446
|
-
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
447
|
-
const cedarling = await init_from_archive_bytes(BOOTSTRAP_CONFIG, bytes);
|
|
448
|
-
```
|
|
170
|
+
4. Define the context.
|
|
449
171
|
|
|
450
|
-
|
|
172
|
+
Supply request-specific data required by your policies and schema.
|
|
451
173
|
|
|
452
|
-
|
|
174
|
+
```ts
|
|
175
|
+
const context = { tenant: "example" };
|
|
176
|
+
```
|
|
453
177
|
|
|
454
|
-
|
|
178
|
+
5. Build the request.
|
|
455
179
|
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
```
|
|
180
|
+
```ts
|
|
181
|
+
const request = { tokens, action, resource, context };
|
|
182
|
+
```
|
|
459
183
|
|
|
460
|
-
|
|
184
|
+
6. Perform authorization and handle the decision.
|
|
461
185
|
|
|
462
|
-
|
|
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
|
+
```
|
|
463
194
|
|
|
464
|
-
|
|
195
|
+
#### Unsigned Authorization
|
|
465
196
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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.
|
|
472
212
|
|
|
473
|
-
|
|
213
|
+
```ts
|
|
214
|
+
const resource = {
|
|
215
|
+
cedar_entity_mapping: { entity_type: "Task::Document", id: "document-1" },
|
|
216
|
+
owner: "alice",
|
|
217
|
+
};
|
|
218
|
+
```
|
|
474
219
|
|
|
475
|
-
|
|
220
|
+
3. Define the action.
|
|
476
221
|
|
|
477
|
-
|
|
222
|
+
```ts
|
|
223
|
+
const action = 'Task::Action::"Read"';
|
|
224
|
+
```
|
|
478
225
|
|
|
479
|
-
|
|
226
|
+
4. Define the context.
|
|
480
227
|
|
|
481
|
-
|
|
228
|
+
```ts
|
|
229
|
+
const context = { tenant: "example" };
|
|
230
|
+
```
|
|
482
231
|
|
|
483
|
-
|
|
484
|
-
// Push data without TTL (uses default from config)
|
|
485
|
-
cedarling.push_data_ctx("user:123", {
|
|
486
|
-
role: ["admin", "editor"],
|
|
487
|
-
country: "US"
|
|
488
|
-
});
|
|
232
|
+
5. Build the request.
|
|
489
233
|
|
|
490
|
-
|
|
491
|
-
|
|
234
|
+
```ts
|
|
235
|
+
const request = { principal, action, resource, context };
|
|
236
|
+
```
|
|
492
237
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
+
}
|
|
498
287
|
```
|
|
499
288
|
|
|
500
|
-
|
|
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
|
+
```
|
|
501
302
|
|
|
502
|
-
|
|
303
|
+
After a successful batch call, inspect each item in the same order as the
|
|
304
|
+
submitted `items`:
|
|
503
305
|
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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
|
+
}
|
|
509
313
|
}
|
|
510
314
|
```
|
|
511
315
|
|
|
512
|
-
|
|
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
|
|
513
320
|
|
|
514
|
-
|
|
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
|
+
```
|
|
515
329
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
console.log(
|
|
523
|
-
|
|
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);
|
|
524
339
|
}
|
|
525
340
|
```
|
|
526
341
|
|
|
527
|
-
###
|
|
342
|
+
### Context Data
|
|
528
343
|
|
|
529
|
-
|
|
344
|
+
Store application-scoped data for policy evaluation, then retrieve or remove it:
|
|
530
345
|
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
console.log(
|
|
536
|
-
|
|
537
|
-
|
|
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);
|
|
538
354
|
}
|
|
539
355
|
```
|
|
540
356
|
|
|
541
|
-
|
|
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
|
+
### Metrics Snapshot
|
|
542
361
|
|
|
543
|
-
|
|
362
|
+
Destructive read: returns a metrics snapshot and resets the counters.
|
|
544
363
|
|
|
545
|
-
```
|
|
546
|
-
|
|
364
|
+
```ts
|
|
365
|
+
try {
|
|
366
|
+
const snapshot = cedarling.drainMetrics();
|
|
367
|
+
console.log(snapshot.operational_stats.get("authz.requests_total"));
|
|
368
|
+
console.log(snapshot.interval_secs);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
console.error("Metrics snapshot failed", error);
|
|
371
|
+
}
|
|
547
372
|
```
|
|
548
373
|
|
|
549
|
-
|
|
374
|
+
Requires `CEDARLING_METRICS_COLLECTION: "enabled"`. Fails whenever
|
|
375
|
+
`CEDARLING_LOCK_TELEMETRY_INTERVAL` is set, even if the Lock server has no
|
|
376
|
+
telemetry endpoint. `interval_secs` is a plain `Number` (not `BigInt`), so
|
|
377
|
+
`snapshot.interval_secs + 1` works. It carries fractional seconds, so
|
|
378
|
+
sub-second intervals are reported exactly. Use `snapshot.jsonString()` for a
|
|
379
|
+
JSON-serializable form with plain objects.
|
|
550
380
|
|
|
551
|
-
|
|
381
|
+
### Trusted Issuer Readiness
|
|
552
382
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
383
|
+
Before token-based authorization, inspect which configured issuers loaded and
|
|
384
|
+
which failed:
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
console.log("Loaded issuers", cedarling.loadedTrustedIssuerIds());
|
|
388
|
+
console.log("Failed issuers", cedarling.failedTrustedIssuerIds());
|
|
558
389
|
```
|
|
559
390
|
|
|
560
|
-
|
|
391
|
+
To check one issuer, pass its configured identifier to
|
|
392
|
+
`cedarling.isTrustedIssuerLoadedByName(issuerId)`.
|
|
561
393
|
|
|
562
|
-
|
|
394
|
+
### Policy Annotations
|
|
563
395
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
396
|
+
Annotations attach metadata such as descriptions to policies using
|
|
397
|
+
`@key("value")`. They describe policies independently of their authorization rules.
|
|
398
|
+
For example, a policy in your archive can include:
|
|
399
|
+
|
|
400
|
+
```cedar
|
|
401
|
+
@description("Allows Alice to read document-1")
|
|
402
|
+
permit (
|
|
403
|
+
principal == Task::User::"alice",
|
|
404
|
+
action == Task::Action::"Read",
|
|
405
|
+
resource == Task::Document::"document-1"
|
|
406
|
+
);
|
|
569
407
|
```
|
|
570
408
|
|
|
571
|
-
|
|
409
|
+
Inside the unsigned walkthrough's `try` block, retrieve descriptions for the
|
|
410
|
+
determining policy IDs returned in the result:
|
|
411
|
+
|
|
412
|
+
```ts
|
|
413
|
+
const descriptions = cedarling.annotationValues(
|
|
414
|
+
result.response.diagnostics.reason,
|
|
415
|
+
"description",
|
|
416
|
+
);
|
|
417
|
+
console.log(descriptions);
|
|
418
|
+
```
|
|
572
419
|
|
|
573
|
-
|
|
420
|
+
See the [Cedar annotation reference](https://docs.cedarpolicy.com/policies/syntax-policy.html#annotations)
|
|
421
|
+
for annotation syntax and behavior.
|
|
574
422
|
|
|
575
|
-
|
|
423
|
+
### Shutdown
|
|
424
|
+
|
|
425
|
+
When the application finishes using a Cedarling instance, shut it down:
|
|
426
|
+
|
|
427
|
+
```ts
|
|
576
428
|
try {
|
|
577
|
-
cedarling.
|
|
429
|
+
await cedarling.shutDown();
|
|
578
430
|
} catch (error) {
|
|
579
|
-
|
|
580
|
-
console.log("Invalid key provided");
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
const value = cedarling.get_data_ctx("nonexistent");
|
|
585
|
-
if (value === null) {
|
|
586
|
-
console.log("Key not found");
|
|
431
|
+
console.error("Cedarling shutdown failed", error);
|
|
587
432
|
}
|
|
588
433
|
```
|
|
589
434
|
|
|
590
|
-
###
|
|
435
|
+
### Other Integration Paths
|
|
591
436
|
|
|
592
|
-
|
|
437
|
+
#### Edge Deployments
|
|
593
438
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
439
|
+
Use the ESM-only `./edge` entry in hosts whose deployment tool bundles the package's
|
|
440
|
+
WASM binary as a precompiled WebAssembly module. In Cloudflare Workers, initialize inside
|
|
441
|
+
the [request context](https://developers.cloudflare.com/workers/runtime-apis/request/#the-request-context)
|
|
442
|
+
so policy downloads can run:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
import { init } from "@janssenproject/cedarling_wasm/edge";
|
|
446
|
+
|
|
447
|
+
export default {
|
|
448
|
+
async fetch() {
|
|
449
|
+
let cedarling;
|
|
450
|
+
try {
|
|
451
|
+
cedarling = await init({
|
|
452
|
+
CEDARLING_APPLICATION_NAME: "edge-api",
|
|
453
|
+
CEDARLING_POLICY_STORE_URI: "https://example.com/policy-store.cjar",
|
|
454
|
+
});
|
|
455
|
+
return new Response("Cedarling initialized");
|
|
456
|
+
} catch (error) {
|
|
457
|
+
console.error("Cedarling initialization failed", error);
|
|
458
|
+
return new Response("Internal server error", { status: 500 });
|
|
459
|
+
} finally {
|
|
460
|
+
try {
|
|
461
|
+
await cedarling?.shutDown();
|
|
462
|
+
} catch (error) {
|
|
463
|
+
console.error("Cedarling shutdown failed", error);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
},
|
|
601
467
|
};
|
|
602
468
|
```
|
|
603
469
|
|
|
604
|
-
|
|
470
|
+
#### Manual Bundler Integration
|
|
605
471
|
|
|
606
|
-
|
|
472
|
+
For application-controlled WASM loading, configure your ESM bundler to emit the
|
|
473
|
+
package's `./wasm` export as a URL-addressable binary asset. Configure the server
|
|
474
|
+
to serve it with the `application/wasm` content type. The example below reuses
|
|
475
|
+
`config` and `policyArchiveBytes` from
|
|
476
|
+
[Load a Cedar Archive from Bytes](#load-a-cedar-archive-from-bytes), replacing
|
|
477
|
+
that section's initialization call:
|
|
607
478
|
|
|
608
|
-
|
|
479
|
+
```ts
|
|
480
|
+
import initWasm, {
|
|
481
|
+
initFromArchiveBytes,
|
|
482
|
+
} from "@janssenproject/cedarling_wasm/manual";
|
|
483
|
+
import wasmUrl from "@janssenproject/cedarling_wasm/wasm";
|
|
609
484
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
485
|
+
let cedarling;
|
|
486
|
+
try {
|
|
487
|
+
await initWasm({ module_or_path: wasmUrl });
|
|
488
|
+
cedarling = await initFromArchiveBytes(config, policyArchiveBytes);
|
|
489
|
+
} catch (error) {
|
|
490
|
+
console.error("WASM loading or Cedarling initialization failed", error);
|
|
491
|
+
throw error;
|
|
492
|
+
}
|
|
617
493
|
```
|
|
494
|
+
|
|
495
|
+
Configure the `.wasm` import to return an asset URL; the exact rule or plugin
|
|
496
|
+
depends on your bundler.
|
|
497
|
+
|
|
498
|
+
## Upgrading Existing Applications
|
|
499
|
+
|
|
500
|
+
Update calls such as `authorize_unsigned()` to `authorizeUnsigned()`,
|
|
501
|
+
`shut_down()` to `shutDown()`, and `json_string()` to `jsonString()`.
|
|
502
|
+
Bootstrap keys (`CEDARLING_*`), request JSON, result/data fields such as
|
|
503
|
+
`request_id`, and serialized JSON retain their names.
|
|
504
|
+
|
|
505
|
+
## See Also
|
|
506
|
+
|
|
507
|
+
- [JavaScript tutorial](https://docs.jans.io/stable/cedarling/tutorials/javascript/)
|
|
508
|
+
- [Full API reference](https://docs.jans.io/stable/cedarling/tutorials/javascript/#api-reference)
|
|
509
|
+
- [Bootstrap-property reference](https://docs.jans.io/stable/cedarling/reference/cedarling-properties/)
|
|
510
|
+
- [Cedar Archive format](https://docs.jans.io/nightly/cedarling/reference/cedarling-policy-store/#cedar-archive-cjar-format)
|
|
511
|
+
- [Maintainer guide](https://github.com/JanssenProject/jans/blob/main/jans-cedarling/bindings/cedarling_wasm/js/docs/maintainer.md)
|