JDLib¶
A multi-tenant security foundation for applications that put PostgreSQL and Neo4j behind one enforced surface: authentication, tenant resolution, authorization, audit, reliability and observability, each with the tests that hold it in place.
This site is the reference for the library as it is implemented today. It is built from the
repository's own documents - the design authorities are linked, not copied - and it is validated in
the same gate as the code: mkdocs build --strict fails the build on a broken link, a missing page
or a stale inventory, and tests/unit/test_docs_portal.py checks the navigation and every diagram.
An internal library
JDLib is not a hosted service and this site claims no public URL. Read it as the engineering reference for a library you deploy inside your own application.
Start where you are¶
| If you are… | Read | What you get |
|---|---|---|
| new to JDLib | Introduction · Quickstart | the problem it solves, how to install it, and the first application that is correct rather than merely running |
| an application developer | Features · Examples | one page per feature: when to use it, when not to, and the seam that does the work |
| an architect | Architecture · Design documents | the boundaries, the components, and what belongs inside the library rather than beside it |
| a security engineer | Security · Threat model | the controls, the failures they answer, and the residual risk that stays yours |
| an operations engineer | Operations · Production readiness | readiness, degradation, and what a deployment has to do that a library cannot |
The whole surface at a glance¶
flowchart TB
Client["Client / agent"]
Gateway["Kong or Tyk<br/>(the deployment's gateway)"]
App["FastAPI application"]
subgraph JDLib["JDLib"]
direction TB
MW["Middleware: request ids,<br/>error envelope"]
AuthN["Authentication<br/>API key · OIDC"]
Ctx["SecurityContext"]
Tenant["Tenant resolution<br/>and TenantContext"]
PEP["Authorization PEP"]
Priv["Privilege context<br/>(operator and delegation)"]
Data["Tenant-bound data access<br/>repository · query compiler"]
Graph["Graph plane<br/>tenant-bound client"]
MCP["MCP surface<br/>tools and resources"]
Audit["Audit and security events"]
Rel["Reliability<br/>breaker · budget · gate · drain"]
Obs["Observability<br/>spans and correlation ids"]
end
Cerbos["Cerbos PDP"]
PG[("PostgreSQL<br/>row-level security")]
Neo[("Neo4j")]
OTel["OpenTelemetry collector"]
Secrets["Credential providers"]
Client --> Gateway
Gateway --> App
App --> MW
MW --> AuthN
AuthN --> Ctx
Ctx --> Tenant
Tenant --> PEP
PEP -->|"decision query"| Cerbos
PEP --> Priv
PEP --> Data
Priv --> Data
Data --> PG
Graph --> Neo
Data --> Graph
MCP --> AuthN
MCP --> Data
Secrets -.->|"resolved per request"| Data
Audit -.->|"one vocabulary"| PEP
Rel -.->|"wraps every dependency call"| PEP
Obs -.->|"spans, allow-listed"| Data
Obs --> OTel
Every box in that diagram is a page in this site, and every arrow is a test somewhere in the repository. The ones that matter most:
- the tenant comes from the credential, never from a request field - the resolver chain decides it, and a header claiming otherwise is ignored (Tenancy);
- authorization runs before the handler, and a degraded policy engine refuses rather than allowing (Authorization);
- the database enforces the same rule as the repository, so a forgotten filter is a refused read rather than a disclosure (Row-level security);
- one error envelope answers every failure, and a 5xx never echoes its own text (Error responses).
The library in one paragraph¶
A request arrives with a credential. JDLib verifies it, resolves the tenant it belongs to, builds a
SecurityContext that the rest of the request reads, and asks a policy engine whether this
principal may take this action on this target. If the answer is yes, the operation runs inside a
tenant-bound session whose statements the database itself constrains; if it is no, the operation
never runs and the refusal is recorded. Everything that happened on the way - the decision, the
privileged read, the export - is written to one audit vocabulary, and the spans that carry the
request's ids never carry its values.
Where the documentation lives¶
| Section | What it is |
|---|---|
| Getting started | installation, configuration, the first application |
| Concepts | the design authorities: what each mechanism is for |
| Architecture | the long-form reference and the request/security flows |
| Features | one guide per feature, in the directive's template |
| Capabilities | one page per capability, machine-checked against the tree |
| Examples | the minimal and enterprise applications, and what running them found |
| Security | the hardening programme, the threat model and the compliance surface |
| Operations | readiness, degradation, and the operator's own job |
| Development | how this documentation is organised and validated |