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

feat(jans-cedarling): update Trusted Issuers schema in the policy store #10141

Merged
merged 6 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 34 additions & 28 deletions docs/cedarling/cedarling-policy-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The Cedarling Policy Store uses a JSON file named `cedarling_store.json` to stor

1. **Cedar Schema**: The Cedar schema encoded in Base64.
2. **Cedar Policies**: The Cedar policies encoded in Base64.
3. **Identity Source**: Details about the trusted issuers (see [below](#identity-source-schema) for syntax).
3. **Trusted Issuers**: Details about the trusted issuers (see [below](#trusted-issuers-schema) for syntax).

**Note:** The `cedarling_store.json` file is only needed if the bootstrap properties: `CEDARLING_LOCK`; `CEDARLING_POLICY_STORE_URI`; and `CEDARLING_POLICY_STORE_ID` are not set to a local location. If you're fetching the policies remotely, you don't need a `cedarling_store.json` file.

Expand All @@ -31,7 +31,7 @@ The JSON Schema accepted by cedarling is defined as follows:
"description": "Once upon a time there was a Policy, that lived in a Store.",
"policies": { ... },
"schema": { ... },
"identity_source": { ... }
"trusted_issuers": { ... }
}
}
}
Expand All @@ -40,7 +40,7 @@ The JSON Schema accepted by cedarling is defined as follows:
- **cedar_version** : (*String*) The version of [Cedar policy](https://docs.cedarpolicy.com/). The protocols of this version will be followed when processing Cedar schema and policies.
- **policies** : (*Object*) Object containing one or more policy IDs as keys, with their corresponding objects as values. See: [policies schema](#cedar-policies-schema).
- **schema** : (*String* | *Object*) The Cedar Schema. See [schema](#schema) below.
- **identity_source** : (*Object of {unique_id => IdentitySource}(#trusted-issuer-schema)*) List of metadata for Identity Sources.
- **trusted_issuers** : (*Object of {unique_id => IdentitySource}(#trusted-issuer-schema)*) List of metadata for Identity Sources.

### `schema`
Either *String* or *Object*, where *Object* is preferred.
Expand Down Expand Up @@ -145,7 +145,7 @@ Here is a non-normative example of the `policies` field:
}
```

## Identity Source Schema
## Trusted Issuers Schema

This record contains the information needed to validate tokens from this issuer:

Expand All @@ -157,24 +157,12 @@ This record contains the information needed to validate tokens from this issuer:
"openid_configuration_endpoint": "https://<trusted-issuer-hostname>/.well-known/openid-configuration",
"access_tokens": {
"trusted": true,
"principal_identifier": "",
"role_mapping": "",
},
"id_tokens": {
"trusted": true,
"principal_identifier": "sub",
"role_mapping": "",
},
"userinfo_tokens": {
"trusted": true,
"principal_identifier": "",
"role_mapping": "role",
},
"tx_tokens": {
"trusted": true,
"principal_identifier": "",
"role_mapping": "",
"principal_identifier": "jti",
...
},
"id_tokens": { ... },
"userinfo_tokens": { ... },
"tx_tokens": { ... },
}
...
}
Expand All @@ -185,21 +173,39 @@ This record contains the information needed to validate tokens from this issuer:
- **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.

**Notes**:
- The `access_tokens`, `id_tokens`, `userinfo_tokens`, and `tx_tokens` fields will follow the [Token Metadata Schema](#token-metadata-schema).
- The `access_tokens` will contain a `trusted` and `principal_identifier` field in addition to the fields from the `Token Metadata Schema`.

### Token Metadata Schema

The Token Entity Metadata Schema defines how tokens are mapped, parsed, and transformed within Cedarling. It allows you to specify how to extract user IDs, roles, and other claims from a token using customizable parsers.


```json
{
"trusted": true|false
"principal_identifier": "some_user123",
"role_mapping": "role",
"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>",
"claim_mapping": {
"mapping_target": {
"parser": "<type of parser ('regex' or 'json')>",
"type": "<type identifier (e.g., 'Acme::Email')>",
"...": "Additional configurations specific to the parser"
},
},
}
```

- **trusted** : (Boolean) The type of token
- **principal_id** : (String) The claim used to create the Cedar entity associated with this token.
- **role_mapping** : (String, *optional*) The claim used to create a role for the token. The default value of `role_mapping` is `role`. The claim can be string or array of string.
- **role_mapping**: (String, *Optional*) Indicates which field in the token should be used for role-based access control. If not needed, set to an empty string (`""`).
- **claim_mapping:** Defines how to extract and transform specific claims from the token. Each claim can have its own parser (`regex` or `json`) and type (`Acme::Email`, `Acme::URI`, etc.).


**Note**: You can include a `role_mapping` in each token but only the first one that get parsed will be recognized by Cedarling. Cedarling parses the `role_mapping`s for each token in this order:

**Note**: Only one token should include the `role_mapping` field in the list of `token_metadata`.
1. `access_tokens`
2. `id_tokens`
3. `userinfo_tokens`
4. `tx_tokens`

## Example Policy store

Expand Down
46 changes: 24 additions & 22 deletions jans-cedarling/bindings/cedarling_python/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from cedarling_python import ResourceData, Request
import os

DEFAULT_POLICY_STORE_PATH = "example_files/policy-store.json"

# use log config to store logs in memory with a time-to-live of 120 seconds
# by default it is 60 seconds
log_config = MemoryLogConfig(log_ttl=100)
Expand All @@ -16,13 +18,16 @@
# use log config to print logs to stdout
log_config = StdOutLogConfig()

# Read policy store from file
# Read policy store from file
policy_store_location = os.getenv("CEDARLING_LOCAL_POLICY_STORE", None)
if policy_store_location is None:
print("Policy store location not provided")
exit(1)
print("Policy store location not provided, use 'CEDARLING_LOCAL_POLICY_STORE' enviroment variable")
print("used default policy store path", DEFAULT_POLICY_STORE_PATH)
print()
policy_store_location = DEFAULT_POLICY_STORE_PATH
with open(policy_store_location, "r") as f:
policy_raw_json = f.read()

# for now we support only json source
policy_source = PolicyStoreSource(json=policy_raw_json)

Expand Down Expand Up @@ -196,32 +201,29 @@
workload_result = authorize_result.workload()
print(f"Result of workload authorization: {workload_result.decision}")

if workload_result is not None:
# show diagnostic information
workload_diagnostic = workload_result.diagnostics
print("Policy ID(s) used:")
for diagnostic in workload_diagnostic.reason:
print(diagnostic)
# show diagnostic information
workload_diagnostic = workload_result.diagnostics
print("Policy ID(s) used:")
for diagnostic in workload_diagnostic.reason:
print(diagnostic)

print("Errors during authorization:")
for diagnostic in workload_diagnostic.errors:
print(diagnostic)
print("Errors during authorization:")
for diagnostic in workload_diagnostic.errors:
print(diagnostic)

print()

# watch on the decision for person
person_result = authorize_result.person()
print(f"Result of person authorization: {person_result.decision}")

if person_result is not None:
person_diagnostic = person_result.diagnostics
print("Policy ID(s) used:")
for diagnostic in person_diagnostic.reason:
print(diagnostic)

print("Errors during authorization:")
for diagnostic in person_diagnostic.errors:
print(diagnostic)
person_diagnostic = person_result.diagnostics
print("Policy ID(s) used:")
for diagnostic in person_diagnostic.reason:
print(diagnostic)

print("Errors during authorization:")
for diagnostic in person_diagnostic.errors:
print(diagnostic)


# watch on the decision for role if present
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
{
"cedar_version": "v4.0.0",
"cedar_policies": {
"840da5d85403f35ea76519ed1a18a33989f855bf1cf8": {
"description": "simple policy example for principal workload",
"creation_date": "2024-09-20T17:22:39.996050",
"policy_content": "cGVybWl0KAogICAgcHJpbmNpcGFsIGlzIEphbnM6Oldvcmtsb2FkLAogICAgYWN0aW9uIGluIFtKYW5zOjpBY3Rpb246OiJVcGRhdGUiXSwKICAgIHJlc291cmNlIGlzIEphbnM6Oklzc3VlCil3aGVuewogICAgcHJpbmNpcGFsLm9yZ19pZCA9PSByZXNvdXJjZS5vcmdfaWQKfTs="
},
"444da5d85403f35ea76519ed1a18a33989f855bf1cf8": {
"description": "simple policy example for principal user",
"creation_date": "2024-09-20T17:22:39.996050",
"policy_content": "cGVybWl0KAogICAgcHJpbmNpcGFsIGlzIEphbnM6OlVzZXIsCiAgICBhY3Rpb24gaW4gW0phbnM6OkFjdGlvbjo6IlVwZGF0ZSJdLAogICAgcmVzb3VyY2UgaXMgSmFuczo6SXNzdWUKKXdoZW57CiAgICBwcmluY2lwYWwuY291bnRyeSA9PSByZXNvdXJjZS5jb3VudHJ5Cn07"
"policy_stores": {
"gICAgcHJpbmNpcGFsIGlz": {
"name": "Jans",
"description": "",
"policies": {
"840da5d85403f35ea76519ed1a18a33989f855bf1cf8": {
"description": "simple policy example for principal workload",
"creation_date": "2024-09-20T17:22:39.996050",
"policy_content": "cGVybWl0KAogICAgcHJpbmNpcGFsIGlzIEphbnM6Oldvcmtsb2FkLAogICAgYWN0aW9uIGluIFtKYW5zOjpBY3Rpb246OiJVcGRhdGUiXSwKICAgIHJlc291cmNlIGlzIEphbnM6Oklzc3VlCil3aGVuewogICAgcHJpbmNpcGFsLm9yZ19pZCA9PSByZXNvdXJjZS5vcmdfaWQKfTs="
},
"444da5d85403f35ea76519ed1a18a33989f855bf1cf8": {
"description": "simple policy example for principal user",
"creation_date": "2024-09-20T17:22:39.996050",
"policy_content": "cGVybWl0KAogICAgcHJpbmNpcGFsIGlzIEphbnM6OlVzZXIsCiAgICBhY3Rpb24gaW4gW0phbnM6OkFjdGlvbjo6IlVwZGF0ZSJdLAogICAgcmVzb3VyY2UgaXMgSmFuczo6SXNzdWUKKXdoZW57CiAgICBwcmluY2lwYWwuY291bnRyeSA9PSByZXNvdXJjZS5jb3VudHJ5Cn07"
}
},
"schema": "eyJKYW5zIjp7ImNvbW1vblR5cGVzIjp7IlVybCI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJob3N0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwicGF0aCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInByb3RvY29sIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fSwiZW50aXR5VHlwZXMiOnsiVHJ1c3RlZElzc3VlciI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJpc3N1ZXJfZW50aXR5X2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJVcmwifX19fSwiV29ya2xvYWQiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiY2xpZW50X2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiaXNzIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJUcnVzdGVkSXNzdWVyIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJvcmdfaWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJVc2VyIjp7Im1lbWJlck9mVHlwZXMiOlsiUm9sZSJdLCJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJjb3VudHJ5Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiZW1haWwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJzdWIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJ1c2VybmFtZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fX0sIkFjY2Vzc190b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhdWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJpZF90b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhY3IiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJhbXIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJhdWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJzdWIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJJc3N1ZSI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJjb3VudHJ5Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwib3JnX2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fSwiUm9sZSI6e319LCJhY3Rpb25zIjp7IlVwZGF0ZSI6eyJhcHBsaWVzVG8iOnsicmVzb3VyY2VUeXBlcyI6WyJJc3N1ZSJdLCJwcmluY2lwYWxUeXBlcyI6WyJXb3JrbG9hZCIsIlVzZXIiLCJSb2xlIl19fX19fQ=="
}
},
"cedar_schema": "eyJKYW5zIjp7ImNvbW1vblR5cGVzIjp7IlVybCI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJob3N0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwicGF0aCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInByb3RvY29sIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fSwiZW50aXR5VHlwZXMiOnsiVHJ1c3RlZElzc3VlciI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJpc3N1ZXJfZW50aXR5X2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJVcmwifX19fSwiV29ya2xvYWQiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiY2xpZW50X2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiaXNzIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJUcnVzdGVkSXNzdWVyIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJvcmdfaWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJVc2VyIjp7Im1lbWJlck9mVHlwZXMiOlsiUm9sZSJdLCJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJjb3VudHJ5Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiZW1haWwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJzdWIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJ1c2VybmFtZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fX0sIkFjY2Vzc190b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhdWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJpZF90b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhY3IiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJhbXIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJhdWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJzdWIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJJc3N1ZSI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJjb3VudHJ5Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwib3JnX2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fSwiUm9sZSI6e319LCJhY3Rpb25zIjp7IlVwZGF0ZSI6eyJhcHBsaWVzVG8iOnsicmVzb3VyY2VUeXBlcyI6WyJJc3N1ZSJdLCJwcmluY2lwYWxUeXBlcyI6WyJXb3JrbG9hZCIsIlVzZXIiLCJSb2xlIl19fX19fQ=="
}
}
1 change: 1 addition & 0 deletions jans-cedarling/cedarling/src/authz/entities/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ pub fn create_role_entities(
TokenKind::Access => &tokens.access_token,
TokenKind::Id => &tokens.id_token,
TokenKind::Userinfo => &tokens.userinfo_token,
TokenKind::Transaction => unimplemented!(),
};

// get payload of role id in JWT token data
Expand Down
Loading