How a request earns its way in.

Someone opens a private app. Pramaan's server, the broker, checks who is asking and from which device, applies your access rules, and only then connects them. This page follows one request, then shows what runs where.

One request, start to finish

  1. 01

    Someone asks.

    Someone opens a private app from the Pramaan app or a browser, or an AI agent calls a tool. The request carries a token the broker issued, or a browser session.

    BrowserPramaan appAI agentRequestwith a token
  2. 02

    It arrives through one way in.

    The request reaches the broker through an entry point that this deployment has switched on. The app behind it has no public address: its connector, a small program beside it, dials out to the broker and opens no inbound port.

    onoffoffoffBrokerAppdials out
  3. 03

    The broker checks who is asking.

    It resolves the token or session to a person or an agent, and refuses one it did not issue or that has expired.

    Issued hereNot issued here,or expiredBrokerpassesrefused
  4. 04

    Your access rules decide.

    Access rules weigh who is asking, the posture reported for the person's device, and which app. Private apps behind the connector are decided on every request; OIDC and SAML applications receive their decision when a token is issued.

    Who is asking?From which device?Which app?Your rulesdecision
  5. 05

    The connector carries it, or nothing does.

    An allowed request travels to the app over the connector's tunnel, and the connector relays only to targets on its own approved list. A refused request stops at the broker.

    BrokerConnectorAppOther appOther appnot reachablerefused: stops here

What runs where

Illustrative
Broker
Connector
Your app
Broker
The broker runs as one process on a host you run. It signs people in, decides access and keeps the evidence.
Connector
The connector runs inside your network, beside a private app. It dials out to the broker and opens no inbound port, and relays only to targets on its own approved list.
Desktop agent
A tray app and a command line for laptops. It opens private apps, sends posture reports, and can update itself after checking a signature bound to the version.
Android app
The Pramaan app is Android only. It approves sign-ins and keeps the device's keys. The published build points at Pramaan's own hosted broker, so a self-hosted deployment needs a rebuilt, re-signed app.
Consoles
A web console for administrators and one for everyone else. Administrators manage people, policy and posture weights; people see their own sessions, devices and sign-in history.

For your engineers

Technical detail: the architecture

Pramaan ID architectureFour tiers. Principals — a browser, the Pramaan app, pramaan-desktop and an AI agent — reach the boundary, which is a ZTNA tunnel, a forward-auth proxy, a secure web gateway and a raw-TCP ingress. All four enter one core process, companion-broker, holding identity, policy, trust and evidence. Beneath it sits state you own: PostgreSQL, the directory, key material and an append-only transparency log. One shared crate, sso-core, is compiled into the server, the desktop client and the phone.PRINCIPALSBrowserany OIDC / SAML appPramaan apppasskeys · approvalspramaan-desktoptray · pramaanctlAI agentMCP tool callsBOUNDARYZTNA tunnelper applicationForward-authany reverse proxySecure web gatewayDNS · TLS · DLPRaw-TCP ingressRDP · SSH · VNCEach way in is off until its own switch is set.COREcompanion-brokerRUST · AXUM · ONE PROCESSIdentityOIDC · SAML · SCIM · LDAPPolicyRBAC · posture · per requestTrustdevice CA · DPoP · PQ co-signEvidenceRFC 6962 log · auditSTATEPostgreSQLdurable, yoursDirectorynative or federatedKey materialkey files on your hostTransparency logappend-only, verifiableSHAREDsso-coreone security crate, compiled identically into the server, the desktop client and the phone

The tiers, top to bottom

Principals

Whoever is asking: a browser signing in to an OIDC or SAML application, the Pramaan app on a phone, pramaan-desktop and its pramaanctl command line on a laptop, or an AI agent calling a tool over MCP. The app and the desktop client also hold a device key, which can bind their tokens to the device. Agents are a principal of their own, and they are off until switched on.

Boundary

Four ways in to private applications: a tunnel through an inside-out connector, forward-auth in front of a reverse proxy, a secure web gateway, and raw-TCP ingress. None of them runs until it is switched on; in the product, each is opt-in.

Core

One core process, companion-broker, holds identity (OIDC, SAML 2.0, LDAP, SCIM), the policy engine, device trust and the evidence. It starts its optional listeners inside that same process, so identity, policy and evidence are not separate services to keep in step.

State

PostgreSQL holds the durable state. People come from Pramaan's own directory or are federated from another one. The broker's keys are key files on your host, and audit events become leaves of an append-only RFC 6962 log. In a self-hosted deployment all of it sits on infrastructure you run.

