Skip to content

Commit

Permalink
feat (jans-cedarling): Create Decision Log optimized for Centralized …
Browse files Browse the repository at this point in the history
…Log Storage (#10338)

* feat(jans-cedarling): add log policy description on authorize request

Signed-off-by: Oleh Bohzok <[email protected]>

* feat(jans-cedarling): add logging cedar-policy `entities` as json for forensic analysis

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): add example of log

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): fix clippy issues

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): update python types documentation

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling):remove commented code

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): update log message information to be more clear

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): add heading for log sample for better readability

Signed-off-by: Oleh Bohzok <[email protected]>

* feat(jans-cedarling): rename log `log_kind` to `log_type`

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): rename LogEntry.id field to request_id

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): update logger interface

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): added DecisionLogEntry

Signed-off-by: Oleh Bohzok <[email protected]>

* feat(jans-cedarling): add loading bootstrap properties
CEDARLING_DECISION_LOG_USER_CLAIMS
and CEDARLING_DECISION_LOG_WORKLOAD_CLAIMS

Signed-off-by: Oleh Bohzok <[email protected]>

* feat(jans-cedarling): add log tokens claims

Signed-off-by: Oleh Bohzok <[email protected]>

* test(jans-cedarling): fix test cases to compile

Signed-off-by: Oleh Bohzok <[email protected]>

* feat(jans-cedarling): add bootstrap config  CEDARLING_DECISION_LOG_DEFAULT_JWT_ID

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): update python documentation

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): update markdown doc via check plugin

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): add new bootstrap properties to documentation

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): cut long log message in documentation

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): add to documentation example of decision log.

Signed-off-by: Oleh Bohzok <[email protected]>

* chore(jans-cedarling): fix clippy issues

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): fix python documentation

Signed-off-by: Oleh Bohzok <[email protected]>

* docs(jans-cedarling): fix python documentation

Signed-off-by: Oleh Bohzok <[email protected]>

---------

Signed-off-by: Oleh Bohzok <[email protected]>
  • Loading branch information
olehbozhok authored Dec 6, 2024
1 parent efb7ab6 commit 019e5ae
Show file tree
Hide file tree
Showing 33 changed files with 970 additions and 298 deletions.
187 changes: 183 additions & 4 deletions docs/cedarling/cedarling-logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,196 @@ logs and can stream to a database or S3 bucket. The Cedarling decision logs prov
evidence of usage of the domain's externalized policies. The logs are also useful for forensic
analysis to show everything the attacker attempted, both allowed and denied.

## Startup Message
## Sample logs

The JSON in this document is formatted for readability but is not prettified in the actual implementation.

### Startup Message

```json
{
"id": "01937359-8968-766e-bc4a-82df4aa1f4bf",
"time": 1732807068,
"id": "01937015-462d-7727-b789-ed95f7faf7a4",
"time": 1732752262,
"log_kind": "System",
"pdp_id": "75f0dc93-0a90-4076-95fa-dc16d3f00375",
"msg": "configuration parsed successfully"
}
{
"id": "01937015-462f-7cb5-86bb-d06c56dc5ab3",
"time": 1732752262,
"log_kind": "System",
"pdp_id": "b862f21f-bcb1-4618-995d-ba7041e9bd16",
"pdp_id": "75f0dc93-0a90-4076-95fa-dc16d3f00375",
"msg": "Cedarling Authz initialized successfully",
"application_id": "TestApp",
"cedar_lang_version": "4.1.0",
"cedar_sdk_version": "4.2.2"
}
```

### Decision Log

Example of decision log.

```json
{
"request_id": "019394db-f52b-7b06-88b8-a288670a32c2",
"timestamp": "2024-12-05T05:27:43.403Z",
"log_type": "Decision",
"pdp_id": "9e189c4b-96ae-4818-8e7f-75a42186af15",
"policystore_id": "a1bf93115de86de760ee0bea1d529b521489e5a11747",
"policystore_version": "undefined",
"principal": "User & Workload",
"User": {
"username": "[email protected]"
},
"Workload": {
"org_id": "some_long_id"
},
"lock_client_id": null,
"action": "Jans::Action::\"Update\"",
"resource": "Jans::Issue::\"random_id\"",
"decision": "ALLOW",
"tokens": {
"id_token": {
"jti": "id_tkn_jti"
},
"Userinfo": {
"jti": "usrinfo_tkn_jti"
},
"access": {
"jti": "access_tkn_jti"
}
},
"decision_time_ms": 3
}
```

