Technical Documentation

In-depth technical reference for Authes: zero-database storage, PIN authentication, tenant isolation, and self-hosting.

1. Architecture Overview

Authes is a lightweight OpenID Connect Core 1.0 and OAuth 2.1 Identity Provider built with Go. Unlike traditional identity servers that require a separate relational database (PostgreSQL, MySQL) or external cache (Redis), Authes is designed around a zero-database architecture.

Key Concept: All configurations, clients, signing keys, and user accounts persist directly as plain, encrypted YAML files with atomic file-system writes.

How Zero-Database Persistence Works

  • Atomic writes: Updates are written to a temporary file and atomically renamed into place (os.Rename). This guarantees no partially written or corrupted files during crashes or restarts.
  • In-memory read cache: Frequently accessed users and client configurations are cached in-memory with mutex synchronization, delivering sub-millisecond response times.
  • No schema migrations: Data structures are decoupled YAML documents. Upgrading Authes does not require running database migrations or managing connection pools.
  • Effortless backups: A full backup is simply a folder copy: cp -r ./data /backup/.

2. Default Authentication: PIN & Reset Password

Standard web authentication often burdens users with complex password rules, forced email verification links, and SMS codes. Authes provides a frictionless, privacy-first authentication model by default:

How Authentication Works

  1. Memorable Username: When a user registers, Authes generates a clean, pronounceable, non-confusing username (e.g. bold-fox4). Users can keep this handle or customize it.
  2. 4-Digit PIN or Password: The user sets a quick numeric PIN (e.g. 4 digits) or a standard password. On touch devices and mobile phones, a built-in numeric keypad makes sign-in instant.
  3. Permanent Password Reset Phrase: During sign-up, Authes generates a secure, permanent reset passphrase. The user copies and saves this phrase in their password vault.
  4. Zero-Email Recovery: If the user ever forgets their PIN, they visit /reset and input their username and permanent reset phrase. Access is restored immediately without needing an SMTP mail server.
Security Defenses: Simple PIN authentication is fortified with automatic rate limiting, progressive login delays, and account lockout protections against automated brute-force attacks.

3. Client ID Metadata Documents (CIMD)

Client ID Metadata Documents (CIMD) eliminate the need to manually create an application in an admin console or store client secrets in public web applications or SPAs.

How CIMD Operates

Your client ID is simply the HTTPS URL where your client metadata JSON file is hosted:

https://mywebsite.com/client.json
{
  "client_name": "My Web Site",
  "redirect_uris": [
    "https://mywebsite.com/auth/callback"
  ]
}

When a user initiates login, your app redirects them to:

Authorize URL
https://authes.org/oauth/authorize?
  response_type=code
  &client_id=https://mywebsite.com/client.json
  &redirect_uri=https://mywebsite.com/auth/callback
  &scope=openid profile

Authes fetches https://mywebsite.com/client.json over HTTPS, confirms that the redirect_uri belongs to the same domain, and handles user authentication. The authorization code is returned to your callback and exchanged at /oauth/token without requiring a pre-shared secret (token_endpoint_auth_method: none).

4. Dynamic Client Registration (DCR — RFC 7591)

For backend services, microservices, or native desktop and mobile applications that cannot host a public HTTPS metadata document, Authes fully supports RFC 7591 Dynamic Client Registration.

Registration API Request

POST /register/client
curl -X POST https://authes.org/register/client \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "Backend Service",
    "redirect_uris": ["https://api.mywebsite.com/auth/callback"],
    "grant_types": ["authorization_code"],
    "response_types": ["code"],
    "scope": "openid profile email"
  }'

Registration API Response (201 Created)

Response JSON
{
  "client_id": "dyn_a982f1b0c7d4e321",
  "client_secret": "sec_8f90a1b2c3d4e5f60718293a4b5c6d7e",
  "client_name": "Backend Service",
  "redirect_uris": ["https://api.mywebsite.com/auth/callback"],
  "token_endpoint_auth_method": "client_secret_post"
}

Clients registered through DCR authenticate during token exchange using their client_secret via HTTP Basic Auth or form-encoded POST body.

5. Multi-Tenancy & Directory Layout

Authes natively supports multi-tenancy. Every tenant is completely isolated in its own filesystem directory with independent cryptographic keys, configuration settings, user databases, and client registrations.

Directory Structure

Filesystem Layout (data/acme/)
data/
└── acme/
    ├── config.yaml      # Tenant configuration (DCR, CIMD, PIN rules)
    ├── jwt_key.pem      # Dedicated 2048-bit RSA private key for RS256
    ├── clients/         # Saved client YAML files (dyn_*.yaml)
    ├── users/           # User account YAML files
    └── templates/       # Custom login/register HTML overrides

Tenant Scoped Endpoints

When a tenant named acme is created, its endpoints become active immediately:

  • Discovery: GET /acme/.well-known/openid-configuration
  • Authorization: GET /acme/oauth/authorize
  • Token Exchange: POST /acme/oauth/token
  • JWKS Public Keys: GET /acme/.well-known/jwks.json
  • Dynamic Registration: POST /acme/register/client

Creating Tenants

Tenants can be created interactively through the /admin dashboard or programmatically by sending a POST request to POST /admin/api/tenants with {"slug": "acme", "name": "Acme Corp"}.

6. Self-Hosting with Docker & Docker Compose

Because Authes has zero external dependencies, self-hosting requires only a single Docker container. All persistent data lives in the mounted ./data directory.

Docker Compose Configuration

docker-compose.yml
version: '3.8'

services:
  authes:
    image: oaeth/authes:latest
    container_name: authes
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./data:/app/data
    environment:
      - PORT=8080
      - ISSUER=http://localhost:8080

Start the container with a single command:

Shell
docker compose up -d

Running from Go Source

You can also compile and run Authes directly from source code:

Shell
git clone https://codeberg.org/oaeth/authes.git
cd authes
go run .

Resource Footprint

The compiled Go binary runs with negligible overhead:

  • RAM: Typically less than 20MB of resident memory.
  • CPU: Near zero idle utilization.
  • Storage: Only the size of your YAML files and RSA keys.

7. Protocol & Endpoints Reference

Authes implements standard OpenID Connect and OAuth 2.1 protocol endpoints:

Function Method Path Description
OIDC Discovery GET /.well-known/openid-configuration Server metadata and supported features
JWKS Public Keys GET /.well-known/jwks.json RSA public keys for RS256 token verification
Authorize GET /oauth/authorize Interactive user authorization and login
Token POST /oauth/token Authorization code exchange for tokens
UserInfo GET /oauth/userinfo User claims via Bearer access token
Dynamic Registration POST /register/client RFC 7591 client onboarding
Admin Console GET /admin Web-based management dashboard
Copied to clipboard