We Built Our Own Identity Provider
← Back to InsightsEngineering

We Built Our Own Identity Provider

Sometimes the most valuable thing a studio builds isn't a product you can see — it's the foundation everything else stands on.

Jonathan
Jonathan· CTO
7 min read
Share

There's a common picture of what a digital studio does: a client sends a brief, you build the landing page or the app or the integration, you hand it over, done. That's honest work, and most of what gets made is exactly that — the surface a user sees.

There's another level, though, and it's the one we're most interested in: when a team stops assembling deliverables and starts building infrastructure. Not the storefront — the foundation. Not what the user looks at, but what everything else quietly stands on. You don't build those in a week; you design them over years, because the cost of getting them wrong isn't a redone mockup, it's a data breach affecting tens of thousands of people.

So we took on one of the most underrated and most critical subsystems in any product: authentication and identity. We built a full, enterprise-grade OpenID Connect Identity Provider — a server whose entire job is to answer a deceptively simple question, "who is this user, and can we trust them?", the way security, the law and common sense actually demand.

Why identity is the core, not a detail

Every "Sign in with Google," every login form with a two-factor code, sits on top of an Identity Provider. It verifies who someone is, hands applications cryptographically signed tokens they can trust, manages sessions and logout and access revocation, and keeps an immutable record of who logged in, when and how.

Most teams solve this on the side: a table of passwords, some session logic, a password-reset flow with a quiet hole in it. It works while the product is small. The moment it grows — enterprise customers, real compliance requirements, a security audit — that home-grown auth becomes the single biggest risk the company carries. Our answer was to pull identity out into a properly designed system. Once. Done right. Built so you can plug anything into it.

Connectors: the heart of it — and the reason for our name

"ConnectiveHub" isn't an accident. The central idea is that every way of logging in is a pluggable module — a connector — and the server is the hub that unifies them. We split the whole zoo of "prove who you are" into three clean classes of plugin, each obeying one contract, so adding a new method never means rewriting the core.

1. Identity sources — "Sign in with…"

External providers that vouch for a person. We deliberately built one server that speaks to the whole world through a universal OIDC upstream connector — Google, Microsoft / Azure AD, Keycloak, or any standard-compliant provider, negotiated automatically from its discovery document — and, in the same server, the regional rails a market like Russia needs: state identity (Gosuslugi / ESIA), bank and ecosystem logins (Sber ID, T-ID, VK ID, Yandex ID), corporate directories (LDAP / Active Directory, SAML 2.0), and qualified e-signature. The list is open by design: a new national ID or industry provider is a new connector, not a new system. T-ID, VK ID and Yandex ID, for instance, are thin wrappers over one universal OIDC engine — one piece of engineering opens three providers.

2. Authentication factors — how strongly you proved it

A separate class answers not who you are but how convincingly you just proved it: passwords done properly (Argon2id hashing with a secret pepper, checked against dictionaries and breached-password databases), TOTP app codes, WebAuthn / FIDO2 passkeys for phishing-resistant hardware and biometric login, SMS codes with automatic gateway failover, and passwordless magic links.

3. Document signing — a legally meaningful act

The third class is legal electronic signature: a deliberately isolated subsystem, because signing a document is not the same thing as logging in — and must never be a side effect of it.

Who you are, how strongly you proved it, and whether you signed something are three independent mechanisms you can combine like building blocks. That's the "connective" in ConnectiveHub.

One server, many isolated organizations

The system is multi-tenant: dozens of completely independent organizations can live on a single instance. Each tenant gets its own token issuer, so one company's tokens are physically impossible to validate with another's keys; its own signing keys, so compromising one tenant never touches the rest; its own connectors, factors and branding; and hard data isolation enforced at the database level with PostgreSQL Row-Level Security — not in application code, where it's easy to slip, but at the lowest layer, where a query missing its tenant filter simply returns nothing. Adding a tenant is a matter of configuration and key generation, not standing up a new database and server.

A trust model with two questions, not one

