> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/solution-architecture/frame/architecture.md).

# The OpenIAM architecture

What OpenIAM is made of, what each component holds and serves, which components hold a system of record, and exactly what degrades versus what stops when one of them is unavailable.

## What this is, and when you need it

OpenIAM is not one process against one database. It is a set of application services that communicate over a message broker, sitting on a relational database, a cache, a search tier, a graph store and a secrets store. That is more moving parts than a single-process product, and any competent enterprise architecture review will ask what it buys and what it costs. This page is the answer: the real component list, what each component holds, what it serves, and — the part that decides the argument — what degrades and what stops when each one is unavailable.

You need this page when someone senior has to sign off on the platform, when your operations function is deciding what it is willing to run, and when you are working out what a backup has to cover. It is not a build guide; the Installation Guide owns standing the components up and keeping them healthy.

## The decision

You do not get to choose whether the components exist. You do get to choose who runs each one, and that is a real decision with a real cost profile.

| Decision                                | Options                                                                    | What it costs                                                                                  | What it buys                                                                                                                           |
| --------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Who operates the relational database    | Self-managed, or a cloud database service                                  | More per month, and less version choice                                                        | Backup, failover and patching become someone else's problem for the one component holding the system of record                         |
| Who operates the cache                  | Self-managed Redis, or a managed cache                                     | Some managed caches restrict the clustering mode available to you                              | One fewer stateful service, with no data at risk if it is lost                                                                         |
| Who operates the search tier            | There is no choice: self-managed OpenSearch, on every platform             | The component most sensitive to disk and heap tuning stays yours, and so does its backup       | Nothing. **No shipped module provisions a managed search service on any platform**, so this row is a constraint rather than a decision |
| Who operates the graph store            | Self-managed JanusGraph over Cassandra, or a managed graph service         | Available on AWS and, in a different form, on Google Cloud; there is **no Azure graph module** | Removes two stateful services — the graph and its Cassandra backing                                                                    |
| Whether to run the secrets store at all | HashiCorp Vault, or Vault disabled and secrets resolved from configuration | Disabling Vault moves secret handling to whatever protects the configuration directory         | One fewer component, at the cost of Vault's property-level secret indirection                                                          |

Everything else — the message broker, the application services, the ingress tier — you run, wherever you run OpenIAM.

## Why there is more than one process

Every service-to-service call in OpenIAM goes over RabbitMQ rather than over direct HTTP between services. Each functional domain has its own virtual host on the broker — identity management, synchronization, reconciliation, workflow, audit, authorization, business rules, Groovy execution and the connector fan-out among them, eighteen in all. Bulk synchronization and bulk reconciliation have their own virtual hosts, separate from the interactive ones, so that a large run cannot starve everyday work. A caller sends a typed request and waits for a reply; the receiving service dispatches on the operation name.

That choice is what produces the component count. What it buys is that a long-running operation — a synchronization over a hundred thousand records, a certification campaign launch, a bulk provisioning run — executes in a process that can be scaled, restarted and starved of resources without touching the process serving interactive sign-in, and that the reconciliation service falling over does not take the console with it. What it costs is set out under *The cost this shape genuinely carries*, below.

## The application services

These are OpenIAM's own processes. On an RPM installation each is a systemd unit; on Kubernetes each is its own workload. Not all of them are deployed in every installation — several are only needed when the corresponding capability is used.

| Service                                                                       | What it does                                                                                                                                                                                                                                     |
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ESB                                                                           | The core identity and access service: users, logins, roles, groups, organizations, resources, policies, authentication and the REST surface behind the consoles                                                                                  |
| auth-manager                                                                  | Maintains the entitlement graph and evaluates it — which users hold which entitlements, and the navigation menus derived from that                                                                                                               |
| idm                                                                           | The provisioning pipeline: builds the target-system operation and orchestrates the connector that performs it                                                                                                                                    |
| workflow                                                                      | The approval engine, built on Activiti                                                                                                                                                                                                           |
| groovy-manager                                                                | Stores, caches and executes the Groovy that customizes synchronization, provisioning, federation and rules                                                                                                                                       |
| synchronization                                                               | Pulls identity data in from authoritative sources — CSV, relational databases, LDAP and application sources                                                                                                                                      |
| reconciliation                                                                | Compares a managed system against OpenIAM and reports the drift                                                                                                                                                                                  |
| audit-log-manager                                                             | Persists the audit log, indexes it for search, and dispatches it to an external destination over HTTP or syslog                                                                                                                                  |
| batch-task-manager                                                            | Runs scheduled work                                                                                                                                                                                                                              |
| business-rule-manager                                                         | Evaluates business rules                                                                                                                                                                                                                         |
| certification-manager                                                         | Runs access certification campaigns                                                                                                                                                                                                              |
| email-manager                                                                 | Renders and sends templated mail                                                                                                                                                                                                                 |
| device-manager                                                                | Device registration and notification                                                                                                                                                                                                             |
| machine-learning                                                              | A separate Python service that scores access risk from behavioural data                                                                                                                                                                          |
| risk-manager                                                                  | Scores the risk carried by identities and entitlements, and recomputes when a broadly held entitlement changes                                                                                                                                   |
| pbac-manager                                                                  | Evaluates policy-based access control, against its own schema                                                                                                                                                                                    |
| sas-manager                                                                   | Integration with SafeNet authentication. It needs a vendor library installed separately                                                                                                                                                          |
| Webconsole, SelfService, SelfService extension, IdP, report viewer, static UI | The user-facing applications. The IdP application serves sign-in, federation and password flows; the rest are the administrative and end-user consoles                                                                                           |
| Access Gateway                                                                | Apache httpd carrying the OpenIAM module — reverse proxy, session enforcement and header injection in front of protected applications                                                                                                            |
| Connectors and source adapters                                                | Separate processes that talk to managed systems and to authoritative sources. They attach to the broker rather than to the services directly, which is why they can run on a different host, a different network or a different operating system |

