Cedarling Nativity Plan - JanssenProject/jans GitHub Wiki

Topology Diagram

nativity-graphic

JS App

  • Needs to call the WASM component using a few javascript lines of code (ideally 1-2)
  • Input from JS component is object
input = { 
           "access_token": "...", 
           "id_token": "...", 
           "userinfo_token": "...", 
           "tx_token": "...",
           "resource": {"id": "12345", "type": "Ticket", "creator": "[email protected]", "organization": "gluu"},
           "action": "View",
           "context": {
                       "ip_address": "54.9.21.201",
                       "network_type": "VPN",
                       "user_agent": "Chrome 125.0.6422.77 (Official Build) (arm64)",
                       "time": "1719266610.98636",
                      }
         }

decision_result = authz(input)

Bootstrap properties

  • CEDARLING_APPLICATION_NAME : Human friendly identifier for this application

  • CEDARLING_POLICY_STORE_URI : Location of policy store JSON, used if policy store is not local, or retreived from Lock Master.

  • CEDARLING_JWT_VALIDATION : Enabled | Disabled

  • CEDARLING_JWT_SIGNATURE_ALGORITHMS_SUPPORTED : ....

  • CEDARLING_REQUIRE_AUD_VALIDATION : Enabled | Disabled. Controls if Cedarling will discard id_token without an access token with the corresponding client_id.

  • CEDARLING_ROLE_MAPPING : Default: {"id_token": "role", "userinfo_token": "role"} but the role may be sent as an access token, or with a different identifier. For example, for Ping Identity, you might see {"userinfo_token": "memberOf"}.

  • CEDARLING_LOG_TYPE : off, memory, std_out, lock

  • CEDARLING_LOG_TTL : in case of memory store, TTL (time to live) of log entities in seconds.

The following bootstrap properties are only needed for enterprise deployments.

  • CEDARLING_LOCK : Enabled | Disabled. If Enabled, the Cedarling will connect to the Lock Master for policies, and subscribe for SSE events.

  • CEDARLING_LOCK_MASTER_CONFIGURATION_URI : Required if LOCK == Enabled. URI where Cedarling can get JSON file with all required metadata about Lock Master, i.e. .well-known/lock-master-configuration.

  • CEDARLING_LOCK_SSA_JWT : SSA for DCR in a Lock Master deployment. The Cedarling will validate this SSA JWT prior to DCR.

  • CEDARLING_POLICY_STORE_ID : The identifier of the policy stored needed only for Lock Master deployments.

  • CEDARLING_AUDIT_LOG_INTERVAL : How often to send log messages to Lock Master (0 to turn off trasmission)

  • CEDARLING_AUDIT_HEALTH_INTERVAL : How often to send health messages to Lock Master (0 to turn off transmission)

  • CEDARLING_AUDIT_TELEMETRY_INTERVAL : How often to send telemetry messages to Lock Master (0 to turn off transmission)

  • CEDARLING_DYNAMIC_CONFIGURATION : Enabled | Disabled, controls whether Cedarling should listen for SSE config updates

  • CEDARLING_GET_TOKEN_STATUS_LIST_UPDATES : Enabled | Disabled, controls whether Cedarling should listen for SSE OAuth Status List updates

Cedarling Policy Store

The Cedarling Policy Store is a JSON file that contains all the data the Cedarling needs to verify JWT tokens and evaluate policies:

  1. Cedar Schema - JSON format Schema file
  2. Cedar Policies - JSON format Policy Set file (beware CLI bug cedar-950)
  3. Trusted Issuers - JSON file with below syntax

cedarling_store.json schema

{
    "app_id": "",
    "policies": {...},
    "schema": {...},
    "trusted_idps": []
}

Trusted Issuer Schema

Because it's out of scope of Cedar, we need to define this:

{"name": "Google", 
 "Description": "Consumer IDP", 
 "openid_configuration_endpoint": "https://accounts.google.com/.well-known/openid-configuration",
 "access_tokens": {"trusted": True}, 
 "id_tokens": {"trusted":True, "principal_identifier": "email"},
 "userinfo_tokens": {"trusted": True, "role_mapping": "role"},  
 "tx_tokens": {"trusted": True}
},
...

Cedarling Modules

cedarling_modules

Startup Sequence Diagram