Most systems measure access with a single "login level" slider. We built to the NIST 800-63-3 standard, which separates two genuinely different questions: how sure are we who this is (a self-asserted email is low; state or bank verification is high), and how strongly did they prove it just now (one password is weak; a hardware key is strong). Someone who logged in with a hardware key but only ever registered an email is not the same as someone verified by the state using that same key — one number hides the difference; two show it. A service can require a minimum on both axes, and the system offers to step the login up rather than starting over.

Security in layers, not a single wall

Auth is where attackers aim first, so the defenses are independent layers, any one of which stands on its own:

  • PKCE (S256) required for every client — a stolen authorization code is useless without the second secret.
  • Refresh-token rotation with reuse detection — tokens rotate atomically in one transaction; if a stolen token is replayed, the whole session's token family is revoked instantly. Theft stops being quiet.
  • Triple-layer CSRF protection — a synchronizer token, Origin/Referer checks, and a SameSite cookie: three mechanisms instead of one point of failure.
  • Rate limiting and account lockout under brute force, plus a session blacklist for instant revocation on logout or admin block — fail-closed by default.
  • A re-authentication gate for sensitive actions — disabling 2FA or removing a device means proving it's really you within the last five minutes; an existing session isn't enough.

One decision underlies all of it: PostgreSQL is the source of truth, not the protocol engine. We use the mature ory/fosite library to speak OAuth2 / OIDC, but every piece of state — tokens, sessions, consents — belongs to our storage layer. That gives us full control over lifecycle, audit and tenant isolation.

The depth off-the-shelf products skip

This is where a hosted Keycloak or Auth0 stops — and part of why building your own is worth it. Qualified electronic signature, for example, solves two completely different jobs, so we kept them as two separate subsystems: signature as login (signing a server nonce to prove key ownership — maximum identity assurance, but nothing is legally signed) and signature as a legal act (an explicit, per-document ceremony with a hash, a qualified timestamp and certificate-status checks). Mixing them would let a routine login accidentally sign a binding document; we designed it so that can't happen. Private keys never leave the user's device — the server receives only a finished signature, with the cryptography isolated in a separate sidecar. Add an append-only, tamper-evident audit log and full user self-service — review and revoke consents, manage factors, delete the account — and you have a system that respects the law it runs under.

Why build instead of buy

The fair question: why not just use Keycloak, Auth0 or Okta? Because where a system is both a competitive advantage and a zone of legal risk, a company should own it, not rent it. Owning it buys full control — our database is the source of truth, so there's no black box and no vendor lock-in, and even the key store is swappable — genuinely crypto-isolated multi-tenancy instead of prefix-based imitation, a trust model that fits real requirements, and one core that works equally well with Google and with state identity. It's a globally standard system that also speaks the local language, not the other way around.

Under the hood

A quick look, to show it's engineering rather than a prototype:

  • Go — a single compiled, memory-safe binary.
  • ory/fosite — the OAuth2 / OIDC protocol engine (but not the source of truth).
  • PostgreSQL 16 + Row-Level Security — the source of truth and tenant isolation.
  • Redis — sessions, rate limits, lockouts, blacklists.
  • Cloud KMS — envelope encryption and token signing, behind a swappable interface.
  • Argon2id + WebAuthn / FIDO2 — brute-force-resistant passwords and hardware keys.

A full admin API, an operator CLI, Prometheus metrics, Grafana dashboards and Docker / Kubernetes deployment round it out — the operational maturity, not just the feature list.

What this says about us

We didn't build this because someone ordered an Identity Provider. We built it because a real engineering studio should be able to make foundations, not just facades — the systems a user never sees but everything depends on, where what matters isn't only the pixels but the threat model, the data isolation, the compliance and an architecture meant to last years.

Authentication is the perfect example: easy to make "work," genuinely hard to make right. If our name means anything, it's this — we connect. People and services, strict security and a smooth login, a local market and the wider world — at the level of the system, not just the brief. If that's the kind of foundation your product needs, let's talk.