#### Field Definitions

* `request_id`: unique identifier for the decision request
* `timestamp`: Derived if possible from the system or context--may be empty in cases where WASM can't access the system clock, and the time wasn't sent in the context.
* `pdp_id`: unique identifier for the Cedarling
* `policystore_id`: What policystore this Cedarling instance is using
* `policystore_version`: What version of the policystore the Cedarling is using
* `principal`: `User` | `Workload`
* `User`: A list of claims, specified by the `CEDARLING_DECISION_LOG_USER_CLAIMS` property, that must be present in the Cedar User entity
* `Workload`: A list of claims, specified by the `CEDARLING_DECISION_LOG_WORKLOAD_CLAIMS` property, that must be present in the Cedar Workload entity
* `lock_client_id`: If this Cedarling has registered with a Lock Server, what is the client_id it received
* `action`: From the request
* `resource`: From the Request
* `decision`: `ALLOW` or `DENY`
* `tokens`: Dictionary with the token type and claims which should be included in the log
* `decision_time_ms`: how long the decision took

### Debug Log Sample

The result of the authorization is quite extensive because we log all `cedar-policy` entity information for forensic analysis. We cannot truncate the data, as it may contain critical information.

```json
{
"id": "01937015-4649-7aad-8df8-4976e4bd8565",
"time": 1732752262,
"log_kind": "Decision",
"pdp_id": "75f0dc93-0a90-4076-95fa-dc16d3f00375",
"msg": "Result of authorize.",
"application_id": "TestApp",
"action": "Jans::Action::\"Read\"",
"resource": "Jans::Application::\"some_id\"",
"context": {
"user_agent": "Linux",
"operating_system": "Linux",
"network_type": "Local",
"network": "127.0.0.1",
"geolocation": [
"America"
],
"fraud_indicators": [
"Allowed"
],
"device_health": [
"Healthy"
],
"current_time": 1732752262
},
"entities": [
{
"uid": {
"type": "Jans::User",
"id": "qzxn1Scrb9lWtGxVedMCky-Ql_ILspZaQA6fyuYktw0"
},
"attrs": {
"sub": "qzxn1Scrb9lWtGxVedMCky-Ql_ILspZaQA6fyuYktw0",
"role": [
"CasaAdmin"
],
"email": {
"domain": "jans.test",
"uid": "admin"
}
},
"parents": [
{
"type": "Jans::Role",
"id": "CasaAdmin"
}
]
},
{
"uid": {
"type": "Jans::id_token",
"id": "ijLZO1ooRyWrgIn7cIdNyA"
},
"attrs": {
"sub": "qzxn1Scrb9lWtGxVedMCky-Ql_ILspZaQA6fyuYktw0",
"acr": "simple_password_auth",
"exp": 1731956630,
"jti": "ijLZO1ooRyWrgIn7cIdNyA",
"amr": [],
"aud": "d7f71bea-c38d-4caf-a1ba-e43c74a11a62",
"iss": {
"__entity": {
"type": "Jans::TrustedIssuer",
"id": "https://account.gluu.org"
}
},
"iat": 1731953030
},
"parents": []
},

...

{
"uid": {
"type": "Jans::Action",
"id": "Tag"
},
"attrs": {},
"parents": []
}
],
"person_principal": "Jans::User::\"qzxn1Scrb9lWtGxVedMCky-Ql_ILspZaQA6fyuYktw0\"",
"person_diagnostics": {
"reason": [
{
"id": "840da5d85403f35ea76519ed1a18a33989f855bf1cf8",
"description": "simple policy example for principal user"
}
],
"errors": []
},
"person_decision": "ALLOW",
"workload_principal": "Jans::Workload::\"d7f71bea-c38d-4caf-a1ba-e43c74a11a62\"",
"workload_diagnostics": {
"reason": [
{
"id": "444da5d85403f35ea76519ed1a18a33989f855bf1cf8",
"description": "simple policy example for principal workload"
}
],
"errors": []
},
"workload_decision": "ALLOW",
"authorized": true
}
```
51 changes: 35 additions & 16 deletions docs/cedarling/cedarling-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ These Bootstrap Properties control default application level behavior.