Cedarling_Startup_Sequence

Source

Authz Sequence Diagram

cedarling-authz-sequence-diagram

Source

Cedar Schema

namespace Jans {
    // ******  TYPES  ******
    type Url = {
        protocol: String,
        host: String,
        path: String,
    };
    type email_address = {
        id: String, 
        domain: String,
    };
    type Context = {
            network: ipaddr,
            network_type: String,
            user_agent: String, 
            operating_system: String,
            device_health: Set<String>,
            current_time: Long,
            geolocation: Set<String>,
            fraud_indicators: Set<String>,
    };

    // ******  Entities  ******
    entity Workload  = {
        client_id: String,
        iss: TrustedIssuer,
        name: String,
    };
    entity Access_token  = {
        aud: String,
        exp: Long,
        iat: Long,
        iss: TrustedIssuer,
        jti: String,
        nbf: Long,
        scope: String,
    };
    entity TrustedIssuer = {
        issuer_entity_id: Url,
    };
    entity Role;
    entity User in [Role] {
        sub: String,
        username: String,
        email: email_address,
        phone_number: String,
        role: Set<String>,
    };
    entity id_token  = {
        acr: Set<String>,
        amr: String,
        aud: String,
        azp: String,
        birthdate: String,
        email: email_address,
        exp: Long,
        iat: Long,
        iss: TrustedIssuer,
        jti: String,        
        name: String,
        phone_number: String,
        role: Set<String>,
        sub: String,
    };
    entity Userinfo_token  = {
        aud: String,
        birthdate: String,
        email: email_address,
        exp: Long,
        iat: Long,
        iss: TrustedIssuer,
        jti: String,
        name: String,
        phone_number: String,
        role: Set<String>,
        sub: String,
    };

    // ******  Actions  ******
    action Compare appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Execute appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Monitor appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Read appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Search appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Share appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Tag appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
    action Write appliesTo {
        principal: [User, Role],
        resource: Application,
        context: Context,
    };
}

JSON Format

Entity Mapping

  • TrustedIssuer: Created on startup from Policy Store
  • Workload: Created from access token client_id
  • Application: Created if input supplies an Application name
  • Role: Created for each role claim value in the joined id_token and userinfo token
  • User: Created based on the joined id_token and userinfo token. sub is the entity identifier
  • Access_token: 1:1 mapping from claims in token
  • id_token: 1:1 mapping from claims in token
  • Userinfo_token: 1:1 mapping from claims in token

Cederling Agama Lab / AdminUI Mockups

Here

Lock Master Swagger

Swagger UI

Cedarling token validation

  • Validate signature from Trusted Issuer (if hash not found in cache)
  • If bootstrap property CEDARLING_REQUIRE_AUD_VALIDATION is true... discard id_token if aud does not match access_token client_id
  • Discard any Userinfo token not associated with a sub from the id_token
  • If Cedarling is Locked, check token status
  • Check access token and id_token exp and nbf claims if time sent in Context

Lock Design Goals

Original design goals of Jans Lock and the Cedarling:

  • Move the PDP to the edge of the network--the browser itself.
  • Make the PDP performant and deterministic (i.e. milliseond statup time and always return a PERMIT/DENY response).
  • Empower application developers to author policies appropriate for the resources and actions they need to protect.
  • Centralilze audit and health data collection
  • Send updates to the Cedarlings from the Lock Master to enable realtime attack mitigation

Cedarling logger

Cedarling application has internal logger.

Configuration

Using configuration parameter CEDARLING_LOG_TYPE you can set up:

  • off - disabled
  • memory - store log entry in memory
  • std_out - write log entry data to std output stream
  • lock - the logger sends log data to the server (corporate feature).

Using the memory logger, we can set time to live entry in memory using CEDARLING_LOG_TTL.

Entry types

Each log entry marked with log type. In field log_kind. Possible variants:

  • Decision
  • System
  • Metric

Log Strage interface

pub trait LogStorage {
    /// return logs and remove them from the storage
    fn pop_logs(&self) -> Vec<LogEntry>;

    /// get specific log entry
    fn get_log_by_id(&self, id: &str) -> Option<LogEntry>;

    /// returns a list of all log ids
    fn get_log_ids(&self) -> Vec<String>;
}
⚠️ **GitHub.com Fallback** ⚠️