Skip to content
OIDOT

Technology

A platform boundary, enforced in the architecture.

Oidot is built as a platform that owns identity, organisations, and access, plus independent product backends that trust it. The separation is not a convention — it is enforced by how tokens are issued and verified, which is what lets each product move at its own pace.

Deliberately boring at the base

The base platform is one service, one database, one container. That is a decision, not a stage we have not yet grown out of. Identity, organisations, entitlement, and billing are stable, well-understood problems, and solving them inside a single well-factored codebase avoids the operational cost of a distributed system before there is anything to distribute.

What is not boring is the boundary. Products do not live inside the platform. Each product is its own deployable, with its own database and its own runtime, free to use a different language or framework where the problem calls for it. The platform issues a signed credential; the product verifies it independently and answers its own authorisation questions.

Infrastructure is added when a specific requirement cannot be met without it. Caching, queues, additional data stores, and service splits each have a named trigger rather than a place on a roadmap. Fewer moving parts means fewer ways to fail, and it means the parts that do exist are there for a reason we can state.

Technology stack

Application

Python / FastAPIthe platform service
Pydanticrequest/response validation at every boundary
SQLAlchemy (async)data access, behind a repository layer
Alembicschema migrations, from the first table onward

Data

PostgreSQLsystem of record for everything that must be correct
Redisplanned, for caching and rate limiting; introduced only against a named need
S3planned, for large binary objects, with references held in PostgreSQL

Infrastructure

Dockerone build artefact, identical locally, in CI, and in production
AWS ECS Fargatecontainer runtime
Amazon RDS (PostgreSQL)managed database in a private subnet
Application Load BalancerTLS termination and routing
AWS Secrets Managercredentials and signing keys
CloudWatchlogs and metrics

Delivery

GitHub Actionslint, test, build, deploy on merge
rufflinting
pytestunit, integration, and API tests

Frontend

Next.js on Vercelthis site and product frontends

Offline token verification

The platform signs access tokens with an asymmetric key and publishes the public half at a JWKS endpoint. A product backend verifies a caller's identity and entitlement without a network call back to the platform. The platform is therefore not a runtime dependency of every request in the system, and it is not a single point of failure for products that are already running.

Enforced module boundaries

Within the platform, identity, organizations, entitlement, and billing communicate through defined interfaces rather than by reading each other's tables. The seam that products are eventually split along is drawn before it is cut.

Layering that keeps logic testable

Routes handle HTTP. Services hold the rules and know nothing about HTTP. Repositories are the only layer that talks to the database. Business logic can be tested without a running server or a live database, and the data layer can be changed without rewriting the rules on top of it.

Stateless by design

The API holds no in-memory session state. This is the one decision that is expensive to retrofit and nearly free to make upfront: it is what allows horizontal scaling to mean "run more containers" rather than "rewrite the service."

A request, end to end

A browser resolves api.oidot.com to a load balancer, which terminates TLS and forwards the request over a private network to a container running in a private subnet. That container queries PostgreSQL, also private, reachable only from the API’s own security group. Nothing but the load balancer is addressable from the internet.

The footprint is chosen the same way as everything else: VPC, IAM, CloudWatch, and Secrets Manager from the first deployment because retrofitting them is painful; queues, Kubernetes, and API Gateway held back until something specific requires them.

Security as a default, not a phase

Authentication is enforced through shared dependencies rather than remembered route by route. Secrets live in a managed store, never in the repository. Input is validated at every boundary, and database access goes through an ORM rather than assembled strings. Credentials are hashed with a modern algorithm and never logged.

Read more about security

Products verify the platform's token themselves. There is no per-request call back to the platform, which is what keeps a product's availability independent of ours.

The architecture is documented

The platform is in active development. If you are evaluating Oidot, or interested in building on it, we are happy to talk through the design in detail.