EVIDENT

Architecture

What runs, where it runs, and what it can reach

Three people have to approve this and they ask different questions. A CTO asks what it costs to run. A CISO asks what it can reach. A DPO asks what it holds. This page answers those three.

The short version: a small set of containers and one volume. It runs on your own hardware, it needs no route to the internet, it reads the structure of your systems rather than their contents, and every access is scoped to a tenant and a role before it reaches anything.

Containers and a volume

EVIDENT is an application container, a web container and an identity provider, with a single named volume holding the internal database and the encrypted credentials. There is no external database to provision, no message broker, no object store and no managed service in the middle.

It runs on a laptop, on one virtual machine, or on your orchestrator. Bringing it up is one command and it is the same command in every environment, which is the property that matters when somebody has to reproduce an incident on a machine that is not the one it happened on.

Deployed on your own hardware, nothing leaves it. The licence is a signed code verified offline against a public key, so an installation on a network with no route out works exactly like one that has it.

Structure, not rows

The primary analysis reads schemas, constraints, foreign keys, types and comments, and the source code that maps onto them. By default it does not read the records in your tables, and that default is a property of how it is built rather than a setting somebody remembered to leave alone. Profiling and sampling are the two modes that do read data, and the paragraph below is what they cost.

Profiling and sampling exist for the cases that need them. Both are off, both are opted into per project, and both say in the report that they were used. The default mode is the narrowest one.

Connections are made with read-only, least-privilege credentials, and where a driver can enforce read-only it is enforced rather than trusted. Credentials are encrypted at rest, bound to the connection they belong to, and never written to a log.

The code is read, not taken

EVIDENT does not keep a copy of your source. It reads it to answer three questions it cannot answer from a schema: which code entity corresponds to which column, what is actually done with that data, and what ends up written to a log. What it keeps is the conclusion and the reference — the file, the symbol, the line — not the file.

Where it is read depends on where the platform runs, and the two answers are different. Self-hosted, the code is read inside your own infrastructure and does not leave it; there is nowhere for it to go. Hosted by us, the repository has to reach the machine the analysis runs on, and what survives that analysis is the same thing either way — the conclusion and the reference, not the file. A page that promised you the first sentence without saying which deployment it meant would be promising something it cannot keep, so this one says it twice.

On the hosted deployment the copy itself is removed when the analysis ends, however it ends, and it is never in a backup. That is a claim about a crash as much as about a success, so it is built as one: the copy holds a lease, the lease is renewed while the analysis reads it, and anything left behind by a killed worker or a restart is reclaimed — but only once the run that took it has actually stopped, never merely because the directory got old. A cleanup that fails leaves the lease open, so it is retried and it is visible rather than assumed. Nine paths, including the two that matter, are covered by tests.

And a judgement without evidence is refused. Every material claim can be asked why and where, and the answer distinguishes what was inferred from what was observed, what was corroborated by a second source from what rests on one, what a person confirmed from what the platform decided, and what somebody stated about their own organisation from what could not be corroborated at all.

The same applies across time. A claim carries what changed between one assessment and the next, so as your systems move you can tell what was genuinely fixed from what still stands because nothing about it changed — and neither of those is a guess anybody has to take on trust.

Who reaches what: tenant first, then role

Every project belongs to a tenant, and every request is answered inside one. That holds on a single-tenant on-premise installation too: it is the same code path, so the isolation you rely on in a hosted deployment is the isolation you have tested on your own.

Inside a tenant, access is role-based and checked at every level — the project, the action, the record. An identity confined to one project is refused everything about another before its permissions are consulted, because an identity that may not touch a project may not touch it however well permitted it is.

Who may see which project is yours to define. The platform enforces the answer; it does not decide it.

Identity through Keycloak

Authentication and the role model live in Keycloak, the open-source identity and access management server maintained under the CNCF. It runs as one of the containers, and it is the same Keycloak your other systems may already be using — this is not a fork or a bundled copy with our patches in it.

What that component gives you, in the version this ships with: OpenID Connect and SAML 2.0, organizations for multi-tenant realms, fine-grained administrative permissions, passkeys and WebAuthn, step-up authentication, persistent user sessions that survive a restart, DPoP-bound tokens, token exchange, client policies, and federation against LDAP, Active Directory and social identity providers.

What Keycloak can do and what EVIDENT declares as a supported integration are two different lists, and the difference matters more than the overlap. OIDC is Available because it is what the product runs on: the deployed platform authenticates every request that way. SAML and SCIM are Planned — the identity provider underneath speaks SAML, EVIDENT has never validated an end-to-end SAML integration, and a checklist that quietly counted the first as the second is exactly the kind of claim this product exists to argue against.

Because identity is a component rather than something we wrote, your existing single sign-on, your password policy, your second factor and your joiner-mover-leaver process apply to EVIDENT without anybody writing an integration.

Agents and machines: JWT, scoped and short-lived

An AI agent connecting over MCP, or a system calling the API, authenticates with a JWT bearer token issued by the same identity provider as everybody else. There is no second, weaker way in.

An administrator defines what each of them may do, individually: which permissions, over which projects, for how long. Sessions are time-limited and refreshed rather than eternal, so a token that leaks stops working on its own.

An agent is marked as one everywhere it appears — in the audit trail, in the record of who changed what — and is never mistaken for a person.

Everything is logged, and nothing sensitive is

Every request, every action, every analysis, every review decision and every administrative change is recorded, correlated by a request identifier that follows the work across components.

The record follows OpenTelemetry, so it goes into the collector, the dashboards and the alerting you already run rather than into a private format that only this product can read. That is what makes it observable, auditable and monitorable by the team that already does those things.

Secrets and sensitive values are not written to it. A connection password supplied to the platform is encrypted and never appears in a log line, and the audit record describes what was touched rather than what was in it.

What your operations team gets

Runbooks for deploying, upgrading, backing up and restoring; health and readiness endpoints; forward-only database migrations that run on boot and say what they did; a documented environment for every setting, with the security-relevant ones defaulting to the closed position.

A team that has done this before should be able to stand it up and configure it in an afternoon. We would rather they did, and we help while they do.