Cedarling Integration
Cedarling is Gluu's deployment of the Cedar policy language as an AuthZEN-compliant sidecar. Cedar is a policy language developed by AWS that's designed specifically for authorization, it's human-readable, fast to evaluate (sub-millisecond for typical policies), and formally verifiable (you can mathematically prove that a set of policies never grants access to a particular resource).
The EDK integrates with Cedarling via HTTP, sending AuthZEN evaluation requests and receiving permit/deny decisions. Cedarling runs as a sidecar container alongside your application, so policy evaluation happens over localhost with no external network dependency.
Why Cedar?
Most authorization systems use either code (imperative role checks scattered throughout your application) or a general-purpose language like Rego (powerful but with a learning curve). Cedar takes a different approach: it's a purpose-built language that reads like English and has formal semantics.
A Cedar policy that says "admins can do anything" looks like this:
permit (
principal in Role::"admin",
action,
resource
);
A policy that says "users can only read documents they own" looks like this:
permit (
principal,
action == Action::"read",
resource
) when {
resource.owner == principal
};
Cedar's formal verification means you can ask questions like "is there any scenario where a non-admin can delete a resource?" and get a definitive answer, not by testing, but by mathematical proof. This is valuable in regulated environments where you need to demonstrate that your access control is correct.
Architecture
Cedarling runs as a sidecar, a separate container in the same pod (Kubernetes) or on the same host (Docker Compose). The EDK sends HTTP requests to localhost, so there's no external network hop or TLS overhead for policy evaluation.
Policies are loaded from files mounted into the Cedarling container. When policies change, you update the mount (ConfigMap in Kubernetes, volume in Docker), the application doesn't need to restart.
Request Modes
The EDK's Cedarling client supports two request modes:
AUTHZEN mode forwards the authorization request in standard AuthZEN format. This is the default and works with any AuthZEN-compliant PDP. Use this for standalone Cedar deployments or when you don't need Janssen-specific features.
SIDECAR_TOKEN mode applies Janssen-specific token semantics. Subject and resource IDs can be SHA-256 hashed before sending to Cedarling, which aligns with how the Janssen identity platform handles token claims. Use this mode when integrating with a Janssen/Gluu identity platform where Cedarling expects hashed identifiers.
Configuration
sphereon:
authzen:
enabled: true
pdp:
type: cedarling
base-url: http://cedarling-sidecar:5000
evaluation-path: /cedarling/evaluation
health-path: /health
timeout-ms: 5000
health-check-timeout-ms: 2000
The CedarlingConfig data class captures all settings:
data class CedarlingConfig(
val baseUrl: String,
val evaluationPath: String = "/cedarling/evaluation",
val healthPath: String = "/health",
val discoveryPath: String = "/.well-known/authzen-configuration",
val entityNamespace: String? = null,
val forwardContextAttributes: Boolean = false,
val mode: CedarlingRequestMode = CedarlingRequestMode.SIDECAR_TOKEN,
val sidecarTokenHashIds: Boolean = true,
val evaluationTimeoutMs: Long = 5000,
val healthCheckTimeoutMs: Long = 2000
)
| Property | Default | Description |
|---|---|---|
baseUrl | - | Cedarling sidecar URL (typically http://localhost:5000) |
evaluationPath | /cedarling/evaluation | AuthZEN evaluation endpoint |
mode | SIDECAR_TOKEN | Request mapping mode (AUTHZEN or SIDECAR_TOKEN) |
sidecarTokenHashIds | true | SHA-256 hash subject/resource IDs in sidecar-token mode |
entityNamespace | null | Cedar namespace prefix for entity types |
forwardContextAttributes | false | Include dynamic context attributes in the request |
Cedar Policy Examples
Cedar policies consist of permit and forbid statements. When multiple policies apply, forbid always wins, this is a safe default that prevents accidental access grants.
Role-Based Access Control
// Admins can perform any action on any resource
permit (
principal in Role::"admin",
action,
resource
);
// Key managers can manage keys but not delete them
permit (
principal in Role::"key-manager",
action,
resource
) when {
action.domain == "kms" &&
action.operation != "delete"
};
Tenant Isolation
Every authorization request from the EDK includes tenant context. Cedar policies can enforce strict tenant boundaries:
// Only allow access within the same tenant
permit (
principal,
action,
resource
) when {
principal.tenant_id == resource.tenant_id
};
This single policy prevents all cross-tenant access, regardless of roles, resource types, or operation types.
Command-Based Authorization
Because the EDK normalizes command IDs into structured action attributes, Cedar policies can match on modules, services, and operations:
// Document editors can create, read, and update — but not delete
permit (
principal in Role::"document-editor",
action,
resource
) when {
action.domain == "document" &&
action.operation in ["create", "read", "update"]
};
// Only resource owners can delete
forbid (
principal,
action,
resource
) when {
action.operation == "delete" &&
resource.owner != principal
};
Time-Based Access
// Allow access only during business hours
permit (
principal,
action,
resource
) when {
context.timestamp >= context.business_hours_start &&
context.timestamp <= context.business_hours_end
};
Deployment
Docker Compose
services:
cedarling:
image: janssenproject/cedarling:latest
ports:
- "5000:5000"
volumes:
- ./policies:/policies
environment:
- CEDAR_POLICY_DIR=/policies
app:
build: .
environment:
- CEDARLING_URL=http://cedarling:5000
depends_on:
- cedarling
Kubernetes
Deploy Cedarling as a sidecar in the same pod. Policies are stored in a ConfigMap:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
env:
- name: CEDARLING_URL
value: http://localhost:5000
- name: cedarling
image: janssenproject/cedarling:latest
ports:
- containerPort: 5000
volumeMounts:
- name: policies
mountPath: /policies
volumes:
- name: policies
configMap:
name: cedar-policies
Updating policies is a ConfigMap update + pod restart (or Cedarling hot-reload if supported by your version).
Health Monitoring
The CedarlingPdp client exposes health checks that the resilience layer uses for circuit breaker decisions. You can also expose Cedarling health as a Spring Boot actuator endpoint:
@Component
class CedarlingHealthIndicator(
private val pdp: CedarlingPdp
) : HealthIndicator {
override fun health(): Health = runBlocking {
if (pdp.isHealthy()) Health.up().build()
else Health.down().withDetail("error", "Cedarling unavailable").build()
}
}
When Cedarling becomes unhealthy, the circuit breaker opens and the fallback policy takes effect (see Authorization Overview).