* **`CEDARLING_LOG_STORAGE`** : `off`, `memory`, `std_out`
* **`CEDARLING_LOG_LEVEL`** : System Log Level [See here](./cedarling-logs.md). Default to `WARN`
* **`CEDARLING_LOG_STDOUT_TYPE`** : Either `System`, `Metric`, or `Decision`. Default to System.
* **`CEDARLING_LOG_STDOUT_TYPE`** : Either `System`, `Metric`, or `Decision`. Default to System.
* **`CEDARLING_DECISION_LOG_USER_CLAIMS`** : List of claims to map from user entity, such as ["sub", "email", "username", ...]
* **`CEDARLING_DECISION_LOG_WORKLOAD_CLAIMS`** : List of claims to map from user entity, such as ["client_id", "rp_id", ...]
* **`CEDARLING_DECISION_LOG_DEFAULT_JWT_ID`** : Default is `jti`, but perhaps some other claim is needed.
* **`CEDARLING_DECISION_LOG_DEFAULT_JWT_ID`** : Token claims that will be used for decision logging. Default is "jti", but perhaps some other claim is needed.
* **`CEDARLING_LOG_TTL`** : in case of `memory` store, TTL (time to live) of log entities in seconds.

**The following bootstrap properties are needed to configure JWT and cryptographic behavior:**
Expand All @@ -41,11 +41,11 @@ These Bootstrap Properties control default application level behavior.
* **`CEDARLING_LOCAL_POLICY_STORE`** : JSON object with policy store
* **`CEDARLING_POLICY_STORE_LOCAL_FN`** : Local file with JSON object with policy store
* **`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_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_AT_ISS_VALIDATION`** : When enabled, the `iss` claim must be present in access token and the scheme must be `https`.
* **`CEDARLING_AT_JTI_VALIDATION`** : When enabled, the `jti` claim must be present in access token.
* **`CEDARLING_AT_NBF_VALIDATION`** : When enabled, the `nbf` claim must be present in access token and the Cedarling should verify that the current date is after the `nbf`.
* **`CEDARLING_AT_NBF_VALIDATION`** : When enabled, the `nbf` claim must be present in access token and the Cedarling should verify that the current date is after the `nbf`.
* **`CEDARLING_AT_EXP_VALIDATION`** : When enabled, the `exp` claim must be present and not past the date specified.
* **`CEDARLING_IDT_ISS_VALIDATION`** : When enabled, the `iss` claim must be present in id_token and the scheme must be `https`.
* **`CEDARLING_IDT_SUB_VALIDATION`** : When enabled, the `sub` claim must be present in id_token.
Expand All @@ -56,12 +56,12 @@ These Bootstrap Properties control default application level behavior.
* **`CEDARLING_USERINFO_SUB_VALIDATION`** : When enabled, the `sub` claim must be present in Userinfo JWT.
* **`CEDARLING_USERINFO_AUD_VALIDATION`** : When enabled, the `aud` claim must be present in Userinfo JWT.
* **`CEDARLING_USERINFO_EXP_VALIDATION`** : When enabled, the `exp` claim must be present and not past the date specified.
* **`CEDARLING_ID_TOKEN_TRUST_MODE`** : `Strict` | `None`. Varying levels of validations based on the preference of the developer.
* **`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.

**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`** : 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_DYNAMIC_CONFIGURATION`** : Enabled | Disabled, controls whether Cedarling should listen for SSE config updates.
* **`CEDARLING_LOCK_SSA_JWT`** : SSA for DCR in a Lock Master deployment. The Cedarling will validate this SSA JWT prior to DCR.
Expand All @@ -76,8 +76,8 @@ The `CEDARLING_USER_WORKLOAD_BOOLEAN_OPERATION` property specifies what boolean

### Available Operations

- **AND**: authz will be successful if `USER` **AND** `WORKLOAD` is valid.
- **OR**: authz will be successful if `USER` **OR** `WORKLOAD` is valid.
* **AND**: authz will be successful if `USER` **AND** `WORKLOAD` is valid.
* **OR**: authz will be successful if `USER` **OR** `WORKLOAD` is valid.

## ID Token Trust Mode

Expand Down Expand Up @@ -105,17 +105,16 @@ A local JWKS can be used by setting the `CEDARLING_LOCAL_JWKS` bootstrap propert
}
```

