Developer reference

Technical Specifications

A developer-focused breakdown of CoreOps Auth's architecture, subsystems and capabilities — a reference for engineers evaluating, extending or deploying the platform.

Next.js 16React 19TypeScriptPostgreSQL + RLSHonoTailwind CSSPrometheusDockernginx

Application Architecture

A type-safe Next.js 16 application with a clean public/protected split, server-side rendering and a separate REST API layer.

  • Next.js 16 (App Router) with React 19 and TypeScript in strict mode
  • Clean separation between public pages and signed-in pages, with every protected page checked server-side
  • Server-side rendering for fast first loads; forms submit through server actions rather than separate API calls
  • REST API built with Hono and mounted at /api, with request validation on every endpoint
  • PostgreSQL accessed directly through a small query layer — no ORM — organised by topic
  • Tailwind CSS and an accessible component library; dark and light themes resolved server-side with no flash on load
  • Unit tests (Vitest) and linting (ESLint) for the access rules and safety helpers

Organisations & Tenants

Many organisations, each with its own tenants — isolated row by row in one database and enforced by PostgreSQL itself on the API.

  • A default organisation runs the platform; any number of further organisations each have one or more tenants
  • Every tenant-scoped table carries organisation and tenant columns — one shared schema, no database per tenant
  • PostgreSQL Row-Level Security confines API queries to the caller's organisation and tenant
  • New organisations and tenants start from a copy of the platform's roles and policies; user accounts are never copied
  • One login can belong to several organisations and tenants, picking one at sign-in and switching from the user menu
  • Organisations and tenants can be suspended or archived; archived ones can't be signed into and can be restored
  • Each organisation and tenant has a permanent GUID used by the API, licences and logs

Account Types & Page Access

What a user can open is decided by their membership's primary role and where it sits — never by policies an administrator could mis-edit.

  • Owner — the default organisation's owner, with every section including Users and Security, Layouts and System
  • Global Administrator — manages every organisation, tenant, application and licence, and sees all system logs
  • Organisation Administrator — manages their own organisation's tenants and users; applications and licences are read-only
  • Standard User — every tenant member: dashboard, profile, messages and documentation
  • Page access is a fixed map with deny-by-default — a new section is hidden until it is deliberately added
  • Protection rules: nobody can archive, suspend or demote themselves; the protected Owner and the last administrator can't be removed
  • Maintenance mode lets only the Owner and Global Administrators in

Authentication

Encrypted cookie sessions backed by server-side session records, hashed credentials and TOTP MFA.

  • Encrypted, HTTP-only session cookies, each linked to a server-side session record so it can be revoked
  • Users can see their active sessions and sign out other devices; revoked sessions are rejected by pages and the API alike
  • Sessions are invalidated when the password changes; session lifetime is configurable from 1 hour to 90 days
  • Passwords hashed with bcrypt, with configurable complexity rules
  • Accounts lock after repeated failed sign-ins; optional email alert on sign-in from a new IP address
  • TOTP MFA with QR-code setup and backup codes; can be enforced for everyone after a grace period
  • Invited users activate their account and set their own password through a time-limited email link
  • Optional IP allowlist for administrator accounts

Licensing & External Applications

Register the applications your organisations use, license them per tenant, and let them ask who may use them.

  • External applications are registered on the platform with their own roles (e.g. viewer, editor, admin)
  • Applications authenticate with application tokens — hashed at rest, revocable, with optional expiry and last-used tracking
  • A tenant gets an application through a licence with a seat count and expiry; suspending or archiving the licence suspends access
  • Tenant administrators assign their users to licensed applications with an application role
  • The application API (/api/v1/app) lists the tenants an application serves and returns each tenant's licence, users and each user's role
  • Unknown tenants and unlicensed tenants return the same answer, so a token can't be used to discover tenants
  • Licence expiry warnings are emailed to platform administrators at 30, 7 and 1 days before expiry
  • Licence enforcement is configurable: log a lapsed licence only, or block the tenant's API access outright

