Scoping applied where the rows are selected,not where they are rendered
Multi-tenancy is usually a review problem: every new query is one missed filter away from a leak, and the defence is that somebody would have caught it. DjiniousData narrows the boundary in one place per record family, enforces it in the handlers every route shares, and records what happened whether or not anyone is watching.
Five places the boundary is decided, and one list that says what it applies to
One list of what is scoped
WORKSPACED_TABLESThe record families that belong to a customer — knowledge objects, resolved entities, documents, dashboards, alert rules, signals, cases, reports — are enumerated in a single module. Adding a table that should be scoped is a one-line change there rather than an audit of every handler that might touch it.
The narrowing parameter can only narrow
?organization=A caller may ask to see less. Naming an organization other than their own does not widen the result: a tenant user is bound server-side to their own organization regardless of what they pass, and the parameter is resolved against that binding rather than trusted.
Two admin tiers, no second role
isGlobalAdmin · isOrgAdminAn admin with no organization is a cross-tenant super-user; an admin with one is scoped to it. The distinction falls out of the data rather than out of a role value somebody has to remember to set. An organization admin cannot mint a global admin, move a user between organizations, or edit the shared base ontology.
The ontology has an org-owned layer
entity_type_overlayA customer extends a shared type with its own fields, labels and workflow states through an overlay keyed by (type, organization). The base type is unchanged for everyone else, and the customer's administrator edits their layer without reaching the one underneath it.
Agents are principals, not exceptions
MCP dispatchThe MCP server threads the API key's principal into the same handlers the REST routes use. There is no agent-shaped path around the checks, and a token's reach is bounded by the role of the user who minted it.
An append-only audit log, written on the way past
Every mutation is recorded as it happens — who, what action, which record, and from where — by the middleware every route passes through, rather than reconstructed afterwards from logs. Append-only means it grows, so retention is a scheduled sweep rather than optional housekeeping.
- Audit events written on the mutation path, not derived from application logs afterwards
- Entity, ontology, connector, token and alert-rule changes all land in the same log
- A retention job sweeps expired events and dead sessions on a schedule
- Live change streams fan out over a WebSocket hub, so what a colleague just changed appears without a refresh


Organizations, and the workspaces inside them
A workspace is the unit a person joins and a record belongs to; an organization is the boundary. A customer's own administrator manages their workspaces and members without seeing anything above them.


Two things worth knowing before you deploy it
Neither of these is a defect, and both are the kind of thing a security review finds on its own. Stating them here is cheaper than being asked.
- Records and time series live in two stores. The ingest writes both in one pass, so the window is small, but a metrics query can be momentarily behind the records it was derived from.
- Connector-driven ingestion runs outside a request context and does not stamp organization on the objects it writes; a deployment that ingests per-customer scopes them explicitly. The fixture behind this site's screenshots does exactly that, and says so.
One account across the platform, one hash in the database
- Credential
- Argon2id, verified against a shared identity database so a single account works across every Djinious application rather than one per app.
- Session
- A JWT signed with HMAC-SHA256. The password hash never leaves the identity store, and a login provisions the local profile on first use.
- API tokens
- Separate principals with their own scopes and expiry, bounded by the owner's role. Only the SHA-256 hash of the secret is stored, and the secret is shown exactly once.
- Roles
- admin, user, viewer — with the admin tier split by whether the account carries an organization. Server-side checks live next to the handlers; the UI mirrors them, and is never the enforcement.
- Vision streams
- Camera sources are refused unless their prefix is on the operator's allow-list, and public URLs go through the same guard as webhooks. A private-network feed is not reachable by asking for it.
Bring your security review
The parts of this that matter are checkable: the scoping helpers, the role checks, the audit path, the token model. A technical demo can go straight to them.