> 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/deployment/network-design.md).

# Network zones and traffic flow

Where each component sits relative to your network boundaries and what may reach it from where — the one thing that may be published, the things that must never be, the broker's genuine judgement call

## What this is, and when you need it

This page settles **where each OpenIAM component sits relative to your network boundaries, and what may reach it from where**. It belongs jointly to the identity lead and whoever owns the firewall estate, and it has to be taken before the topology is built: two of its answers — what is published, and what the broker may talk to — are expensive to change afterwards.

What follows is the zone and flow model, not a port inventory; the exhaustive port and firewall table belongs to the Installation Guide. A port appears here only where the number itself changes a design.

## The decision

| Decision                                           | Options                                                  | What it costs                                                     | What it buys                                                                           |
| -------------------------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| What is published externally                       | The Access Gateway only, or more                         | Each additional endpoint is a control you design and defend       | The shipped design publishes one thing, and everything behind it assumes that          |
| Where the broker sits                              | Internal only, or reachable from named external networks | Mutual TLS, a certificate lifecycle, an allowlist                 | On-premise connectors reach a cloud-hosted platform with no inbound rule to any target |
| Where TLS terminates                               | The load balancer, the Access Gateway, or nowhere        | Certificate management moves with the termination point           | Defaults differ by distribution, so this is a decision either way                      |
| How the domain-controller segment reaches OpenIAM  | The published address, an internal one, or not at all    | A path from the estate's most sensitive segment into the platform | Windows password changes OpenIAM can validate and capture                              |
| Whether the platform may reach the public internet | Allowed, or blocked                                      | Blocking means switching off a shipped control deliberately       | An egress position stated rather than discovered at go-live                            |

## Direction of flow is the organizing idea

Almost every connection is outbound from the component that needs something, which removes most of the firewall conversation before it starts. Services dial the broker, the relational database, the cache, the search tier, the graph store and the secrets store. Connectors dial the broker. The Access Gateway dials the ESB to resolve each request, and dials each application it fronts. The consoles do not call the backend services directly at all — **with the single exception of the ESB, the backend services declare no ports at all**, and every call between a console and a service, or between two services, crosses the broker.

Two consequences follow. **The protected application never calls OpenIAM**: the gateway needs a path to the ESB and to each application it fronts, and those applications need none in return. And **nothing dials into a connector host**, which is what makes [connector placement](/solution-architecture/integration/connector-placement.md) a free choice.

```mermaid
flowchart LR
    B[Browser] --> LB[Load balancer]
    LB --> AG[Access Gateway]
    DC[Domain controllers] --> AG
    AG --> PX[Internal proxy]
    AG --> ESB[ESB]
    AG --> APP[Protected applications]
    PX --> UI[Consoles, identity provider, report viewer]
    UI --> MQ[Message broker]
    ESB --> MQ
    SVC[Other backend services] --> MQ
    CONN[Connector hosts] --> MQ
    ESB --> DATA[(Database, cache, search tier, graph store, secrets store)]
    SVC --> DATA
    CONN --> TGT[Managed systems]
    ESB --> INET[Public internet]
```

Every arrow reads "opens a connection to". Read it for what it does not contain: apart from browsers and domain controllers, nothing initiates a connection into the platform.

## Exactly one thing may be published

**The Access Gateway is the only component the shipped tooling gives an external address.** Everything a user reaches — the identity provider, self-service, the administrative console and the report viewer — arrives on the **same hostname and the same port**, differentiated by path.

That is worth reading twice. **There is no separate public endpoint for the identity provider.** The SAML and OpenID Connect endpoints live inside the identity provider application, behind the same gateway on the same address as everything else. A design that gives federation its own external hostname, or firewalls the identity provider differently from the consoles, describes a shape OpenIAM does not ship.

One default deserves naming: on AWS the shipped load balancer is **internet-facing unless you say otherwise**, so a deployment that does nothing gets a public endpoint. That belongs in a design document rather than in a penetration test.

## What must never be reachable

This is the load-bearing part of the page. Take it as a network-design requirement rather than a finding: the platform assumes the Access Gateway is the trust boundary, and the design must make that true.

**The ESB's port is protected by network placement alone.** It is the one backend service that listens on a port, and it is the platform's internal service interface: it assumes every caller has already been authenticated by the Access Gateway, because in the shipped design every caller has. Treat reachability of that port as equivalent to trust in the platform. This is the hardest "must never be exposed" in the architecture.

**The gateway passes its decisions to the backends in the request, and the backends rely on it having made them.** The gateway sanitises what a client sends before forwarding it, so what a backend reads is the gateway's own decision rather than the client's suggestion — a positive control, and one of the reasons the gateway is the trust boundary rather than merely the front door. The consequence for the design is direct: a request that reaches a backend without passing through the gateway has not been through the checks that backend assumes were already made.

