Sidecar Overview#
The sidecar is a containerized Flask project that uses the cedarling_python binding and implements the AuthZen specification. This image can run alongside another service and uses cedarling to validate evaluation requests against a policy store.
Docker setup#
- Ensure that you have installed docker
- Create a file called
bootstrap.json. You may use this sample file. - Modify the bootstrap file to your specifications. In particular you need to provide a link to your policy store in
CEDARLING_POLICY_STORE_URI. The configuration keys are described in the Python binding configuration keys. - Pull the docker image:
docker pull ghcr.io/janssenproject/jans/cedarling-flask-sidecar:0.0.0-nightly -
Run the docker image, replacing
</absolute/path/to/bootstrap.json>with the absolute path to your bootstrap file:docker run -d \ -e APP_MODE='development' \ -e CEDARLING_BOOTSTRAP_CONFIG_FILE=/bootstrap.json \ -e SIDECAR_DEBUG_RESPONSE=False \ --mount type=bind,src=</absolute/path/to/bootstrap.json>,dst=/bootstrap.json \ -p 5000:5000\ ghcr.io/janssenproject/jans/cedarling-flask-sidecar:0.0.0-nightly-druns the sidecar in daemon mode in the background. Omit this if you want to run the sidecar in the foreground to monitor logs in real time.SIDECAR_DEBUG_RESPONSEwill cause the sidecar to return extra diagnostic information for each query if set toTrue. This may be useful to check which policies are being used to reach a decision.SIDECAR_TRACE_WORKLOAD_ID(optional) sets the TRACEworkload_idused when a request has noAudit-Workload-IDheader. See TRACE correlation.GUNICORN_GRACEFUL_TIMEOUT(optional, default8) is how many seconds Gunicorn waits on shutdown for in-flight requests and then the TRACE flush. It must cover the longest request plus the flush and stay below the platform stop grace period (Docker and Cloud Run 10 seconds, KubernetesterminationGracePeriodSeconds30 seconds by default).- Take note of the output of the command. This is the container ID of the sidecar.
- The sidecar runs in the background on port 5000. OpenAPI documentation is available at
http://0.0.0.0:5000/swagger-ui - To stop the sidecar, run
docker container stop <container ID>
Usage#
The sidecar has one endpoint: /cedarling/evaluation.
Example request to the evaluation endpoint:
Note
The request shown below is designed against the AuthZen specification and should not be used for a regular cedarling deployment.
{
"subject": {
"type": "JWT",
"id": "",
"properties": {
"tokens": [
{
"mapping": "Jans::Access_Token",
"payload": "eyJhbGciOiJIUzI1NiIs..."
},
{
"mapping": "Jans::Id_Token",
"payload": "eyJhbGciOiJFZERTQSIs..."
},
{
"mapping": "Acme::DolphinToken",
"payload": "ey1b6cfMef21084633a7..."
}
]
}
},
"resource": {
"type": "Application",
"id": "",
"properties": {
"cedar_entity_mapping": {
"entity_type": "Jans::Application",
"id": "some_id"
},
"app_id": "application_id",
"name": "Some Application",
"url": {
"host": "jans.test",
"path": "/protected-endpoint",
"protocol": "http"
}
}
},
"action": {
"name": "Jans::Action::\"Read\""
},
"context": {
"device_health": [
"Healthy"
],
"fraud_indicators": [
"Allowed"
],
"geolocation": [
"America"
],
"network": "127.0.0.1",
"network_type": "Local",
"operating_system": "Linux",
"user_agent": "Linux",
"current_time": 1
}
}
Cedarling requires OpenID tokens from one or more trusted issuers to perform authorization, as described Cedarling authorization reference. These values are sent in the subject field's properties. A more detailed example of creating an AuthZen request can be seen in the gateway example.
Upon creating the principal, action, resource, and context entities, cedarling will evaluate these entities against the policies defined in the policy store. Then it will return a true/false decision. If the decision is false, the sidecar will analyze cedarling diagnostics and provide additional information for the admin.
Example of true case:
{
"decision": true
}
Example of false case:
{
"context": {
"reason_admin": {
"authorize_reason": ["DENY"],
"authorize_error": []
}
},
"decision": false
}
In this example the evaluation was DENY, so the decision was false. Additional information is returned in the context field.
TRACE correlation#
Callers that take part in Lock TRACE can send the correlation fields as headers on /cedarling/evaluation. The sidecar passes them to Cedarling as the request's TRACE context:
| Header | TRACE field |
|---|---|
Audit-Trace-ID |
trace_execution_id |
Audit-Execution-Authority |
execution_authority |
Audit-Workload-ID |
workload_id (optional) |
Audit-Workload-Instance-ID |
workload_instance_id (optional) |
Audit-Trace-ID and Audit-Execution-Authority must be sent together, otherwise the request is rejected with 400. Each value is trimmed and is at most 255 characters. The component that owns the unit of work creates these values; the sidecar does not generate them. They do not take part in the Cedar evaluation. Without these headers no TRACE context is sent.
When Audit-Workload-ID is missing, workload_id is the first non-empty value of:
SIDECAR_TRACE_WORKLOAD_IDenvironment variableCEDARLING_APPLICATION_NAMEfrom the bootstrap configurationcedarling-sidecar
TRACE records are submitted to Lock Server only by a Cedarling build that includes record emission (#15485), with CEDARLING_TRACE enabled and Lock Server set up for TRACE, see TRACE properties. The sidecar already sends the TRACE context and flushes on shutdown.
Cedarling queues records and sends them in the background. When the container stops, the Gunicorn worker finishes in-flight requests and then calls Cedarling shut_down() from its worker_exit hook, which sends the queued records once. Both steps share GUNICORN_GRACEFUL_TIMEOUT: the Gunicorn master kills the worker when it expires, and records still queued are lost.
When present, trace_execution_id is returned in the response context. With such a build and TRACE enabled, trace_record_status from the Cedarling decision log is returned as well, for example emitted or not_emitted_queue_full:
{
"context": {
"request_id": "019a2b1c-...",
"trace_execution_id": "exec-1",
"trace_record_status": "emitted"
},
"decision": true
}