A production-ready OpenID Connect (OIDC) and OAuth 2.0 provider built on .NET 10 with PostgreSQL, optional Redis caching, a tenant-aware admin UI, sample applications, and browser E2E coverage.
Source code in this repository is licensed under Apache 2.0. Use of the MrWhoOidc name, logos, and other brand assets is governed separately by TRADEMARK_POLICY.md.
The commands below use docker compose (Compose V2). If your Docker installation still exposes the legacy docker-compose binary, replace the command form accordingly.
Use the published Docker image first. Clone MrWho if your goal is to run MrWhoOidc. Clone MrWhoOidc only if you need to change code, debug the product, or rebuild images from source.
Estimated time: 3-5 minutes on a typical development machine. This path pulls ghcr.io/popicka70/mrwhooidc:latest instead of building local images.
Use a persistent working directory. Do not clone into /tmp.
mkdir -p "$HOME/src"
cd "$HOME/src"
pwd
git clone https://github.com/popicka70/MrWho.git
cd "$HOME/src/MrWho"
pwd
test -f docker-compose.yml && test -f .env.example && echo "MrWho repo ready"
bash ./scripts/generate-cert.sh localhost changeit
cp .env.example .envEdit .env and set at minimum:
POSTGRES_PASSWORDto a strong passwordCERT_PASSWORD=changeitOIDC_PUBLIC_BASE_URL=https://localhost:8443BOOTSTRAP_TOKENto a temporary secret if the database is empty
Then start and bootstrap the stack:
docker compose up -d
curl -k -X POST https://localhost:8443/bootstrap \
-H 'Content-Type: application/json' \
-H 'X-Bootstrap-Token: your-temporary-bootstrap-token' \
-d '{
"tenantSlug": "default",
"tenantName": "Default Tenant",
"adminEmail": "admin@example.com",
"adminPassword": "ChangeMeNow123!",
"adminName": "Administrator"
}'
# Remove BOOTSTRAP_TOKEN from .env after the bootstrap succeeds.
docker compose up -d
curl -k https://localhost:8443/t/default/.well-known/openid-configuration
bash ./scripts/health-check.sh https://localhost:8443 defaultUse this path when you want the published image to be the source of truth and you do not need to change the product code.
Use this path only when you need to modify or debug MrWhoOidc itself. The commands below build local images from the checked-out source tree.
All commands below assume your current directory is exactly the repository root. Use a persistent folder such as $HOME/src; do not clone into /tmp.
mkdir -p "$HOME/src"
cd "$HOME/src"
pwd
git clone https://github.com/popicka70/MrWhoOidc.git
cd "$HOME/src/MrWhoOidc"
pwd
test -f docker-compose.dev.yml && test -f .env.example && echo "MrWhoOidc source repo ready"
cp .env.example .env
docker compose -f docker-compose.dev.yml up -d --build
curl -k https://localhost:8443/t/default/.well-known/openid-configuration
bash ./scripts/verify-installation.shThe source-built development stack starts:
- MrWhoOidc WebAuth at
https://localhost:8443 - PostgreSQL and Redis
- MailHog at
http://localhost:8025 - OidcDemo at
https://localhost:5001 - RazorClient at
https://localhost:5003 - ReactOidcClient at
http://localhost:5173 - TestApi at
https://localhost:7149
Development mode auto-seeds the default tenant and admin account. Sign in with admin@mrwho.local / Admin123!.
The canonical local admin entry is https://localhost:8443/admin/clients. The /admin route redirects there.
When you want customer onboarding and license requests to stay inside MrWhoOidc.Web, start the licensing overlay on top of the base source-built dev stack:
docker compose -f docker-compose.dev.yml -f docker-compose.licensing-portal.dev.yml up -d --buildThis overlay adds:
- MrWhoLicensing API at
https://localhost:7443 MrWhoOidc.Webcustomer portal athttp://localhost:8088/portal.html- seeded OIDC clients from
dev/portal-seed-manifest.json:portal-webfor the browser PKCE flowlicensing-adminfor the internal backoffice
Local flow:
- open
http://localhost:8088/portal.html - register or sign in through
https://localhost:8443/t/default - onboard an organization in the portal
- submit registration or licensing requests through the authenticated portal API
The portal keeps the browser on the MrWhoOidc.Web host and proxies:
/oidc/*to WebAuth/licensing/*to MrWhoLicensing
Customer-safe portal endpoints live under https://localhost:7443/api/portal/*.
For an IDE-first workflow, you can also run the Aspire host:
dotnet run --project MrWhoOidc.AppHostFor a production-style deployment from the published image, use Option 1 above and the MrWho repository.
- OpenID Connect Provider (OP) with full discovery support
- Authorization Code Flow with PKCE
- Client Credentials Grant
- Token Exchange (RFC 8693) with DPoP support
- Back-Channel Logout (BCL) with durable outbox pattern
- JWT signing with key rotation
- Automatic EF Core migrations
- Multi-Tenancy: Isolated data per tenant with subdomain/path routing
- User Enrollment: Self-service registration, tenant invitations, and tenant domain auto-join
- High Performance: Optional Redis caching (60-80% DB load reduction)
- Production Hardened: Non-root containers, read-only volumes, network isolation
- Observability: Structured logging, OpenTelemetry, health endpoints
- Zero-Downtime Upgrades: Backward-compatible migrations, graceful degradation
- Federated authentication with upstream IdPs
- Multi-level IdP configuration support
- Token exchange for delegated access
MrWhorepositorydocker-compose.yml: recommended published-image path for first-time local and production-style deployment.docker-compose.dev.yml: primary source-build contributor path with seeded data, example applications, MailHog, and local image builds.MrWhoOidc.AppHost: optional Aspire workflow for local .NET debugging and orchestration.docker-compose.yml: source-repo production-shaped compose file that still builds locally from this repository's Dockerfile.
Two security-sensitive knobs now have explicit configuration surfaces:
{
"Auth": {
"TokenValidationClockSkewSeconds": 60
},
"KeyRotation": {
"RsaKeySizeBits": 3072
}
}Auth:TokenValidationClockSkewSecondscontrols JWT lifetime clock skew for local token validation.KeyRotation:RsaKeySizeBitscontrols the size of newly generated RSA signing and encryption keys.- If you increase
KeyRotation:RsaKeySizeBitsabove the active RSA signing key size, the next key rotation check will mint a replacement signing key immediately and keep the old signing key published until the configured overlap window expires.
For environment-variable based deployments, use Auth__TokenValidationClockSkewSeconds and KeyRotation__RsaKeySizeBits.
| Sample | Purpose | Local URL | Notes |
|---|---|---|---|
Examples/MrWhoOidc.OidcDemo |
Minimal Razor Pages OIDC client | https://localhost:5001 |
Included in docker-compose.dev.yml |
Examples/MrWhoOidc.RazorClient |
Interactive .NET client with OBO flow to TestApi | https://localhost:5003 |
Included in docker-compose.dev.yml and AppHost |
Examples/MrWhoOidc.TestApi |
Protected downstream API used by the demos | https://localhost:7149 |
Included in docker-compose.dev.yml and AppHost |
Examples/ReactOidcClient |
SPA example using PAR and PKCE | http://localhost:5173 |
Included in docker-compose.dev.yml |
Examples/MrWhoOidc.GoWebClient |
Go web app with auth code + PKCE and optional OBO | Manual run | Uses JSON config |
Examples/MrWhoOidc.GoApi |
Go API validating access tokens | Manual run | Uses JSON config |
See docs/example-applications-guide.md for setup details, when to use each example, and how they map to the dev stack.
- docs/for-developers/quickstart-15-min.md - Getting started with the published image first and source builds second
- docs/troubleshooting/local-development.md - Common local startup, port, certificate, and Docker issues
- docs/index.md - Documentation hub by audience and workflow
- docs/production-setup-guide.md - Production bootstrap, environment variables, and cloud deployment notes
- docs/deployment-guide.md - Full deployment lifecycle and container operations
- docs/developer-guide.md - Integration guide for discovery, authorization, token exchange, JAR/JARM, and DPoP
- docs/example-applications-guide.md - Demo applications and sample architecture map
- e2e/README.md - Python + Playwright browser E2E suite
- MrWhoOidc.Cli/README.md - CLI installation and usage (
dotnet tool install --global MrWhoOidc.Cli; NuGet)
- docs/admin-guide.md - Admin UI and operational workflows
- docs/user-registration-and-enrollment.md - Registration, invitations, and tenant domain claims
- docs/docker-compose-examples.md - Deployment variants
- docs/upgrade-guide.md - Upgrade and rollback procedures
- docs/docker-security-best-practices.md - Container and runtime hardening
- Unit and integration tests:
dotnet test - Browser E2E tests:
cd e2e && sh ./setup-venv.sh && .venv/bin/pytest -v - Example application health paths are covered by the dev stack and E2E suite
Published images are available at ghcr.io/popicka70/mrwhooidc.
docker pull ghcr.io/popicka70/mrwhooidc:latest
docker pull ghcr.io/popicka70/mrwhooidc:v1.0.0