## The infrastructure components

This is the list an evaluator will hand you. Stated precisely, with what each one actually holds:

| Component               | What it holds                                                                                                                                                                                                                                       | What it serves                                                                                                                                                                                               |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Relational database     | The system of record for identities, entitlements, policies, configuration, workflow state, batch schedules, certification campaigns and policy-based access data, across seven schemas. **Not the audit trail** — see the search tier below        | Every service. Four engine families ship: MySQL and MariaDB, PostgreSQL, SQL Server and Oracle                                                                                                               |
| RabbitMQ                | Nothing durable beyond messages in flight                                                                                                                                                                                                           | Every call between services, on a virtual host per functional domain                                                                                                                                         |
| Redis                   | Cached copies of configuration and entitlement data, and the distributed locks that keep several nodes from doing the same startup or refresh work at once                                                                                          | Cache reads across all services. It runs in single, sentinel or cluster mode, selected by `openiam.redis.mode`                                                                                               |
| OpenSearch              | Search indices over users, groups, roles, resources, organizations, managed systems, orphan accounts, SoD violations, provisioning requests and connector replies — all rebuildable — **plus the audit trail, which is held here and nowhere else** | Every search and list screen in the consoles, and the audit search. Note this is **OpenSearch, not Elasticsearch**                                                                                           |
| Graph store             | The entitlement graph — users, groups, roles, organizations and resources as vertices, memberships as edges                                                                                                                                         | The authorization service, which answers entitlement questions and builds navigation menus from it. Selected by `gremlin.provider`; the shipped values are `neptune`, `cosmosdb` and, by default, JanusGraph |
| Cassandra               | The graph's storage, and nothing else                                                                                                                                                                                                               | JanusGraph, when the graph runs self-managed. No OpenIAM service talks to Cassandra directly. On Google Cloud, Bigtable takes this role; on AWS with Neptune, neither is present                             |
| HashiCorp Vault         | Secrets referenced from property files — database and broker credentials, keystore passwords, connector credentials                                                                                                                                 | Property resolution, principally at service startup                                                                                                                                                          |
| Consul                  | Vault's storage backend, bound to the loopback interface on an RPM installation                                                                                                                                                                     | Vault, and only Vault. No OpenIAM service talks to Consul                                                                                                                                                    |
| Apache httpd, and nginx | No state                                                                                                                                                                                                                                            | Apache httpd is the Access Gateway; nginx is the ingress in front of the consoles on a container deployment                                                                                                  |

Two entries on that list are worth pausing on, because they are the two most often misread. **Cassandra is not a second database for OpenIAM data** — it exists only because JanusGraph needs a storage backend, and it disappears entirely if you take a managed graph service. **Consul is not a service mesh or a service registry for OpenIAM** — it is where Vault keeps its data, and if you disable Vault it has no job at all.

## What depends on what

The dependency direction is what matters here — read the arrows as "cannot work without".

```mermaid
flowchart TD
    UI[Consoles and IdP] --> ESB[ESB and the other services]
    GW[Access Gateway] --> ESB
    ESB --> MQ[RabbitMQ]
    AUTH[auth-manager] --> MQ
    IDM[idm] --> MQ
    WF[workflow] --> MQ
    CONN[Connectors and source adapters] --> MQ
    ESB --> DB[(Relational database)]
    ESB --> REDIS[(Redis)]
    ESB --> SEARCH[(OpenSearch)]
    AUTH --> GRAPH[(Graph store)]
    AUTH --> DB
    AUTH --> REDIS
    IDM --> DB
    WF --> DB
    GRAPH --> CASS[(Cassandra or Bigtable)]
    GRAPH --> SEARCH
    ESB --> VAULT[Vault, at startup]
    VAULT --> CONSUL[(Consul)]
```

