Two planes, separated by job
The platform is split into two independently deployed services that share a common, layered core. Keeping privileged provisioning apart from per-tenant request traffic shrinks the blast radius of each.A disciplined, layered core
Both services are built in Go on a four-layer architecture with a one-directional dependency rule:1
Foundation
Infrastructure utilities (database, crypto, sessions, tracing). Depends on
nothing above it.
2
Domain
Business logic per entity (users, applications, policies…). Depends only on
foundation.
3
Usecase
Orchestrates multiple domain services for complex flows.
4
REST
HTTP handlers and middleware, the only layer that speaks the wire.
The layering is a documented, review-enforced convention (backed by linting
and directory structure), not a compiler-guaranteed invariant. We call that out
honestly rather than overclaiming.
Hosting and hardening
Iru Identity runs on AWS, with a security-hardened deployment:Hardened containers
Services run on AWS Fargate as non-root with a read-only root filesystem,
no-new-privileges, and all Linux capabilities dropped.
No standing database passwords
The application connects to managed PostgreSQL (Amazon RDS) using
short-lived IAM authentication tokens. There is no static DB password to
leak.
Secrets stay out of code
Credentials and signing keys are injected from a managed secret store at
runtime, never committed to the repository or stored in the database in plain
text.
Scanned supply chain
Container images are scanned for vulnerabilities in the CI pipeline before they
can ship.
Two regions, real data residency
Iru Identity operates in two isolated regions (United Statesus-east-2 and
European Union eu-central-1), and residency is enforced in code, not by
convention.
- Every tenant is pinned to a region, stored on the tenant record.
- The database layer holds separate connection pools per region and routes every transaction by the tenant’s region. A request whose region can’t be resolved is rejected. It never silently falls back to another region.
- Region-specific data operations (such as seed data) are gated so they can’t run against the wrong region.
Built to stay up, and to be observable
Health checks & graceful shutdown
Health checks & graceful shutdown
A dependency-free liveness endpoint lets the orchestrator probe without
touching the database or auth. On shutdown, services stop accepting traffic
and flush tracing, error reporting, and database connections in order.
Resilient data access
Resilient data access
Connection pools are tuned and bounded, ping their database at startup, and
fail fast if it’s unreachable rather than serving broken requests.
Eventually-consistent provisioning
Eventually-consistent provisioning
Account provisioning to your apps runs through an outbox and reconciliation
loop in cancellation-aware background workers, so downstream changes are
retried until they succeed instead of being lost.
End-to-end tracing
End-to-end tracing
Requests are traced with OpenTelemetry from HTTP through application code
down to the SQL query, and structured logs are correlated by tenant and trace
ID. Errors are captured centrally with sampling to balance fidelity and cost.
Verifiable migrations & audit
Verifiable migrations & audit
Schema changes are embedded, version-ordered, and checksum-verified (a
changed, already-applied migration is a hard failure). A standing checker
proves every table’s audit journal stays in sync with its live schema.
Where to go next
Multi-tenant isolation
How row-level security and append-only auditing keep every tenant’s data
separate and tamper-evident.
Authentication architecture
Phishing-resistant sign-in, signed requests, and how SSO trust is established.
Security & privacy
The guarantees these mechanisms add up to.
System architecture
The customer-facing view of how identities and sign-in flow.