Sign inSign up

varavel/zen-idp

By varavel

•Updated about 1 month ago

Zen IdP is a declarative, zero-maintenance OIDC Identity Provider

Image
2

1.2K

varavel/zen-idp repository overview

⁠Zen IdP

CI status ⁠ Release Version ⁠ License ⁠ ⁠

A Varavel project ⁠

Zen IdP is a declarative, zero-maintenance OIDC Identity Provider. It is a single Go binary that turns a reviewable YAML file into a complete authentication service: sign-in with TOTP codes, OIDC Authorization Code Flow for your applications, and a small administration interface - no database server, no external services, nothing to babysit.

⁠Watch a 1-minute video demo (using Grafana as an example OIDC client)⁠

More examples here: https://zen-idp.varavel.com/docs/examples/⁠

⁠The idea

Most identity providers ask you to run several services, manage a database, and click through an admin panel to keep identity data in sync. Zen IdP takes the opposite road:

  • Your YAML is the source of truth. Users, OIDC clients, claims, and policy all live in plain, reviewable files. Changes go through your normal code review flow - not through a hidden database.
  • One root secret does the heavy lifting. From a single ZEN_IDP_SECRET, Zen IdP deterministically derives its RSA signing identity and every user's TOTP credential. Nothing sensitive is ever stored, it is recomputed.
  • SQLite holds only disposable state. Sessions, one-use tokens, rate-limit counters, locks, and audit records live in an embedded SQLite file. Lose the file and you lose nothing permanent: identity and credentials are fully recovered from YAML plus the root secret.

⁠Features

  • Full OIDC Authorization Code Flow with PKCE (S256) for public clients, RS256-signed ID and access tokens, discovery, and JWKS
  • Deterministic TOTP authentication (RFC 6238) - no user database, no shared-secret storage
  • Declarative YAML configuration with deterministic deep composition across files, directories, or globs
  • Administration UI for enrollment tokens, user locks, panic recovery, and the audit log
  • Panic action and administrative locks that instantly gate sign-in and SSO
  • Rate limiting for user logins, administrator logins, and client authentication - keyed by identifier, never by IP
  • Strict validation, secure defaults, CSRF protection, and browser security headers
  • Zero external state: one binary, one SQLite file, done

Tip

The complete, step-by-step documentation lives at [zen-idp.varavel.com](https://zen-idp.varavel.com). It guides you through the whole project (from your first sign-in to production operations) and is the best place to understand Zen IdP in full.

⁠Quick start

Install the zen-idp binary with the shell installer (Linux and macOS), Homebrew, or PowerShell (Windows):

# Linux or macOS
curl -fsSL https://get.varavel.com/zen-idp | sh

# macOS or Linux with Homebrew
brew install varavelio/tap/zen-idp

# Windows
irm https://get.varavel.com/zen-idp.ps1 | iex

The same executable also ships as multi-arch OCI images on varavel/zen-idp (Docker Hub) and ghcr.io/varavelio/zen-idp (GitHub container registry). See the installation docs⁠ for every option.

Generate your bootstrap credentials:

zen-idp generate-secrets

Warning

`generate-secrets` prints **everything** to standard output: the root secret, administrator plaintext and hash, client plaintext and hash, and operational notes. Treat the output as sensitive. Store the plaintext securely, put only the hashes in YAML, and never reuse a secret or hash across clients.

Point Zen IdP at your configuration with environment variables:

ZEN_IDP_CONFIG_PATH=./config/zen-idp.yaml
ZEN_IDP_SECRET=PASTE_THE_GENERATED_ROOT_SECRET_HERE
ZEN_IDP_DB_PATH=./var/zen-idp.db

Zen IdP never loads .env implicitly. Pass it explicitly when you want it:

zen-idp validate-config --env-file ./local.env
zen-idp serve --env-file ./local.env

validate-config runs the exact startup discovery, merge, parse, and validation path - a great habit before every deploy. serve then starts the HTTP listener on 0.0.0.0:8080 by default.

The fastest way to see it all work: open http://127.0.0.1:8080/admin, sign in with the administrator password, create an enrollment token, and share the enrollment link with your first user. That link walks them through setting up their authenticator app.

⁠Configuration

Start from config.example.yaml⁠ - it documents every supported field. The essentials:

  • config.issuer - your public HTTPS URL. This is the OIDC issuer and the base for every endpoint, so it must be the URL your users and applications actually reach.
  • config.security.admin_password_hash - the Argon2id hash of the administrator password (never the plaintext).
  • clients - one entry per application. Include a secret_hash for a confidential client, or omit it for a public client (SPA, mobile app).
  • users - one mapping per identity: a stable sub, optionally a login identifier, a TOTP revision, an expiration, and any custom claims your applications need.

ZEN_IDP_CONFIG_PATH accepts exactly one selector: a single file, a directory (immediate .yaml/.yml children), or a doublestar glob. Files are sorted and deduplicated deterministically, maps merge recursively, and conflicts fail validation - so you can split configuration across files and compose them freely.

⁠Commands

CommandEnvironment requiredWhat it does
serveZEN_IDP_CONFIG_PATH, ZEN_IDP_SECRET, ZEN_IDP_DB_PATHBootstraps everything and starts the server: OIDC endpoints, login and admin UI.
validate-configZEN_IDP_CONFIG_PATHRuns the exact startup configuration path without needing the root secret or the database.
generate-secretsNonePrints an independent root secret, administrator and client credential pairs, and operational notes.

Each generate-secrets run is independent. When adding a client later, use only the new client section of the output - do not replace the root or administrator values unless you intend to rotate them.

⁠What you get out of the box

  • For your applications - the standard OIDC endpoints: discovery, JWKS, authorization, token, and UserInfo. Public clients must use PKCE; confidential clients authenticate with their secret over TLS. No consent screens, no refresh tokens, no surprises.
  • For your users - a clean sign-in page (sub or configured login identifier plus a TOTP code), SSO across all your applications, a panic action that locks their account and signs out every session, and an enrollment flow that sets up their authenticator with a QR code.
  • For you - an admin area to create enrollment tokens, lock or unlock users, clear panic locks, and browse the audit log. Every security-relevant action is recorded.

⁠Security notes

  • Terminate TLS at your reverse proxy, CDN, or load balancer. Zen IdP serves plain HTTP by default, derives Secure cookies and TLS requirements from the issuer scheme, and trusts the X-Forwarded-Proto header of the terminating proxy to recognize the original scheme, so the public issuer URL must be HTTPS in production and your proxy must forward it.
  • The root secret is the crown jewel: it derives the signing key and every TOTP credential. Rotating it rotates everything - plan accordingly.
  • Rate limits are keyed by identifier, never by source IP. Put IP-level limits at your edge.
  • The SQLite file is disposable operational state. Deleting it revokes every session and token and wipes the audit log, but the signing identity and all credentials remain intact.

⁠License

Zen IdP is open-source and available under the MIT License⁠. Feel free to use it in your personal or commercial projects.

Tag summary

Content type

Image

Digest

sha256:49409027c…

Size

35.1 MB

Last updated

about 1 month ago

docker pull varavel/zen-idp