RBAC for the API

Roles, policies, resources and validator rules decide what each API request may do — and every decision is recorded.

  • Policies are allow/deny statements over resources and actions, edited visually or as JSON
  • Policies attach to roles; validator rules attach to a resource and apply to every request for it
  • Evaluation order: an explicit deny wins, then an allow, otherwise the request is implicitly denied
  • Policies and validator rules are scoped to their own organisation or tenant, with the default organisation's as the baseline
  • Application tokens use their own principal and never match policies written for signed-in users
  • Every evaluation is written to the validator log with the matching policy and outcome

User Management

Invitation-based accounts, managed per organisation and tenant, with a full history of every sign-in.

  • Users are invited by email — there is no public self-registration — individually or by CSV bulk import
  • A person joins an organisation and is given access to one or more of its tenants; administrators sit at organisation level
  • Existing people can be added to further organisations and tenants with the same login
  • Archive keeps a user's history but blocks sign-in and can be reversed; remove deletes their access
  • Administrators can enable or disable accounts, change roles, resend invitations and reset MFA
  • Email address changes are confirmed at the new address before they take effect
  • Self-service profile: name, email, password, theme, MFA, active sessions and personal access tokens

REST API

Three authenticated API surfaces — for users, for platform administration and for licensed applications.

  • User API under /api/v1, authenticated by session or personal access token and authorised by RBAC policy
  • Personal access tokens are issued for one organisation and tenant, stored hashed and revocable
  • Control-plane API for organisations, tenants and licences, available to platform administrators
  • Application API under /api/v1/app for licensed external applications using application tokens
  • The user and application APIs can be switched off from System settings without a deployment
  • Rate limits per IP address, per organisation/tenant and per application
  • Allowed browser origins (CORS) configurable; an OpenAPI 3.1 description is served to signed-in users

Platform Administration

One place to run every organisation — scoped automatically to what each administrator may manage.

  • Organisations, tenants, applications and licences managed from the Platform pages
  • Organisation Administrators see the same pages limited to their own organisation
  • Licences are searchable and filterable by status, organisation and application
  • Per-tenant data export to a JSON bundle, and restore into an existing or new tenant
  • Read-only, time-limited "view as tenant" inspection for support, with real row-level isolation

Logging & Audit

Six non-blocking logs, each entry tagged with the organisation and tenant it belongs to.

  • Authentication log — sign-ins, sign-outs, failures, lockouts, rate limiting, session terminations and tenant switches
  • System log — administrative actions and background events, attributed to the administrator who acted
  • Email log — every send with recipient, template, delivery status and full message
  • API log — method, path, status, timing and the requester: a user, a personal access token or an application and its token
  • Validator log — every RBAC decision with the matching policy
  • Traffic log — visits to public pages
  • Every entry stores its organisation and tenant GUIDs; logs are filterable, paginated and exportable to CSV
  • Automatic retention purge after a configurable number of days

Rate Limiting & Lockout

Per-IP throttling and persistent account lockout on every sensitive endpoint, tunable without code changes.

  • Per-IP rate limiting on sign-in, MFA, password reset and the contact form
  • API limits per IP address and, once the caller is known, per organisation/tenant or per application
  • Thresholds adjustable from System settings — no code changes
  • Accounts lock after a configurable number of consecutive failed password attempts; lockout survives restarts
  • Works alongside network-level limits at the reverse proxy (an nginx configuration is included)
  • Cloudflare Turnstile CAPTCHA on the public contact form when keys are configured

Email

Runtime-configurable SMTP with built-in templates and fully logged, non-blocking delivery.

  • SMTP settings changed at runtime from System settings — no restart
  • Templates for invitations, access granted, password reset, password changed, email verification, licence expiry warnings and the test email
  • Optional notices: sign-in from a new IP address, and account lockouts to administrators
  • Sending never blocks the action that triggered it
  • Every attempt is logged against the organisation and tenant it was sent for
  • Send a test email from System settings to check the configuration