Two things to take from it. First, **the graph store depends on the search tier as well as on Cassandra** when it runs self-managed — JanusGraph uses OpenSearch as its index backend. That is a real coupling and it surprises people. Second, **nothing depends on Consul except Vault**, and nothing depends on Vault after startup except a Groovy script that deliberately reads a secret at runtime.

## What stops, and what merely degrades

This is the question behind the component count, and it deserves a direct answer rather than reassurance.

| Component unavailable                                                                                                          | What stops                                                                                                                                                                                       | What keeps working                                                                                                        | What you observe                                                                                                |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Relational database                                                                                                            | Everything. This is the system of record and there is no degraded mode                                                                                                                           | Nothing meaningful                                                                                                        | Operations fail; services that are restarted do not complete startup                                            |
| RabbitMQ                                                                                                                       | Every operation that crosses a service boundary, which is very nearly all of them                                                                                                                | A page already rendered in a browser                                                                                      | Requests fail with an internal error and the text *Response is not received from RabbitMQ during reply timeout* |
| Redis                                                                                                                          | Cache reads and refreshes, and the distributed locks that guard startup work and index rebuilds                                                                                                  | Nothing, for long                                                                                                         | Repeated connection-failure warnings in the service logs, then failing operations                               |
| OpenSearch                                                                                                                     | Search and list screens across the consoles, user and object lookup that reads from the index, and audit search. Audit indexing and provisioning-request indexing stall                          | Sign-in, provisioning, workflow, connector traffic and every write to the database                                        | Console lists return nothing or error; audit events cannot be recorded, and there is no second place they land  |
| Graph store                                                                                                                    | Entitlement evaluation and the navigation menus built from it. The authorization service will not complete startup while the graph is unreachable, and shuts itself down if a full rebuild fails | The rest of the platform, including the identity data the graph is built from                                             | The authorization service logs a graph error and exits; entitlement answers stop                                |
| Cassandra or Bigtable                                                                                                          | The graph, and therefore everything in the row above                                                                                                                                             | Everything that does not need an entitlement answer                                                                       | Presents as a graph failure, not as a database failure                                                          |
| Vault                                                                                                                          | Service startup. A running service does not read Vault again unless a Groovy script asks it to                                                                                                   | Every service already running                                                                                             | A restarted service fails to start and logs that it cannot reach Vault                                          |
| Consul                                                                                                                         | Vault, and through it service startup                                                                                                                                                            | Every service already running                                                                                             | Presents as a Vault failure                                                                                     |
| Access Gateway                                                                                                                 | Access to applications proxied behind it, and the desktop and header-injection integrations that depend on it                                                                                    | Direct sign-in to OpenIAM's own consoles, federation to applications that use SAML or OIDC directly, and all provisioning | Protected application URLs fail; OpenIAM itself is reachable                                                    |
| A single application service — reconciliation, synchronization, certification, email, device, business rules, machine learning | Only that capability                                                                                                                                                                             | Everything else                                                                                                           | The operation owned by that service times out with the broker reply-timeout error; nothing else changes         |

### The three that are hard dependencies

Be honest about this in a design review; a reviewer who catches you softening it will discount everything else you said. **The relational database, RabbitMQ and Redis are hard dependencies whose loss stops the platform.** There is no degraded read-only mode, no local cache that carries the estate through an outage, and no queueing of work for later. Design all three for availability together — that is what the HA topologies in Part 7 are for, and it is why "can we run this on one node in production" resolves to no.

The rest fail more gracefully. Losing the search tier is disruptive but not fatal: identities keep flowing, provisioning keeps running, and writes keep reaching the system of record; what you lose is the ability to find things — and, for the duration of the outage, the audit trail, which has nowhere else to land. Losing the graph store stops entitlement answers but loses no data. Losing Vault costs you nothing until the next restart.

### Only three things hold state you cannot regenerate

This is the point that usually settles the "seven loosely integrated services" objection, and it is the most useful thing on this page:

* **The relational database is the system of record.** Almost everything the platform knows lives here.
* **Vault holds secrets**, which exist nowhere else in a form the platform can use.
* **The audit trail is the third, and it is the exception people miss.** Audit events are OpenSearch documents. The relational tables that used to hold them were dropped at 4.2.0.0 and nothing writes them to the database now, so the audit indices are themselves a system of record: they cannot be rebuilt from anywhere, and a database backup that covers every schema preserves not one audit event. Where retention is an obligation, the search tier needs its own snapshot or a continuous export — see *Audit export to a SIEM* in the Administration Guide.
* **Everything else in the search tier, plus Redis, the graph store and Cassandra, holds derived data only.** Those indices are populated from the relational database and can be rebuilt from it. The cache repopulates on the next sweep. The search indices are rebuilt from the Webconsole — see *Rebuild a search index* in the Administration Guide. The entitlement graph is rebuilt the same way, and the authorization service will rebuild it automatically if it finds the graph empty at startup — see *Rebuild the authorization graph*.
* **RabbitMQ holds work in flight.** Losing the broker's persisted messages loses queued operations, not data — the operations are re-runnable.

So the recovery story is not "restore several data stores consistently to the same point in time". It is "restore the relational database and the secrets store, protect the audit indices separately, and rebuild the rest" — a materially different proposition from the one an evaluator assumes on seeing the component list, and worth stating in exactly those terms. *What a backup and restore must cover* in the Administration Guide sets out the scope.

### The cost this shape genuinely carries

Two costs are real and should be conceded rather than argued.

**Diagnosis crosses process boundaries.** When an operation fails, the error surfaces in the caller and the cause sits in the service that owned the work. That is slower than diagnosing a single-process product, and it is why the Administration Guide has both *Which log answers which question* and *Diagnose a failed operation*. Budget for a team that knows which service owns which operation.

**The stateful component count is the operational load.** Four stateful components in the self-managed shape — the database, Redis, OpenSearch and Cassandra under the graph — is four things to patch, monitor and capacity-plan. The honest mitigation is not that they are easy, but that on AWS and Google Cloud three of the four can be handed to platform services.

## What we recommend

**Hand away every stateful component your platform has a shipped module for.** On AWS that is the database, the cache and the graph. On Google Cloud it is the database, the cache and the graph's storage backend. On Azure it is the database and the cache; plan there for a self-managed graph and its Cassandra cluster as well. **Plan for a self-managed search tier everywhere** — no platform hands that one away. Do not assume parity across clouds: the difference is the most common surprise in a cloud-hosted design, and it lands on the Azure architect.

**Do not disable Vault in production** without a documented reason and an equivalent control over the configuration directory.

**Treat the three hard dependencies as one availability decision, not three.** There is no benefit in a highly available database in front of a single-node broker.

**Do not put a maintenance-window requirement on the graph store.** It can be lost and rebuilt. Design for the database and the broker; accept a degraded interval on the graph and on the search indices that are derived. **Treat the search tier as the exception it is**, because the audit trail lives there and cannot be rebuilt from anything — give it a snapshot or an export, and do not put it in the disposable column alongside the cache.

The circumstance that changes this advice is a deployment with no cloud platform underneath it. There you run all of it, and the component count is the component count — in which case the argument to make is the one above: three things need a backup, the rest are rebuilt.

## What OpenIAM does not do here

* **There is no single-process or embedded deployment mode.** There is no shape of OpenIAM that runs without a message broker, a cache and a database. The smallest supported shape puts all of them on one machine; it does not remove them.
* **There is no Azure graph module.** On Azure the graph runs self-managed, and so does its storage: JanusGraph and a Cassandra cluster are both deployed by Helm as in-cluster workloads. **This is not a managed Cassandra service** — it is a distributed database you operate, and stating it loosely understates the Azure footprint by a whole stateful system. The authorization service does recognise a `cosmosdb` graph provider setting, but no Terraform module ships to provision it, so an Azure design should assume the self-managed path.
* **There is no managed search option on any platform.** A managed search module exists in the shipped material for AWS and is not connected to the deployment; every platform, including AWS, deploys OpenSearch as a workload you operate.
* **The platform does not queue work through an outage of the database, the broker or the cache.** Losing any of them fails the operation in front of the user; it does not defer it.
* **Losing the search tier is not invisible.** Some object lookups read from the index rather than the database, so an OpenSearch outage is felt in the consoles, not just in search boxes.
* **Consul provides nothing to OpenIAM directly.** If you are inventorying components for an operational review, it belongs in the Vault line, not as an independent capability.

## Related

* [Deployment shapes at a glance](/solution-architecture/frame/deployment-shapes.md) — how these components are laid out across machines.
* *Rebuild a search index* and *Rebuild the authorization graph* in the Administration Guide — the two recovery paths that make the derived components cheap to lose.
* *What a backup and restore must cover* and *Audit export to a SIEM* in the Administration Guide — the scope that follows from three things holding a system of record, and how the audit trail is protected.
* *Which log answers which question* in the Administration Guide — the map from a symptom to the service that owns it.

*Applies to OpenIAM 2026.8.1. Last reviewed 7 August 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/solution-architecture/frame/architecture.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
