Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(jans-cedarling)!: move TOKEN_CONFIGS into the token_metadata schema #10972

Open
wants to merge 49 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8ed7425
wip(jans-cedarling): add fields to TokenEntityMetadata
rmarinn Feb 18, 2025
3d87189
wip(jans-cedarling): remove dependence of jwt_service to TOKEN_CONFIGS
rmarinn Feb 20, 2025
db6088a
refactor!(jans-cedarling): remove token configs from bootstrap props
rmarinn Feb 20, 2025
42332f8
test(jans-cedarling): remove duplicate tests
rmarinn Feb 20, 2025
5752795
refactor!(jans-cedarling): remove CEDARLING_TOKEN_CONFIGS bootstrap p…
rmarinn Feb 20, 2025
6bbcc8f
refactor!(jans-cedarling): rename entity_mapping to principal_mapping
rmarinn Feb 20, 2025
cbc36b2
refactor!(jans-cedarling): rename principal_identifier to token_id
rmarinn Feb 20, 2025
5391b52
feat(jans-cedarling): add workload_id in TokenEntityMetadata
rmarinn Feb 20, 2025
081fb33
refactor(jans-cedarling): define default token_id in TokenEntityMetadata
rmarinn Feb 20, 2025
1fe22f0
Merge branch 'main' into jans-cedarling-10888
rmarinn Feb 20, 2025
197c4f8
refactor(jans-cedarling): use token entity metadata to create Workload
rmarinn Feb 20, 2025
5a67739
refactor(jans-cedarling): use token entity metadata to create User
rmarinn Feb 20, 2025
5641f74
refactor(jans-cedarling): use token entity metadata to create Role
rmarinn Feb 20, 2025
12fd44d
refactor(jans-cedarling): cleanup implementation of Attribute::build_…
rmarinn Feb 22, 2025
4c27d36
wip(jans-cedarling): implement new build entity
rmarinn Feb 22, 2025
2286c20
wip(jans-cedarling): remove schema dependence of entity builder
rmarinn Feb 26, 2025
de5284c
refactor(jans-cedarling)!: move TOKEN_CONFIGS into the token_metadata…
rmarinn Feb 28, 2025
3b0249d
test: remove redundant tests in mapping_entities
rmarinn Feb 28, 2025
960da8b
fix(jans-cedarling): support for getting entity id from array claims
rmarinn Feb 28, 2025
9cd8732
test(jans-cedarling): fix policy tests the broke because of the refactor
rmarinn Mar 2, 2025
b0f920c
test(jans-cedarling): update schema for uniffi test
rmarinn Mar 2, 2025
211a4b0
chore(jans-cedarling): resolve clippy issues
rmarinn Mar 2, 2025
cc94ed6
refactor(jans-cedarling): handle errors in build entity attributes
rmarinn Mar 2, 2025
faa6f07
refactor(jans-cedarling): gracefully handle error in entity builder init
rmarinn Mar 2, 2025
cf34531
Merge branch 'main' into jans-cedarling-10888
rmarinn Mar 2, 2025
aca7994
test(jans-cedarling): update python tests
rmarinn Mar 2, 2025
2ae9afe
docs(jans-cedarling): add a Cedarling entities section
rmarinn Mar 2, 2025
f32b124
feat(jans-cedarling): add policy_store_schema.json
rmarinn Mar 3, 2025
1761b5f
refactor(jans-cedarling): update bootstrap.json in iOS binding
rmarinn Mar 3, 2025
ecb640b
docs(jans-cedarling): remove references to CEDARLING_TOKEN_CONFIGS
rmarinn Mar 3, 2025
e9c142a
refactor(jans-cedarling)!: rename Jans::id_token to Jans::Id_token
rmarinn Mar 3, 2025
382df5e
fix(jans-cedarling): principal id srcs not getting resolved correctly
rmarinn Mar 3, 2025
f82954e
test(jans-cedarling): update inputs and schema for WASM tests
rmarinn Mar 3, 2025
c9e34a0
chore(jans-cedarling): resolve clippy issues
rmarinn Mar 3, 2025
74c5f80
docs: fix attribute mappings table
rmarinn Mar 4, 2025
edaed3d
refactor: update descriptions in the policy store schema
rmarinn Mar 4, 2025
4a959de
test: add additional tests
rmarinn Mar 5, 2025
4630567
refactor: no longer require the policy_store_version in the schema
rmarinn Mar 5, 2025
d667a74
fix: context creation failing due to using the wrong namespace
rmarinn Mar 6, 2025
19181ec
docs: fix typos in cedarling-entities.md
rmarinn Mar 6, 2025
bbc58ff
chore: remove commented code in the examples
rmarinn Mar 6, 2025
dfa79fb
fix: incorrect bootstrap props in wasm test
rmarinn Mar 6, 2025
2b15b4b
refactor: make default token id srcs a constant
rmarinn Mar 6, 2025
a131825
refactor: make id srcs resolving functions more readable
rmarinn Mar 6, 2025
07f7d4e
docs: clarify the sources of the workload and user entity attrs
rmarinn Mar 6, 2025
2a170ed
feat: implement CEDARLING_MAPPING_TRUSTED_ISSUER bootstrap property
rmarinn Mar 6, 2025
cf79898
chore: remove commented code and improve code syntax
rmarinn Mar 6, 2025
1c02ab6
refactor: remove pretty_assertions import on the main cedarling crate
rmarinn Mar 6, 2025
8c9303d
refactor: move the entity builder to it's own service module
rmarinn Mar 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions docs/cedarling/cedarling-entities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
tags:
- administration
- Cedar
- Cedarling
- Principal
- Mappings
---

