From 47407376456bafc2d7936b188c20242bc1bbea4f Mon Sep 17 00:00:00 2001 From: Oleh Bohzok <6554798+olehbozhok@users.noreply.github.com> Date: Thu, 9 Jan 2025 02:44:37 +0200 Subject: [PATCH] chore(jans-cedarling): update documentation Signed-off-by: Oleh Bohzok <6554798+olehbozhok@users.noreply.github.com> Signed-off-by: Oleh Bohzok --- docs/cedarling/cedarling-authz.md | 6 +- docs/cedarling/wasm/README.md | 228 ++++++++++++++++++ .../bindings/cedarling_wasm/README.md | 151 +++++++++++- .../bindings/cedarling_wasm/index.html | 2 +- .../bindings/cedarling_wasm/src/lib.rs | 2 +- 5 files changed, 384 insertions(+), 5 deletions(-) create mode 100644 docs/cedarling/wasm/README.md diff --git a/docs/cedarling/cedarling-authz.md b/docs/cedarling/cedarling-authz.md index 0f5f03fe0f3..89f3a5c7619 100644 --- a/docs/cedarling/cedarling-authz.md +++ b/docs/cedarling/cedarling-authz.md @@ -55,7 +55,9 @@ Action, Resource and Context is sent by the application in the authorization req this is a sample request from a hypothetical application: ```js -input = { +const bootstrap_config = {...}; +const cedarling = await init(bootstrap_config); +let input = { "tokens": { "access_token": "eyJhbGc....", "id_token": "eyJjbGc...", @@ -76,7 +78,7 @@ input = { } } -decision_result = authz(input) +decision_result = await cedarling(input) ``` ## Automatically Adding Entity References to the Context diff --git a/docs/cedarling/wasm/README.md b/docs/cedarling/wasm/README.md new file mode 100644 index 00000000000..b58712cf220 --- /dev/null +++ b/docs/cedarling/wasm/README.md @@ -0,0 +1,228 @@ +--- +tags: + - cedarling + - wasm +--- + +# WASM for Cedarling + +Cedarling provides a binding for JavaScript programs via the `wasm-pack` tool. This allows browser developers to use the cedarling crate in their code directly. + +## Requirements + +- Rust 1.63 or greater +- Installed `wasm-pack` via `cargo` +- clang with `wasm` target support + +## Building + +- Install `wasm-pack` by: + + ```sh + cargo install wasm-pack + ``` + +- Build cedarling `wasm` in release: + + ```bash + wasm-pack build --release --target web + ``` + + `wasm-pack` automatically make optimization of `wasm` binary file, using `wasm-opt`. +- Get result in the `pkg` folder. + +## Including in projects + +For using result files in browser project you need make result `pkg` folder accessible for loading in the browser so that you can later import the corresponding file from the browser. + +Here is example of code snippet: + +```html + +``` + +## Usage + +Before usage make sure that you have completed `Building` steps. +You can find usage examples in the following locations: + +- `jans-cedarling/bindings/cedarling_wasm/index.html`: A simple example demonstrating basic usage. +- `jans-cedarling/bindings/cedarling_wasm/cedarling_app.html`: A fully featured `Cedarling` browser app where you can test and validate your configuration. + +### Defined API + +```ts +/** + * Create a new instance of the Cedarling application. + * This function can take as config parameter the eather `Map` other `Object` + */ +export function init(config: any): Promise; + +/** + * The instance of the Cedarling application. + */ +export class Cedarling { + /** + * Create a new instance of the Cedarling application. + * Assume that config is `Object` + */ + static new(config: object): Promise; + /** + * Create a new instance of the Cedarling application. + * Assume that config is `Map` + */ + static new_from_map(config: Map): Promise; + /** + * Authorize request + * makes authorization decision based on the [`Request`] + */ + authorize(request: any): Promise; + /** + * Get logs and remove them from the storage. + * Returns `Array` of `Map` + */ + pop_logs(): Array; + /** + * Get specific log entry. + * Returns `Map` with values or `null`. + */ + get_log_by_id(id: string): any; + /** + * Returns a list of all log ids. + * Returns `Array` of `String` + */ + get_log_ids(): Array; +} + +/** + * A WASM wrapper for the Rust `cedarling::AuthorizeResult` struct. + * Represents the result of an authorization request. + */ +export class AuthorizeResult { + /** + * Convert `AuthorizeResult` to json string value + */ + json_string(): string; + /** + * Result of authorization where principal is `Jans::Workload` + */ + workload?: AuthorizeResultResponse; + /** + * Result of authorization where principal is `Jans::User` + */ + person?: AuthorizeResultResponse; + /** + * Result of authorization + * true means `ALLOW` + * false means `Deny` + * + * this field is [`bool`] type to be compatible with [authzen Access Evaluation Decision](https://openid.github.io/authzen/#section-6.2.1). + */ + decision: boolean; +} + +/** + * A WASM wrapper for the Rust `cedar_policy::Response` struct. + * Represents the result of an authorization request. + */ +export class AuthorizeResultResponse { + /** + * Authorization decision + */ + readonly decision: boolean; + /** + * Diagnostics providing more information on how this decision was reached + */ + readonly diagnostics: Diagnostics; +} + +/** + * Diagnostics + * =========== + * + * Provides detailed information about how a policy decision was made, including policies that contributed to the decision and any errors encountered during evaluation. + */ +export class Diagnostics { + /** + * `PolicyId`s of the policies that contributed to the decision. + * If no policies applied to the request, this set will be empty. + * + * The ids should be treated as unordered, + */ + readonly reason: (string)[]; + /** + * Errors that occurred during authorization. The errors should be + * treated as unordered, since policies may be evaluated in any order. + */ + readonly errors: (PolicyEvaluationError)[]; +} + +/** + * PolicyEvaluationError + * ===================== + * + * Represents an error that occurred when evaluating a Cedar policy. + */ +export class PolicyEvaluationError { + /** + * Id of the policy with an error + */ + readonly id: string; + /** + * Underlying evaluation error string representation + */ + readonly error: string; +} +``` diff --git a/jans-cedarling/bindings/cedarling_wasm/README.md b/jans-cedarling/bindings/cedarling_wasm/README.md index 7a36c132216..f49af05a1a8 100644 --- a/jans-cedarling/bindings/cedarling_wasm/README.md +++ b/jans-cedarling/bindings/cedarling_wasm/README.md @@ -36,4 +36,153 @@ To run example using `index.html` you need execute following steps: 1. Build wasm cedarling. 2. Run webserver using `python3 -m http.server` or any other. -3. Visit [localhost](http://localhost:8000/). +3. Visit example app [localhost](http://localhost:8000/), on this app you will get log in browser console. + - Also you can try use cedarling with web app using [cedarling_app](http://localhost:8000/cedarling_app.html), using custom bootstrap properties and request. + +## WASM Usage + +After building WASM bindings in folder `pkg` you can find where you can find `cedarling_wasm.js` and `cedarling_wasm.d.ts` where is defined interface for application. + +In `index.html` described simple usage of `cedarling wasm` API: + +```js + import { BOOTSTRAP_CONFIG, REQUEST } from "/example_data.js" // Import js objects: bootstrap config and request + import initWasm, { init } from "/pkg/cedarling_wasm.js"; + + async function main() { + await initWasm(); // Initialize the WebAssembly module + + let instance = await init(BOOTSTRAP_CONFIG); + let result = await instance.authorize(REQUEST); + console.log("result:", result); + } + main().catch(console.error); +``` + +Before using any function from library you need initialize WASM runtime by calling `initWasm` function. + +### Defined API + +```ts +/** + * Create a new instance of the Cedarling application. + * This function can take as config parameter the eather `Map` other `Object` + */ +export function init(config: any): Promise; + +/** + * The instance of the Cedarling application. + */ +export class Cedarling { + /** + * Create a new instance of the Cedarling application. + * Assume that config is `Object` + */ + static new(config: object): Promise; + /** + * Create a new instance of the Cedarling application. + * Assume that config is `Map` + */ + static new_from_map(config: Map): Promise; + /** + * Authorize request + * makes authorization decision based on the [`Request`] + */ + authorize(request: any): Promise; + /** + * Get logs and remove them from the storage. + * Returns `Array` of `Map` + */ + pop_logs(): Array; + /** + * Get specific log entry. + * Returns `Map` with values or `null`. + */ + get_log_by_id(id: string): any; + /** + * Returns a list of all log ids. + * Returns `Array` of `String` + */ + get_log_ids(): Array; +} + +/** + * A WASM wrapper for the Rust `cedarling::AuthorizeResult` struct. + * Represents the result of an authorization request. + */ +export class AuthorizeResult { + /** + * Convert `AuthorizeResult` to json string value + */ + json_string(): string; + /** + * Result of authorization where principal is `Jans::Workload` + */ + workload?: AuthorizeResultResponse; + /** + * Result of authorization where principal is `Jans::User` + */ + person?: AuthorizeResultResponse; + /** + * Result of authorization + * true means `ALLOW` + * false means `Deny` + * + * this field is [`bool`] type to be compatible with [authzen Access Evaluation Decision](https://openid.github.io/authzen/#section-6.2.1). + */ + decision: boolean; +} + +/** + * A WASM wrapper for the Rust `cedar_policy::Response` struct. + * Represents the result of an authorization request. + */ +export class AuthorizeResultResponse { + /** + * Authorization decision + */ + readonly decision: boolean; + /** + * Diagnostics providing more information on how this decision was reached + */ + readonly diagnostics: Diagnostics; +} + +/** + * Diagnostics + * =========== + * + * Provides detailed information about how a policy decision was made, including policies that contributed to the decision and any errors encountered during evaluation. + */ +export class Diagnostics { + /** + * `PolicyId`s of the policies that contributed to the decision. + * If no policies applied to the request, this set will be empty. + * + * The ids should be treated as unordered, + */ + readonly reason: (string)[]; + /** + * Errors that occurred during authorization. The errors should be + * treated as unordered, since policies may be evaluated in any order. + */ + readonly errors: (PolicyEvaluationError)[]; +} + +/** + * PolicyEvaluationError + * ===================== + * + * Represents an error that occurred when evaluating a Cedar policy. + */ +export class PolicyEvaluationError { + /** + * Id of the policy with an error + */ + readonly id: string; + /** + * Underlying evaluation error string representation + */ + readonly error: string; +} +``` diff --git a/jans-cedarling/bindings/cedarling_wasm/index.html b/jans-cedarling/bindings/cedarling_wasm/index.html index 80308f5e145..fb5078e883c 100644 --- a/jans-cedarling/bindings/cedarling_wasm/index.html +++ b/jans-cedarling/bindings/cedarling_wasm/index.html @@ -38,7 +38,7 @@

It is Cedarling example WASM page