Single sign-on, built in.
CodeB ships with its own OpenID Connect identity provider. Sign-in lives on every page: a button on the landing form gives joiners a verified-in-call badge, the same button on the SoftPhone PWA auto-registers their SIP identity, and admin + third-party apps (Nextcloud, custom RPs) all federate against the same per-tenant user database. Cookie-free, PKCE-only public clients or confidential clients with a secret — pick what fits.
OIDC is on by default. Discovery URL: https://<your-host>/.well-known/openid-configuration
Adding it to your own site? → Read the integration how-to · See the data flow
What you get
Standards-based
OpenID Connect Core 1.0, Authorization Code flow with PKCE (S256), RS256-signed JWTs. Discovery per RFC 8414, JWKS per RFC 7517. Any RP that speaks OIDC will work.
OIDC Core 1.0Cookie-free, honestly
No cookies anywhere — not session, not tracking. Sign-in across multiple RPs uses a signed, 30-minute, same-origin assertion in localStorage at the IdP origin: never sent to other sites, never used for cross-site tracking, cleared on logout. Per-tab access & refresh tokens live in sessionStorage and vanish when the tab closes. Full design on the data-flow page.
One credential store
Sign-in reuses the same HA1 password hash your SIP softphones use. No plaintext password ever reaches the server — the browser hashes it before posting. One user record drives both voice and identity.
No duplicate usersPer-tenant keys
Each tenant gets its own 2048-bit RSA signing key, generated on first need and persisted to App_Data/<tenant>/oidc/. Tokens minted for tenant A never verify against tenant B.
Roles, not just identities
Four roles out of the box: admin, user, siponly, guest. The role travels in the JWT as a custom claim and as a standard groups entry. Per-user custom groups can be set in the admin UI to feed Nextcloud / RP membership directly into the token. Admin pages enforce role === "admin" server-side on every request.
Verified-in-call badge
Sign in on the landing page before joining and your conference tile shows the amber CodeB shield to every participant. Anti-impersonation for free, no third-party identity provider, no Zoom-style verified-name extension required.
Anti-impersonationAuthentication factor in the token
Every id_token + access_token carries amr (RFC 8176) and acr. RPs see the actual factor — ["pwd"] for password, ["hwk","mfa"] for smart card via CP V2 — and can require step-up auth where it matters.
Hot key rotation
Two signing keys can be active at once. Rename private-key.xml → private-key-previous.xml; the next request generates a fresh active key. JWKS publishes both, the kid in each token pins it to the right one. No IIS recycle, no dropped sessions.
Token revocation (RFC 7009)
POST a refresh token to /oidc.ashx?action=revoke to end a session immediately on the IdP side. Confidential clients authenticate with their secret; public clients revoke without auth. Always returns 200 to prevent token-validity enumeration.
CP V2 smart-card sign-on
Operators running Aloaha’s Credential Provider V2 can drop a trust key at App_Data/<tenant>/oidc/cp-v2-trust.xml and pass a signed assertion to /authorize — users skip the login form entirely and the issued tokens carry amr: ["hwk","mfa"].
Integration guide
Adding CodeB sign-on to your own app takes a config block. The OIDC how-to walks through discovery, PKCE, token validation and refresh, with copy-paste samples in vanilla JS and Node/Express.
DeveloperThe endpoints
Standard OIDC URLs. RPs typically only need the discovery URL — everything else is auto-discovered.
| Endpoint | Purpose |
|---|---|
| /.well-known/openid-configuration | Discovery document. RFC 8414. Lists every other endpoint and the supported algorithms. |
| /.well-known/jwks.json | JSON Web Key Set. RFC 7517. The tenant’s RSA public key, so any RP can verify signatures. |
| /oidc.ashx?action=authorize | Authorization endpoint. Redirects to the login form, then back to the RP with an auth code. |
| /oidc.ashx?action=token | Token endpoint. Exchanges the auth code (with PKCE verifier) for an access token, ID token, and refresh token. |
| /oidc.ashx?action=userinfo | UserInfo endpoint. Returns the signed-in user’s sub, role, profile claims. |
| /oidc.ashx?action=end_session | RP-initiated logout. Clears tokens client-side, redirects to post_logout_redirect_uri. |
Wire up an RP in three lines
Any OIDC-compliant relying party works. Point it at the discovery URL, use the public client ID codeb-admin, and you’re done.
The discovery document fills in authorization_endpoint, token_endpoint, jwks_uri, id_token_signing_alg_values_supported and the rest automatically.
What the ID token looks like
RS256-signed JWT. Standard OIDC claims plus a tenant-scoped role and any profile fields the admin filled in for that user.
Cookie-free, by design
OIDC implementations typically lean on a session cookie at the IdP to keep the user "signed in" across /authorize calls. CodeB doesn’t. The login form parses the original authorize URL, validates the PKCE challenge and redirect URI server-side, mints the auth code directly, and posts it back as JSON. The browser navigates to the RP’s callback without ever bouncing through a cookie-bearing redirect.
That keeps the privacy posture honest: no cookies anywhere on the CodeB site, OIDC included. If you advertise cookie-free, you stay cookie-free.
Multi-tenant from day one
Tenant identity is the request domain — same as the rest of CodeB. A user signing in at phone.acme.com hits the Acme RSA key and the Acme SIP credential file; a user at phone.contoso.com hits the Contoso key and the Contoso credentials. The two tenants share no state.
Adding a new tenant means adding a hostname. The first request to /oidc.ashx generates that tenant’s RSA key and persists it at App_Data/<tenant-domain>/oidc/private-key.xml. No schema migration, no restart, no downtime for the other tenants.
Operator notes
| Question | Answer |
|---|---|
| How are passwords stored? | As HA1 digests: MD5(user:realm:password). The plaintext password never reaches the server — the login form hashes it in the browser. Same HA1 your SIP softphones already use. |
| Where do user accounts live? | App_Data/<tenant>/sip-credentials/<tenant-slug>.json. Manage them from the Register admin page. |
| Where does the private key live? | App_Data/<tenant>/oidc/private-key.xml. Plain XML, not committed to source. Back it up with the rest of App_Data. |
| How do I rotate the key? | Delete the file and recycle the IIS app pool. The next request regenerates a fresh key with a new kid. RPs re-fetch JWKS automatically. |
| Is there an audit log? | Yes — App_Data/<tenant>/logs/codeb-oidc-YYYY-MM-DD.log (JSONL), and a parallel feed into the Windows Event Log under source CodeBOIDC. |
| How long do tokens live? | Access tokens 1 hour. Refresh tokens 7 days. ID tokens 1 hour. Auth codes 60 seconds, single use. |
Want the rest? All features →