So the requirement is not tidiness. The application zone must be reachable from the Access Gateway and nothing else, including workloads on the same network with no business there.

## The broker is the one genuine judgement call

Everything else here is a rule; the broker is a decision. It has a shipped, documented exposure setting, because exposing it is the supported way for on-premise connectors to reach a cloud-hosted platform. That is the opposite of the usual instinct and it is correct: one outbound connection per connector host is a far smaller crossing than inbound rules to every domain controller, database and application.

**Mutual TLS with peer verification is the control that makes it safe.** The shipped material supports running the broker with TLS and requiring a client certificate, and one shipped broker configuration requires the peer certificate and disables the plain listener entirely. The distributions differ here — the container chart adds a TLS listener alongside the plain one and leaves peer verification to a value you supply — so **require the client certificate and verify the peer explicitly**, in your own configuration, rather than relying on a default to do it. **And expose it to named networks, not the internet.** Note too that broker payload encryption uses a single symmetric key shared across the estate, and every connector host holds it — so **set it deliberately at build time**, because rotating it afterwards is a whole-estate operation.

[Connector placement](/solution-architecture/integration/connector-placement.md) covers the decision on top of this one, including the site-to-site link the shipped modules do not build.

## The zones

| Zone                   | What sits in it                                                                                                     | What may open a connection into it                                      |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| **Edge**               | The load balancer and the Access Gateway                                                                            | Browsers; domain controllers, if the password filter is routed here     |
| **Application**        | The internal proxy, the consoles, the identity provider, the report viewer, the ESB and every other backend service | The Access Gateway, and nothing else                                    |
| **Data and messaging** | The database, the broker, the cache, the search tier, the graph store and its backing store, the secrets store      | The application zone — plus, for the broker alone, every connector zone |
| **Connector**          | Connector and source-adapter processes, one zone per segment holding targets                                        | Nothing at all                                                          |
| **Target**             | The managed systems, including the domain controllers                                                               | The connector zone that serves them                                     |

Most estates collapse the middle two onto shared subnets. The value in naming them separately is that their reachability rules differ — and that the target zone reaches back into the edge in exactly one case, below.

## Load-balancer decisions, and the missing ingress

**No sticky sessions are required.** HTTP session state lives in the cache rather than the JVM, the gateway holds no per-user state, no session affinity is set anywhere in the shipped material, and the gateway runs multiple replicas assuming any of them can serve any request. Say this plainly in a design review; architects routinely assume the opposite and specify affinity they do not need.

**The corollary is that the cache is not just a cache.** Every node must reach it, and losing it logs everyone out. A design that treats it as disposable and gives it a single instance has made an availability decision without noticing — see [Availability and recovery](/solution-architecture/deployment/availability-and-recovery.md).

**The trap: the Access Gateway has no health endpoint a load balancer can use.** Its status page is restricted to local requests, so an external probe receives a 403 and the load balancer concludes the node is down; the shipped container probe works only because it runs against the loopback address. Decide the alternative at design time — a TCP check, or a path that survives the gateway's federation handling. The consoles do expose usable health endpoints.

**And there is no Kubernetes `Ingress` object anywhere in the shipped application charts.** Path routing happens inside the deployment, in the internal proxy's configuration; the entry point is a load-balancer service in front of the gateway. Any design assuming an ingress controller, ingress annotations, path rules or cert-manager wiring is describing something OpenIAM does not ship — check it early, or a platform team will apply its ingress standard to nothing.

## Where TLS terminates

Termination is a decision, and the shipped default differs by distribution — so a design that states no position inherits a different answer depending on how it is deployed.

| Shape          | Shipped default                                                                                                   | What it implies                                                                                            |
| -------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Packaged Linux | Plain HTTP on port 80; the stock TLS virtual host is moved aside at installation and a TLS example ships disabled | Both 80 and 443 are opened in the firewall with nothing listening on 443. Enabling TLS is a deliberate act |
| Containers     | TLS terminated at the Access Gateway                                                                              | The gateway holds the certificate and its renewal                                                          |
| AWS            | Termination moves to the load balancer when a certificate is supplied                                             | Load balancer to gateway is cleartext inside the cloud network                                             |

**Behind the gateway everything is cleartext by default** — gateway to ESB, gateway to internal proxy, internal proxy to consoles. Defensible when the application zone is a controlled network; not when it is shared with workloads you do not administer.

Internal TLS to the data tier is not uniform. **The secrets store requires mutual TLS and it is on by default**, making certificate issuance a build-order dependency rather than a hardening task: certificates must exist before any service starts. **The cache is off by default**, and it carries session state. **Database connections are not TLS-enabled by the shipped configuration**, so enabling transport security to the database is a hardening step the design must include. **The search tier is TLS-enabled by default in the container distribution**; in a packaged deployment, confirm the scheme in use and enable it if it is not already on.