One shared crate, sso-core, spans the tiers: it is compiled into three programs (the broker, the phone app's bridge and pramaan-desktop). Phone, laptop and server share one implementation of that security code.

The connector is pramaan-connector, and the consoles, admin-ui and account-ui, are built with Svelte 5.

What a connection meets on the way in

Recorded run Dial-out, and an ordered stack of guards in front of the two listeners we publish: a connector dials out to the broker and opens no inbound port. Our deployment's filters and the broker's pre-auth gate stand in front of both listeners. The broker checks drawn after the gate are the raw-TCP ingress's; the connector listener has its own, not drawn. The filters are configuration of our deployment, not part of the broker. compose.yml:254-272 and the host filter ruleset · 03ada75 · recorded 2026-11-05
Guards in front of the listeners we publishThe layers a new connection meets, in order, in our reference deployment: our deployment's filters and the broker's pre-auth gate, in front of both published listeners; then the broker's checks on the raw-TCP ingress; then the connector's own allowlist. A flood from one address is stopped at the source-address connection limits once it goes over them; a legitimate connection reaches the access-rule decision. flood from one address legitimate connection Our deployment, both listeners edge firewall source-address connection limits container ingress filter Broker, both listeners pre-auth gate Broker, raw-TCP ingress only token authentication client-id allowlist group visibility safety interlock access-rule decision Connector, beside the app connector upstream allowlist

What this does not show: a penetration test, the connector listener's own checks after the pre-auth gate, every check the broker makes, or any limit or address.

Text version

A hostile connection: a flood from one source address

  1. edge firewall: passes; the port is open
  2. stopped at, once over the limit: source-address connection limits

A legitimate connection to the raw-TCP ingress

  1. edge firewall
  2. source-address connection limits
  3. container ingress filter
  4. pre-auth gate
  5. token authentication
  6. client-id allowlist
  7. group visibility
  8. safety interlock
  9. reaches the access-rule decision
  10. if it allows: connector upstream allowlist

Layer names only; no limits or addresses are published.

Step through one request

Illustrative: one private-app request, step by step. Nothing here moves until you press a button.

  1. Browser or app

    Someone opens a private app from the Pramaan app or a browser, or an agent calls a tool.

    Evidence. A token the broker issued, or a browser session.

  2. Identity

    The broker resolves the token or session to a person or an agent, and refuses one it did not issue or that has expired.

    Evidence. The token, resolved on every call.

  3. Device posture

    A laptop's readings arrive as agent posture reports, and a browser session carries the posture captured when it was signed in: that of the device that approved it.

    Evidence. The posture report. It is self-reported: the report's signature proves which enrolled device sent it, not that its readings are true.

  4. Policy decision

    Access rules weigh who is asking, which app, and the posture reported for the person's device.

    Evidence. One of four verdicts: Allow, Deny, Step-up or Inspect. For a private app, group membership is re-read and the access rules are re-run on each request.

  5. Connector

    An allowed request travels to the app over the connector's tunnel; a refused request stops at the broker.

    Evidence. When the web edge refuses a request, because of the person's groups or your access rules, the refusal is written as an audit event.

  6. Private app

    The app has no public address: its connector dials out to the broker and opens no inbound port, and relays only to targets on its own allowlist.

    Evidence. The decision made before it: the app is denied unless an access rule allows it.

  7. Transparency log

    Every audit event becomes a leaf of the append-only RFC 6962 transparency log, whose signed tree head anyone can check.

    Evidence. A leaf and a signed tree head. The log proves that recorded events were not altered; it is not a record of every access decision.

Questions

Do I have to switch on every way in?

No. Each way in to private applications is off until you set its switch: in the product, each is opt-in. Signing in to OIDC and SAML applications needs none of them.

Where does the broker run?

On a host you run, as one process, with its state in PostgreSQL and its keys in key files on your host. The published Android app is the exception: it points at Pramaan's own hosted broker, so a self-hosted deployment needs a rebuilt, re-signed app.

Is every request decided again?

Private apps behind the connector are decided on every request. OIDC and SAML applications receive their decision when a token is issued, and that access token stays usable until it expires, 300 seconds by default, unless the person is deactivated.

What do the phone, the laptop and the server share?

The same security code: one shared security core, compiled into three programs, the broker, the phone app's bridge and the desktop agent. A change to it changes the security code of all of them at once.

Talk to us, or try it first

  1. Book a walkthrough

    Against your own apps, not slides.

  2. Run the lab

    It uses a demonstration account; none of your data is involved.

  3. See pricing

    Published floors, named-user bands and what every tier includes.