Dashboards, Messages & Webhooks

Everyday features every user and administrator relies on.

  • Personal dashboards built from widgets; each account type starts from its own template and every user gets their own copy
  • Dashboards can be shared by link, reset to a template, and follow the user's current organisation or tenant
  • In-app messages with starring, forwarding and trash; the Owner can broadcast to everyone
  • Message content is sanitised before it is stored and before it is shown
  • Webhooks for sign-in, sign-out, account creation and password changes — signed with HMAC and recorded with every delivery attempt
  • Built-in documentation with a help card for every feature

Monitoring & Metrics

A Prometheus-compatible metrics endpoint with runtime and request instrumentation, ready for any OpenMetrics stack.

  • Prometheus-compatible endpoint at /api/metrics, protected by a bearer token (METRICS_TOKEN)
  • Always available for scraping, whether or not the REST API is switched on; returns 503 until a token is configured
  • Node.js runtime metrics: GC pauses, heap usage, event-loop lag, CPU and uptime
  • API request counter and duration histogram by method, route and status
  • Route labels use matched route patterns, keeping metric cardinality low
  • Compatible with Prometheus, Grafana and any OpenMetrics-compatible stack

Database

PostgreSQL 15+ with a schema created automatically on first start, Row-Level Security and one-click backup and restore.

  • PostgreSQL 15 or later, local, in Docker or hosted
  • Two database roles: a main role (superuser or BYPASSRLS) for the application, and a restricted role the API uses so Row-Level Security is enforced
  • The complete schema and starting data are created automatically on the first start of an empty database
  • Existing databases are never altered on start-up — schema changes are made in one place and applied by recreating the database
  • Settings cached in memory, with live reads where they matter
  • Full backup with pg_dump and restore with psql from the System pages, including restoring an uploaded backup

Configuration

Database-backed settings that take effect immediately — no restart, no redeploy.

  • All platform settings stored in the database and applied immediately
  • Switches for password reset, MFA enforcement and the REST API
  • Landing page for visitors: sign-in, welcome or maintenance
  • Session lifetime from 1 hour to 90 days, and password complexity rules
  • Maximum upload size, default role for bulk-imported users, and application base URL
  • Application name, description, SEO metadata (keywords, robots, charset) and custom page scripts (e.g. analytics) editable from the admin pages

Security

Hardened headers and careful data handling, applied everywhere by default.

  • Content Security Policy, HSTS for one year including subdomains, clickjacking and MIME-sniffing protection
  • Referrer information limited cross-origin; camera, microphone and location access disabled
  • Passwords, personal access tokens and application tokens stored only as hashes
  • Message HTML sanitised against script injection; CSV exports protected against spreadsheet formula injection
  • Backups and data exports restricted by account type, never by editable policy
  • Server-side session revocation honoured by every page, download and API request

Deployment

A small, non-root Docker image behind a TLS-terminating reverse proxy.

  • Production Docker image running as a non-root user, with the PostgreSQL client included for backups
  • Docker Compose setup with PostgreSQL 16, persistent volumes and an optional nginx reverse proxy
  • A setup script for running the published image against an existing PostgreSQL server
  • TLS terminated at the proxy; the proxy supplies the client IP used for rate limiting and lockout
  • Configured through environment variables — database connections, session secret, metrics token and CAPTCHA keys
scrape /api/metrics200 OK
# Prometheus-compatible, Bearer-token protected
curl -H "Authorization: Bearer $TOKEN" https://your-host/api/metrics

# HELP api_request_duration_ms request latency
# TYPE api_request_duration_ms histogram
api_requests_total{method="GET",route="/api/users",status="200"} 1284
nodejs_eventloop_lag_seconds 0.0021