## The reversal nobody expects: domain controllers dial in

Everyone assumes an identity platform pushes to Active Directory. The password filter reverses it.

The filter runs **on every domain controller** and calls OpenIAM's web tier **outbound over HTTPS**, authenticating with a service account credential held encrypted on the machine rather than with a certificate. It makes two calls: an asynchronous notification that a password changed, backed by a retry service, and — the important one — **a synchronous, blocking policy-validation call at the moment of the password change**.

The design consequence is availability, not connectivity. **If a domain controller cannot reach OpenIAM, the filter's configured behaviour on an unknown validation response decides whether the user's password change succeeds.** Reachability from the domain-controller segment is therefore an availability decision about Windows password changes, in the segment an organization is least willing to open, and it should be monitored as a dependency on the platform's uptime rather than settled by a firewall ticket. Which address the filter uses — published or internal — is a configuration choice rather than a fixed default; take the internal one where the controllers can reach it. Whether the design needs the filter at all is Part 3, *Password strategy*.

## Egress, and the rules nobody writes for you

**By default the platform makes an outbound call to a public compromised-password service on the password-change path.** It is a shipped control, enabled on the default policy, and worth having in most estates. In an air-gapped or egress-restricted design it becomes a decision to take deliberately: either the egress path exists and is documented, or the check is switched off. Leaving it enabled with no path out leaves a password-change path depending on a call that cannot complete. It is the platform's only routine call to the public internet, so a closed egress policy has one exception to argue about.

In the other direction, the packaged Linux installation opens only the two web ports in the host firewall. **Nothing in the shipped scripts opens the broker, the cache, the search tier, the graph store or the secrets store between nodes.** For a multi-node packaged deployment those rules are entirely the customer's to write, and what must be open is the dependency list in Part 1, *The OpenIAM architecture*. Budget for it as design work; take the port inventory from the Installation Guide.

## What we recommend

**Publish the Access Gateway and nothing else**, as an architectural invariant. Challenge any requirement implying a second published endpoint, particularly a separate federation hostname. On AWS, set the load balancer scheme explicitly: whether internet-facing suits your estate is a decision; inheriting it is not.

**Put the ESB and the consoles where only the Access Gateway can reach them**, and say why in those terms: the backends act on decisions the gateway has already made for them, and the ESB is an internal interface whose only protection is where it sits.

**Expose the broker only when on-premise connectors need it, and only with mutual TLS and an allowlist**, after confirming which shipped broker configuration your path gives you.

**Do not specify sticky sessions; do specify a highly available cache** — the same decision from two sides. And **settle the gateway's health check before the load balancer is procured**.

**Terminate TLS in one named place, and state what protects the cleartext behind it.** **Treat the domain-controller path as an availability dependency with a named owner**, and settle the filter's behaviour when OpenIAM is unreachable before the first controller is touched.

What changes all of this is a deployment not on the sign-in path for anything external — internal-only governance, no self-service, no federation, no protected applications. There the edge shrinks to an internal load balancer, the AWS default stops mattering, and the only crossings left are the connector zones and, if password synchronization is in scope, the domain controllers.

## What OpenIAM does not do here

* **There is no Kubernetes `Ingress` object in the shipped application charts** — no controller, no hostnames, no path rules, no cert-manager wiring.
* **There is no separate public endpoint for the identity provider.**
* **The ESB's port carries no protection of its own.** It is an internal service interface placed behind the Access Gateway, and network placement is what keeps it there.
* **The backends do not re-make the gateway's decisions.** They act on the decisions the Access Gateway has already made and passed to them in the request.
* **The Access Gateway offers no load-balancer-usable health endpoint**, and **the packaged installation opens no inter-node port**.
* **Source-address allowlisting sits at the network layer** — add it wherever your standard requires it; nothing in the platform depends on a fixed source address.
* **There is no shipped inbound provisioning endpoint.** A design assuming an externally reachable SCIM service is not supported by anything in the shipped deployment material.

## Related

* [Connector placement](/solution-architecture/integration/connector-placement.md) — where connector processes sit, and the site-to-site link a cloud-hosted deployment needs.
* [Choosing a topology](/solution-architecture/deployment/choosing-a-topology.md) — the shape this zone model is applied to.
* *How the Access Gateway works* in the Administration Guide — what the gateway does per request.
* *Content providers and URI patterns* in the Administration Guide — the objects behind the headers the gateway sets and strips.
* The [Installation Guide](/installation/installation.md) — the port inventory and the inter-node firewall rules.

*Applies to OpenIAM 2026.8.1. Last reviewed 13 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/deployment/network-design.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.