- Where keys are `Trusted Issuer IDs` assigned to each key store
- and the values contains the JSON Web Keys as defined in [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517).
- The `trusted_issuers_id` is used to tag a JWKS with a unique identifier and enables using multiple key stores.

* Where keys are `Trusted Issuer IDs` assigned to each key store
* and the values contains the JSON Web Keys as defined in [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517).
* The `trusted_issuers_id` is used to tag a JWKS with a unique identifier and enables using multiple key stores.

## Loading the bootstrap config

There are multiple ways to load your bootstrap config:

- [From a JSON file](#loading-from-json)
- [From a YAML file](#loading-from-yaml)
* [From a JSON file](#loading-from-json)
* [From a YAML file](#loading-from-yaml)

You can load from both file types using the following code snippet:

Expand All @@ -136,6 +135,9 @@ Below is an example of a bootstrap config in JSON format.
"CEDARLING_POLICY_STORE_URI": "",
"CEDARLING_POLICY_STORE_ID": "840da5d85403f35ea76519ed1a18a33989f855bf1cf8",
"CEDARLING_LOG_TYPE": "memory",
"CEDARLING_DECISION_LOG_USER_CLAIMS": ["sub", "email", "username"],
"CEDARLING_DECISION_LOG_WORKLOAD_CLAIMS": ["client_id", "rp_id"],
"CEDARLING_DECISION_LOG_DEFAULT_JWT_ID": "jti",
"CEDARLING_LOG_TTL": 60,
"CEDARLING_USER_AUTHZ": "enabled",
"CEDARLING_WORKLOAD_AUTHZ": "enabled",
Expand Down Expand Up @@ -173,7 +175,24 @@ Below is an example of a bootstrap config in JSON format.
}
```

- Note that properties set to `"disabled"`, an empty string `""`, zero `0`, and `null` can be ommited since they are the defaults.
* Note that properties set to `"disabled"`, an empty string `""`, zero `0`, and `null` can be ommited since they are the defaults.

#### Local JWKS

A local JWKS can be used by setting the `CEDARLING_LOCAL_JWKS` bootstrap property to a path to a local JSON file. When providing a local Json Web Key Store (JWKS), the file must follow the following schema:

```json
{
"trusted_issuer_id": [ ... ]
"another_trusted_issuer_id": [ ... ]
}
```

* Where keys are `Trusted Issuer IDs` assigned to each key store
* and the values contains the JSON Web Keys as defined in [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517).
* The `trusted_issuers_id` is used to tag a JWKS with a unique identifier and enables using multiple key stores.

* Note that properties set to `"disabled"`, an empty string `""`, zero `0`, and `null` can be ommited since they are the defaults.

### Loading From YAML

Expand Down Expand Up @@ -219,4 +238,4 @@ CEDARLING_AUDIT_TELEMETRY_INTERVAL: 0
CEDARLING_LISTEN_SSE: 'disabled'
```
- Note that properties set to `'disabled'`, an empty string `''`, zero `0`, and `null` can be ommited since they are the defaults.
* Note that properties set to `'disabled'`, an empty string `''`, zero `0`, and `null` can be ommited since they are the defaults.
Loading

0 comments on commit 019e5ae

Please sign in to comment.