Allow. Deny. Explain.
Darwan is KaritKarma's centralised authorization service. One service decides who may do what, returns the rule that made the call, and hashes the decision into a SHA-256 audit chain anyone with audit scope can re-verify. RBAC plus deny-override ABAC, 58 endpoints, 4 SDKs. Live at darwan.net.
POST /v1/authorize
Authorization: Bearer <wenme-jwt>
{
"tenantId": "dk_acme",
"principalId": "usr_7f3a",
"action": "read",
"resourceType": "sales.order",
"resourceId": "ord_4201",
"subject": { "department": "sales" },
"resource": { "owner": "usr_7f3a" }
}
<-- 200 OK
{
"allowed": true,
"decision": "allow",
"policyVersion": "v3.2.1",
"ruleId": "R014",
"reason": "RBAC grant + ABAC owner match",
"decisionId": "dec_8c2f..."
}
// audit event hash-chained
// GET /v1/audit-events/verify -> chain OKFour steps. Deny by default. Explain every call.
Every request walks the same pipeline: bind, RBAC, ABAC, explain. No shortcuts, no bypass, no black-box deny.
Bind principal to tenant
Wenme issues the JWT, Darwan resolves principal-role assignments inside the tenant scope, then walks group-inherited roles. Expired time-bound assignments drop out before any rule fires.
RBAC grant required
The (action, resourceType) tuple is matched against the principal's effective role-permission set. No grant means deny. Attribute-free decisions are cached in Redis; the cache is bypassed when attribute bags, scoped roles, or a policy set are in play.
ABAC policy overlay
Policy sets are versioned. Deny rules evaluate first, then allow rules with JSON conditions on subject, resource, and request context. Deny always overrides allow.
Explain + audit chain
Every decision returns the outcome, reason, rule id, and policy version. The authorize:explain endpoint adds the matched rules and a decision id. The audit event is hashed into a per-tenant SHA-256 integrity chain that GET /v1/audit-events/verify re-checks end to end.
Where Darwan sits in the authorization landscape.
| Feature | Darwan | OPA | Casbin | Keycloak |
|---|---|---|---|---|
| Multi-tenant by design | Every resource scoped by tenantId, isolation at the schema | Single-policy bundle, multi-tenancy is bring-your-own | Single enforcer, tenant routing in app code | Realm per tenant, separate admin surfaces |
| RBAC plus ABAC overlay | RBAC grant required, then ABAC policy can deny | Pure ABAC, RBAC modelled on top | Model-string per pattern, no first-class layering | RBAC core, optional policy add-on |
| Explainable decisions | authorize:explain returns matched rules, reasons, decision id | Decision logs with input replay | Boolean only, no native trace | Token introspection, no per-decision trace |
| Signed audit chain | Per-tenant SHA-256 chain, verify endpoint + CSV export | External SIEM responsibility | Adapter-dependent | Standard event log, no integrity chain |
| Deployment model | Self-host or KaritKarma-managed in-region | Sidecar per service, you operate everything | Library, embedded in app process | Self-host, JVM operations |
Four first-party clients.
Darwan is the policy spine of the KaritKarma stack.
Wenme
Issues the OAuth 2.1 JWT Darwan validates against its userinfo endpoint
BitsPath
159 Darwan permissions across 17 categories, 63 of them pbx.*
BitsPath Voice
Pure-Rust voice engine calls Darwan on every authorized API action
Your runtime
Anything that can POST JSON: dk_ API keys or Wenme bearer tokens, four SDKs, OpenAPI document
.NET 10, Postgres, Redis.
Questions buyers actually ask.
- What is Darwan?
- Darwan is KaritKarma's centralised authorization service for regulated institutions. It answers a single question on every request: is this principal allowed to perform this action on this resource inside this tenant? Authentication is handled by Wenme (OAuth 2.1 with PKCE), and Darwan layers RBAC plus deny-override ABAC, explainable decisions, and a SHA-256 audit chain on top.
- How does Darwan compare to Open Policy Agent?
- OPA is a general policy engine deployed as a sidecar per service, with multi-tenancy and RBAC modelled in Rego by the application team. Darwan is opinionated for SaaS and regulated workloads: tenant isolation is first-class, RBAC and ABAC are layered with a deny-override rule, and a signed audit chain is built in. You operate one Darwan, not one OPA per service.
- Does Darwan support attribute-based policies?
- Yes. Policy sets are versioned, and each rule carries a JSON condition that runs against subject, resource, and request context. A typical use is restricting an invoice.read grant so a non-owner cannot read another department's invoice. Deny rules evaluate first, then allow rules. Deny always overrides allow.
- Where does Darwan fit relative to Wenme?
- Wenme answers who you are. Darwan answers what you may do. A request arrives with a Wenme-issued JWT, the calling service forwards the token (or trusted principal headers) to Darwan, and Darwan returns allow or deny with a reason. The two services are independent and can be deployed separately.
- What is the API contract for /v1/authorize?
- Authorize uses a split shape: action plus resourceType, not a flat permissionKey. For a permission string such as sales.order.read, the caller passes action=read and resourceType=sales.order. The body also carries tenantId, principalId, optional resourceId, and subject/resource/context attribute bags for ABAC evaluation. The response returns allowed, decision, policyVersion, ruleId, and reason.
- How does Darwan make its audit log tamper-evident?
- Every audit event is SHA-256 hash-chained per tenant: the previous event's hash is folded into the next, so any edit or deletion breaks the chain. A dedicated endpoint, GET /v1/audit-events/verify, re-computes the whole chain on demand, and audit events export as CSV or JSON for evidence packs. Retention is configurable with a background archival service.
One service, one decision, one signature.
A 45-minute session with the engineer who will be responsible for your deployment. We map your audit findings to specific platform controls.