This repository is the public-facing companion to the MrWhoOidc product line.
It exists to publish:
| Area | Purpose |
|---|---|
| docs | deployment guides, configuration reference, admin and developer docs, operational guides |
| demos | working example applications in .NET, React, Go, Kotlin, plus an OBO demo API |
| src/MrWhoOidc.Client | .NET client package for discovery, auth flows, token exchange, logout helpers, and JWKS caching |
| src/MrWhoOidc.Security | .NET security helpers including DPoP support |
| docker-compose.yml | base container deployment |
| docker-compose.dev.yml | local development overlay with MailHog |
| docker-compose.redis.yml | Redis performance overlay |
| docker-compose.production.yml | hardened production overlay |
| website | static GitHub Pages site for the project overview |
MrWhoOidc currently focuses on a standards-based OIDC and OAuth 2.0 identity service with current product capabilities including:
mrwho-clicerts/aspnetapp.pfx for local testingThe examples below use docker compose. If your environment still exposes the legacy docker-compose binary, replace the command name accordingly. First run is typically 3-5 minutes, depending on image pulls and container startup time.
The base docker-compose.yml path is production-oriented. On an empty database it does not auto-seed a tenant or admin user; the first usable local instance requires an explicit bootstrap.
This is the default published-image path. Do not clone MrWhoOidc and do not use docker compose -f docker-compose.yml up -d --build for this flow.
mkdir -p "$HOME/src"
cd "$HOME/src"
git clone https://github.com/popicka70/MrWho.git
cd MrWho
bash ./scripts/generate-cert.sh localhost changeit
chmod 644 ./certs/aspnetapp.pfx
test -f ./certs/aspnetapp.pfx && echo "certificate ready"
cp .env.example .env
# for the stock local path, edit at minimum:
# POSTGRES_PASSWORD
# BOOTSTRAP_TOKEN on a fresh local database
# CERT_PASSWORD=changeit and OIDC_PUBLIC_BASE_URL=https://localhost:8443 already match the generated certificate and default local ports
# leave MAIL_* empty unless you plan to enable SMTP
# if you are reusing an existing local Docker volume and changed POSTGRES_PASSWORD,
# either keep the original password or reset the local database state first:
# docker compose down -v --remove-orphans
grep -q 'ghcr.io/popicka70/mrwhooidc:latest' docker-compose.yml && echo "published image compose file confirmed"
docker compose config | grep ghcr.io/popicka70/mrwhooidc:latest
docker compose up -d
# if the first bootstrap curl fails with a TLS or socket error,
# wait 5-10 seconds for HTTPS startup and retry the same request
# bootstrap the first tenant and admin user on an empty database
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,
# then re-apply the containers
docker compose up -d
# post-bootstrap smoke tests
curl -k https://localhost:8443/t/default/.well-known/openid-configuration
curl -k -I https://localhost:8443/admin/clients
curl -k https://localhost:8443/t/default/jwks
bash ./scripts/health-check.sh https://localhost:8443 default
If either verification command above does not print ghcr.io/popicka70/mrwhooidc:latest, stop because you are no longer following the published Docker image path.
Expected discovery output includes fields such as issuer, authorization_endpoint, token_endpoint, and jwks_uri.
Expected first-run behavior:
https://localhost:8443/admin/clients redirects anonymous users to the tenant login page.BOOTSTRAP_TOKEN after the initial bootstrap so POST /bootstrap is no longer available.https://localhost:8443/admin shows a self-signed certificate warning until you trust the generated local certificate.mrwho-oidc logs show password authentication failed for user "oidc" and PostgreSQL says it is skipping initialization, you are reusing an older local database volume. Restore the previous password or run docker compose down -v --remove-orphans, then start again.mrwho-oidc logs show Configured HTTPS certificate file '/https/aspnetapp.pfx' was not found, rerun bash ./scripts/generate-cert.sh localhost changeit, then chmod 644 ./certs/aspnetapp.pfx, and restart the stack.Optional overlays:
# Development logging + MailHog
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Add Redis caching
docker compose -f docker-compose.yml -f docker-compose.redis.yml up -d
# Hardened production-style setup
docker compose -f docker-compose.yml -f docker-compose.production.yml up -d
Default endpoints:
https://localhost:8443/t/default/.well-known/openid-configurationhttps://localhost:8443/admin/clientshttps://localhost:8443/t/default/jwkshttps://localhost:8443/jwksUse the tenant-scoped discovery document for first-run smoke tests. Root discovery depends on a default tenant already existing.
For fresh production-style databases, set BOOTSTRAP_TOKEN and follow docs/deployment-guide.md.
Start here depending on what you need:
See demos/README.md for the full matrix. Highlights:
.NET Razor client for interactive confidential-client scenariosReact SPA for browser-only PKCE flowsGo web client for non-.NET web integrationsKotlin Spring client for Java and Spring environmentsOBO demo API for delegated token validation patternsThe public client packages currently published from this repo are:
| Package | Current Line | Targets |
|---|---|---|
MrWhoOidc.Client |
2.0.1 |
net8.0, net10.0 |
MrWhoOidc.Security |
2.0.1 |
net8.0, net10.0 |
These packages are intended to make client integration, discovery, token handling, DPoP, and logout processing easier for .NET applications.
Current public documentation reflects the product’s current behavior:
/t/{slug}See docs/multitenancy-quick-reference.md for the operational model.
This repo ships a small static site in website intended for GitHub Pages deployment. The Pages workflow lives in .github/workflows/deploy-pages.yml.