-
Notifications
You must be signed in to change notification settings - Fork 160
Cedarling Project Overview
This document serves as a high-level overview of Cedarling's current internals and should help with onboarding, restructuring, or future feature implementation.
For feature-specific plans, refer to: Cedarling Nativity Plan.
Powered by the Cedar Rust engine, the Cedarling validates JWTs and maps the JSON payload claims to Cedar entities, enabling authorization via the Cedarling::authorize method. It also offers a secondary method, Cedarling::authorize_unsigned, which accepts pre-constructed Cedar entities.
The Cedarling performs other tasks associated with a Policy Decision Point or "PDP", like logging, policy store management, workload identity registration, and communication with enterprise IT infrastructure. In order to perform these services, the Cedarling runs an in-memory KV store with built in record expiration.
-
authz: Policy evaluation logic -
bootstrap_config: Loads config structs viaSerde::Deserialize -
common: Shared data structures across the app -
entity_builder: Builds Cedar entities from JWTs or manually for unsigned auth -
http: HTTP helpers (multi-target safe) -
init: Initializes the services using the bootstrap configs -
jwt: JWT parsing and validation -
lock: Background task logic to communicate with the Lock Server -
log: Logger setup -
tests: End-to-end tests
Note: The
initmodule may be over-abstracted. Consider simplifying the service factory logic.
Cedar authorization uses the PARC model:
- Policy
- Action
- Resource
- Context (e.g. headers, timestamps, user posture)
Typical JWT-based flow:
- Call
Cedarling::authorize - Validate JWT via
JwtService - Build entities using
EntityBuilder - Evaluate entities against policies in
authz - Return
Ok(AuthorizeResult)orErr(AuthorizeError)
Alternative: Use Cedarling::authorize_unsigned for direct entity input.
Handled via JwtService in the jwt module. JWTs from untrusted issuers are rejected with a warning.
Criteria for valid JWT:
- Comes from a trusted issuer
- Has a defined token metadata
Handled via EntityBuilder in the entity_builder module. JWTs from untrusted issuers are rejected with an error.
JWT claims are mapped to Cedar attributes (1:1 by default).
Mappings are configured via the Token Entity Metadata Schema's claim mapping field in the Policy Store.
NOTE
JWTs might contain claims that aren't in the Cedar Entity's Schema. Cedarling should be able to ignore these and not fail immediately.
This is probably the slowest step in the authorization procedure since we have to continually re-check the schema against the input. Improvements must be made.
WASM targets require special handling:
- Custom HTTP logic (JS is single-threaded)
- No
stdoutprinting (usewasm-bindgen)
Refer to wasm-bindgen for bridging native/WASM features.
Bindings code are separated by language in jans-cedarling/bindings. They each should have a README.md which contains setup instructions.
Cedarling communicates with the Lock Server for:
- Logs
- Health checks (WIP)
- Telemetry (WIP)
- Policy updates (WIP)
Uses Dynamic Client Registration (DCR) to obtain access tokens. Logic is in the lock module.
Use the CEDARLING_LOCK_SSA_JWT to provide the Software Statement Assertion JWT. This is optional as stated in the spec but may be required by the Auth server.
Use the head branch of the Jans server. Earlier versions (e.g. 1.5) had bugs.
Download latest builds from: Dynamic Download.
Note that the other installation directions will not give you the latest build even if you're in the head branch of the docs so make sure to use the Dynamic download.
The target speed is sub-100ms per call to Cedarling::authorize.
We once tried to implement JWT caching in only in the JWT module but it didn't present any significant gains.
After profiling using pprof, we found out that the biggest bottleneck is creating the Cedar entities from the JWTs. Caching the whole request might improve the speed but just caching the JWTs wont.
This should output an SVG named cedarling_profiling_flamegraph.
cargo run --example profiling- The
entity_builderrelies heavily on the structure of the token metadataΓÇöunexpected schema changes might break parsing silently. - WASM build will sometimes fail even if it works on native. One example is you cant just spawn a new task using
tokio::spawn. There are some helper function in thehttp_utilsmodule to solve the usual tasks. - The Lock Server will not recognized client immediately after DCR. Expect receive some unauthorized responses for the first few seconds if you're testing locally.
- Cedar Policy
- OpenID Connect Core
- OpenID Connect Discovery
- OIDC Dynamic Client Registration
- JSON Web Token (RFC 7519)
- OAuth2 DCR (RFC 7591)