# Cedarling Principal Mappings

Cedarling automatically creates the following entities:

- [Trusted Issuer](#trusted-issuer-entity)
- [Workload](#workload-entity)
- [User](#user-entity)
- [Role](#role-entity)
- [JWT Entities](#jwt-entities)

The entity type names of the Workload and User entities can be customized via the `CEDARLING_MAPPING_USER` and `CEDARLING_MAPPING_WORKLOAD` [properties](./cedarling-properties.md) respectively.

> ***Notes***
> - All entity creation and attribute population logic is configurable via the [Token Metadata Schema (TEMS)](./cedarling-policy-store.md#token-metadata-schema) and [Cedarling bootstrap properties](./cedarling-properties.md).
> - Attribute presence depends on token contents and policy store configuration.
> - Role inheritance simplifies **user-role mapping** for RBAC policy enforcement.

## Trusted Issuer

Cedarling creates a Trusted Issuer entity at startup for each trusted issuer defined in the [policy store](./cedarling-policy-store.md#trusted-issuers-schema).

- *Default Type Name:* `Jans::TrustedIssuer`
- *Entity ID:* Set using the name of the trusted issuer object in the policy store.

## Workload Entity

Cedarling creates a **Workload** entity for each request when the `CEDARLING_WORKLOAD_AUTHZ` [bootstrap property](./cedarling-properties.md) is set to `enabled`.

- *Default Type Name:* `Jans::Workload`
- *Entity ID:* Determined by the `workload_id` attribute from the [Token Entity Metadata Schema (TEMS)](./cedarling-policy-store.md#token-metadata-schema).
- If `workload_id` is **not set**, Cedarling will fall back to the following claims (in order):

1. `aud` from the `access_token`
2. `client_id` from the `access_token`

### Example Workload Schema

```cedarschema/
entity Workload = {
iss: TrustedIssuer,
client_id?: String,
aud?: String,
name?: String,
rp_id?: String,
spiffe_id?: String,
access_token?: Access_token,
};
```

#### Attribute Mappings

| Attribute | Source |
| `iss` | Reference to the Trusted Issuer entity created at startup |
| `client_id` | the `"lient_id` claim from the JWT |
| `aud` | the `aud` claim from the JWT |
| `name` | the `name` claim from the JWT |
| `spiffe_id` | the `spiffe_id` claim from the JWT |
| `rp_id` | Derived from either the `aud` or the `client_id` claim from the JWT |

## User Entity

Cedarling creates a **User** entity for each request when the `CEDARLING_USER_AUTHZ` [bootstrap property](./cedarling-properties.md) is set to `enabled`.

- *Default Type Name:* `Jans::User`
- *Entity ID:* Determined by the `user_id` attribute from the [TEMS](./cedarling-policy-store.md#token-metadata-schema).
- If `user_id` is **not set**, Cedarling will fall back to the following claims (in order):

1. `sub` from the `userinfo_token`
2. `sub` from the `id_token`

### Default User Schema

```cedarschema
entity User in [Role] = {
sub?: String,
email?: email_address,
phone_number?: String,
role?: Set<String>,
username?: String,
id_token?: Id_token,
userinfo_token?: Userinfo_token,
};
```

#### **Attribute Mappings**

User attributes are derived from the combined claims in the `id_token` and the `userinfo_token` if available.

**Standard Claims**

- `sub`
- `role`
- `email`
- `phone_number`
- `username`
- `birthdate`
- `country`

## Role Entity

Cedarling automatically attempts to create **Role** entities for each request.

- **Default Type Name:** `Jans::Role`
- **Entity ID:** Determined by the `role_mapping` attribute from the [TEMS](./cedarling-policy-store.md#token-metadata-schema).
- If `role_mapping` is **not set**, Cedarling will try to create Role entities based on the following claims (in order):

1. `role` from the `userinfo_token`
2. `role` from the `id_token`

### RBAC Support

Since Role entities are automatically assigned as parents of User entities, you can easily define RBAC policies like:

```cedarschema
permit (
principal == Jans::Role::"Admin",
action in [Jans::Action::"Compare",Jans::Action::"Execute"],
)
```

## JWT Entities

Cedarling creates **JWT entities** for each token defined in the [trusted issuers schema](./cedarling-properties.md#trusted-issuers-schema).


- *Type Name:* Determined by the `entity_type_name` attribute from the [TEMS](./cedarling-policy-store.md#token-metadata-schema).
- *Entity ID:* Determined by the `token_id` attribute from the [TEMS](./cedarling-policy-store.md#token-metadata-schema).

### Attribute Mappings

Each **claim** in the JWT is automatically added to the JWT entity's attributes.
47 changes: 27 additions & 20 deletions docs/cedarling/cedarling-policy-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,22 +156,25 @@ Here is a non-normative example of the `policies` field:
This record contains the information needed to validate tokens from this issuer:

```json
"identity_source": {
"some_unique_id" : {
"trusted_issuers": {
"trusted_issuer_id" : {
"name": "name_of_the_trusted_issuer",
"description": "description for the trusted issuer",
"openid_configuration_endpoint": "https://<trusted-issuer-hostname>/.well-known/openid-configuration",
"tokens_metadata": {
"access_tokens": {
"trusted": true,
"principal_identifier": "jti",
"token_id": "jti",
...
},
"id_tokens": { ... },
"userinfo_tokens": { ... },
"tx_tokens": { ... },
...
}
},
"another_issuer_id": {
...
}
...
}
Expand All @@ -180,7 +183,7 @@ This record contains the information needed to validate tokens from this issuer:
- **name** : (*String*) The name of the trusted issuer.
- **description** : (*String*) A brief description of the trusted issuer, providing context for administrators.
- **openid_configuration_endpoint** : (*String*) The HTTPS URL for the OpenID Connect configuration endpoint (usually found at `/.well-known/openid-configuration`).
- **identity_source** : (*Object*, *optional*) Metadata related to the tokens issued by this issuer.
- **trusted_issuer_id** : (*Object*, *optional*) Metadata related to a particular issuer. You can add as many trusted issuers you want. Furthermore, the name this object is what will be used as the entity ID of the [Trusted Issuer](./cedarling-entities.md#trusted-issuer) that Cedarling automatically creates at startup.
- **tokens_metadata** : (*Object*, *optional*) Tokens metadata in a map of *token name* -> *token metadata*. See [Token Metadata Schema](#token-metadata-schema).

### Token Metadata Schema
Expand All @@ -189,8 +192,12 @@ The Token Entity Metadata Schema defines how tokens are mapped, parsed, and tran

```json
{
"user_id": "<field name in token (e.g., 'email', 'sub', 'uid', etc.) or '' if not used>",
"role_mapping": "<field for role assignment (e.g., 'role', 'memberOf', etc.) or '' if not used>",
"trusted": true,
"token_id": "jti",
"workload_id": "aud | client_id",
"user_id": "sub | uid | email",
"role_mapping": "role | group | memberOf",
"required_claims": ["iss", "exp", "some_custom_claim", ...],
"claim_mapping": {
"mapping_target": {
"parser": "<type of parser ('regex' or 'json')>",
Expand Down Expand Up @@ -288,7 +295,7 @@ Here is a non-normative example of a `cedarling_store.json` file:
}
},
"schema": "schema_encoded_in_base64",
"identity_source": {
"trusted_issuers": {
"08c6c18a654f492adcf3fe069d729b4d9e6bf82605cb" : {
"name": "Google",
"description": "Consumer IDP",
Expand All @@ -312,7 +319,7 @@ Here is a non-normative example of a `cedarling_store.json` file:
"trusted": true,
"principal_identifier": "",
"role_mapping": "",
},
},
}
}
}
Expand All @@ -334,18 +341,18 @@ Here is example of a minimum supported `cedar-policy schema`:

```cedar-policy_schema
namespace Jans {
entity id_token = {"aud": String,"iss": String, "sub": String};
entity Role;
entity User in [Role] = {};
entity Access_token = {"aud": String,"iss": String, "jti": String, "client_id": String};
entity Workload = {};

entity Issue = {};
action "Update" appliesTo {
principal: [Workload, User, Role],
resource: [Issue],
context: {}
};
entity id_token = {"aud": String,"iss": String, "sub": String};
entity Role;
entity User in [Role] = {};
entity Access_token = {"aud": String,"iss": String, "jti": String, "client_id": String};
entity Workload = {};

entity Issue = {};
action "Update" appliesTo {
principal: [Workload, User, Role],
resource: [Issue],
context: {}
};
}
```

Expand Down
104 changes: 0 additions & 104 deletions docs/cedarling/cedarling-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ These Bootstrap Properties control default application level behavior.
* **`CEDARLING_JWT_SIG_VALIDATION`** : `enabled` | `disabled` -- Whether to check the signature of all JWT tokens. This requires an `iss` is present.
* **`CEDARLING_JWT_STATUS_VALIDATION`** : `enabled` | `disabled` -- Whether to check the status of the JWT. On startup, the Cedarling should fetch and retreive the latest Status List JWT from the `.well-known/openid-configuration` via the `status_list_endpoint` claim and cache it. See the [IETF Draft](https://datatracker.ietf.org/doc/draft-ietf-oauth-status-list/) for more info.
* **`CEDARLING_JWT_SIGNATURE_ALGORITHMS_SUPPORTED`** : Only tokens signed with these algorithms are acceptable to the Cedarling.
* **`CEDARLING_TOKEN_CONFIGS`** : JSON object containing token specific configs. See: [Token Configs](#token-configs).
* **`CEDARLING_ID_TOKEN_TRUST_MODE`** : `Strict` | `None`. Varying levels of validations based on the preference of the developer.
`Strict` mode requires (1) id_token `aud` matches the access_token `client_id`; (2) if a Userinfo token is present, the `sub` matches the id_token, and that the `aud` matches the access token client_id.

Expand All @@ -60,7 +59,6 @@ These Bootstrap Properties control default application level behavior.
## Required keys for startup

* **`CEDARLING_APPLICATION_NAME`
* **`CEDARLING_TOKEN_CONFIGS` - check if default implementation of Token Config is suitable for you.

To enable usage of principals at least one of the following keys must be provided:

Expand All @@ -84,91 +82,6 @@ The `CEDARLING_USER_WORKLOAD_BOOLEAN_OPERATION` property specifies what boolean
* **AND**: authz will be successful if `USER` **AND** `WORKLOAD` is valid.
* **OR**: authz will be successful if `USER` **OR** `WORKLOAD` is valid.

## Token Configs

The token configs property sets the entity type name of a token and it's validation settings. Below is an example of the `CEDARLING_TOKEN_CONFIGS`:

```js
CEDARLING_TOKEN_CONFIGS = {
"access_token": {
"entity_type_name": "Jans::Access_token",
"iss": "enabled",
"aud": "enabled",
"sub": "enabled",
"jti": "enabled",
"nbf": "enabled",
"iat": "enabled",
"exp": "enabled",
},
"id_token": {
"entity_type_name": "Jans::id_token",
"exp": "enabled",
},
"userinfo_token": {
"entity_type_name": "Jans::Userinfo_token",
"exp": "enabled",
},
"custom_token1": {
"entity_type_name": "Jans::SomeCustom_token",
"exp": "enabled",
},
"custom_token2": {
"entity_type_name": "Jans::AnotherCustom_token",
"exp": "enabled",
},
// more custom tokens can be added here
}
```

## Default implementation of Token Config

Here is rust code default implementation of Token Configs (`CEDARLING_TOKEN_CONFIGS`). This is used when no custom token config is provided.

```rust
impl Default for TokenConfigs {
fn default() -> Self {
Self(HashMap::from([
("access_token".to_string(), TokenConfig {
entity_type_name: "Jans::Access_token".to_string(),
claims: ClaimsValidationConfig {
iss: FeatureToggle::Enabled,
sub: FeatureToggle::Disabled,
aud: FeatureToggle::Disabled,
exp: FeatureToggle::Enabled,
nbf: FeatureToggle::Disabled,
iat: FeatureToggle::Disabled,
jti: FeatureToggle::Enabled,
},
}),
("id_token".to_string(), TokenConfig {
entity_type_name: "Jans::id_token".to_string(),
claims: ClaimsValidationConfig {
iss: FeatureToggle::Enabled,
sub: FeatureToggle::Enabled,
aud: FeatureToggle::Enabled,
exp: FeatureToggle::Enabled,
nbf: FeatureToggle::Disabled,
iat: FeatureToggle::Disabled,
jti: FeatureToggle::Disabled,
},
}),
("userinfo_token".to_string(), TokenConfig {
entity_type_name: "Jans::Userinfo_token".to_string(),
claims: ClaimsValidationConfig {
iss: FeatureToggle::Enabled,
sub: FeatureToggle::Enabled,
aud: FeatureToggle::Enabled,
exp: FeatureToggle::Enabled,
nbf: FeatureToggle::Disabled,
iat: FeatureToggle::Disabled,
jti: FeatureToggle::Disabled,
},
}),
]))
}
}
```

## ID Token Trust Mode

The level of validation for the ID Token JWT can be set to either `None` or `Strict`.
Expand Down Expand Up @@ -233,17 +146,6 @@ Below is an example of a bootstrap config in JSON format. Not all fields should
"CEDARLING_POLICY_STORE_URI": null,
"CEDARLING_POLICY_STORE_LOCAL": null,
"CEDARLING_POLICY_STORE_LOCAL_FN": "./example_files/policy-store.json",
"CEDARLING_TOKEN_CONFIGS": {
"access_token": {
"entity_type_name": "Jans::Access_token"
},
"id_token": {
"entity_type_name": "Jans::id_token"
},
"userinfo_token": {
"entity_type_name": "Jans::Userinfo_token"
}
},
"CEDARLING_POLICY_STORE_ID": "gICAgcHJpbmNpcGFsIGlz",
"CEDARLING_LOG_TYPE": "std_out",
"CEDARLING_LOG_LEVEL": "INFO",
Expand Down Expand Up @@ -304,11 +206,6 @@ CEDARLING_WORKLOAD_AUTHZ: enabled
CEDARLING_POLICY_STORE_URI: null
CEDARLING_POLICY_STORE_LOCAL: null
CEDARLING_POLICY_STORE_LOCAL_FN: ./example_files/policy-store.json
CEDARLING_TOKEN_CONFIGS:
access_token: { entity_type_name: "Jans::Access_token" }
id_token: { entity_type_name: "Jans::id_token" }
userinfo_token: { entity_type_name: "Jans::Userinfo_token" }

CEDARLING_POLICY_STORE_ID: gICAgcHJpbmNpcGFsIGlz
CEDARLING_LOG_TYPE: std_out
CEDARLING_LOG_LEVEL: INFO
Expand All @@ -322,7 +219,6 @@ CEDARLING_JWT_STATUS_VALIDATION: disabled
CEDARLING_JWT_SIGNATURE_ALGORITHMS_SUPPORTED:
- HS256
- RS256

CEDARLING_ID_TOKEN_TRUST_MODE: strict
CEDARLING_LOCK: disabled
CEDARLING_LOCK_SERVER_CONFIGURATION_URI: null
Expand Down
Loading