🔐

Prizrak OAuth

«Sign in with Prizrak» for any website. People sign in with their Prizrak address and confirm it in the app — no passwords in the browser. Standard OpenID Connect: ready-made plugins for WordPress, Nextcloud, forums and more work out of the box.

Prizrak can be an OAuth 2.0 / OpenID Connect server. The sign-in server is prizrak.im — one for the whole federation: people from any Prizrak server sign in through it, and it asks their home server to confirm. Websites only need to know one address — https://prizrak.im.
For users

What signing in looks like

  1. Click «Sign in with Prizrak» on the website

    The website opens the Prizrak sign-in page. It shows the website’s name, its domain and whose it is.

  2. Enter your address — or scan the QR code

    Type your Prizrak address, for example fox:prizrak.im or vasya:ru.prizrak.im. Or open Prizrak on your phone — + → «Scan QR code» — and point it at the code on the page.

  3. Confirm in the app

    A request appears on all your devices: which website, which domain, what it will learn. The page shows a number — tap the same number in the app. The request lives for 2 minutes.

  4. You’re in

    The website receives your address (and your name and avatar — only if you allowed it). Your Prizrak password is never typed in a browser and never reaches the website.

Not you? If a sign-in request appears that you didn’t start — just tap «Deny» or ignore it. Without your confirmation nobody can sign in as you, even knowing your address. Settings → Privacy → «Sign in to websites with Prizrak» shows every website you signed in to, lets you revoke access, or switch sign-in off completely.
Under the hood

How Prizrak works as an OAuth server

The website talks to one sign-in server. Your identity is confirmed by your own home server and your own devices — over the signed Prizrak federation.

1

Website

Sends the person to prizrak.im/oauth/authorize (OpenID Connect, code + PKCE).

2

prizrak.im

Sign-in server. Finds the person’s home server by the address and asks it — with a request signed by the server key.

3

Home server

Any Prizrak server. Checks the account exists and sign-in is allowed, forwards the request to the person’s devices.

4

Your devices

You tap the number from the page. The home server signs the answer and sends it back to prizrak.im.

← back to the website: a one-time code → tokens. The id_token is signed by prizrak.im (RS256 or ES256), sub is the full Prizrak address, and home_assertion carries the home server’s own signature — so the answer can be checked all the way to the person’s server.
Why it’s convenient

For website owners and for people

🧩

Standard OpenID Connect

Discovery, JWKS, authorization code, PKCE, refresh tokens, userinfo, revocation. Any OIDC plugin or library works — no custom code.

🌐

The whole federation

One issuer — https://prizrak.im. Users of every Prizrak server sign in through it; websites don’t have to know about each server.

🔑

No passwords in the browser

Sign-in is confirmed in the app. Nothing to phish on a fake page: there is no password field at all.

🔢

Number matching and QR

Three numbers in the app, one on the page — accidental «Allow» on a flood of requests won’t work. Or scan the QR code on the page.

🎛

The person decides

Name and avatar are given only with a checkmark. «Websites you signed in to» — with revocation; sign-in can be switched off entirely.

⚡

Works at once

Any Prizrak user registers a website in the app and gets client_id and a secret immediately — no approval, no forms.

For developers

Connect your website in three steps

  1. Register the website in the Prizrak app

    Desktop or Android: Settings → Privacy → «Sign in to websites with Prizrak» → «My websites» → «Register a website». Enter the name, the domain (forum.example.com) and the redirect URI your plugin shows (https://forum.example.com/…/callback).

  2. Copy client_id and the secret

    The secret is shown once — save it right away (a new one can be issued at any time; the old one stops working). The app also shows ready-made settings for the plugin.

  3. Paste the settings into the plugin

    Most plugins only need the discovery address, client_id and the secret — they read everything else themselves.

SettingValue
Issuerhttps://prizrak.im
Discoveryhttps://prizrak.im/.well-known/openid-configuration
Client ID / SecretFrom the app — «My websites».
Scopesopenid (address), profile (name and avatar, if the person allows), offline_access (refresh token).
Redirect URIExactly as registered. Only https:// on your domain or its subdomains; http://localhost — for testing.
PKCES256. Required for websites/apps without a secret, recommended for everyone.
Client authenticationclient_secret_basic, client_secret_post, none (+PKCE)
Username / IDIdentify people by sub (the full address, e.g. vasya:ru.prizrak.im). For a login name use preferred_username — some platforms do not allow «:» in names.
Reference

Endpoints and claims

EndpointDescription
/.well-known/openid-configurationDiscovery — everything a plugin needs.
/oauth/authorizeSign-in page: response_type=code, client_id, redirect_uri, scope, state, nonce, code_challenge.
/oauth/tokenCode → tokens (authorization_code, refresh_token). The code lives 60 s and works once; access token — 1 hour.
/oauth/userinfoWho signed in (Bearer access token).
/oauth/jwksPublic keys for checking id_token (RS256 and ES256).
/oauth/revoke, /oauth/end_sessionRevoke a token; sign out and return to post_logout_redirect_uri.
ClaimDescription
sub, prizrak_idThe full Prizrak address: name:server. Stable, unique across the federation.
preferred_usernameThe name part of the address (vasya).
name, pictureDisplay name and avatar — only if the person allowed it (scope profile).
home_assertionThe answer of the person’s home server, signed by its federation key (Ed25519, /.well-known/prizrak/server). Optional to check.
nonce, auth_time, at_hashStandard OpenID Connect claims.
Example

Without a plugin — by hand

# 1. Send the person to the sign-in page
https://prizrak.im/oauth/authorize?response_type=code&client_id=pz_XXXX
  &redirect_uri=https%3A%2F%2Fforum.example.com%2Fcallback
  &scope=openid%20profile&state=RANDOM&nonce=RANDOM
  &code_challenge=BASE64URL(SHA256(verifier))&code_challenge_method=S256

# 2. They come back with ?code=…&state=… — exchange the code for tokens
curl -u pz_XXXX:SECRET https://prizrak.im/oauth/token \
  -d grant_type=authorization_code -d code=CODE \
  -d redirect_uri=https://forum.example.com/callback -d code_verifier=VERIFIER
# {"access_token":"…","id_token":"eyJ…","token_type":"Bearer","expires_in":3600}

# 3. Who is it
curl -H "Authorization: Bearer ACCESS_TOKEN" https://prizrak.im/oauth/userinfo
# {"sub":"vasya:ru.prizrak.im","preferred_username":"vasya","name":"Vasya"}
Plugins

Ready-made plugins

Official Prizrak plugins will be published right here. Until then, the standard OpenID Connect plugins of popular platforms already work — just give them the discovery address, client_id and the secret.

📝

WordPress

Plugin «OpenID Connect Generic Client». Login type — button, identity key — sub, nickname — preferred_username.

Works now
☁️

Nextcloud

App «OpenID Connect user backend» (user_oidc): add a provider with the discovery address; unique user ID — sub.

Works now
💬

Discourse

Built-in OpenID Connect plugin: enable it, paste the discovery address, client_id and the secret.

Works now
🍵

Gitea / Forgejo

Site administration → Authentication sources → OAuth2 → provider «OpenID Connect», auto-discovery URL.

Works now
📊

Grafana

Section [auth.generic_oauth]: the authorize, token and userinfo addresses from the table above, scopes openid profile.

Works now
👻

Official plugins

A «Sign in with Prizrak» button with the ghost, one-click setup for WordPress and other platforms, notifications from the website to Prizrak. They will be published on this page.

Coming soon
Security

Honestly about what a website gets

📭

Only who you are

A website learns your address (and name/avatar if allowed). Your chats, contacts and files are end-to-end encrypted and are never given to websites — OAuth doesn’t touch them.

🏠

Your server confirms

prizrak.im accepts an answer only if it is signed by the server from your address: ru.prizrak.im can confirm only *:ru.prizrak.im.

⛔

Blocking fraud

The confirmation window always shows the real domain and the owner of the website. The prizrak.im administrator can block a fraudulent website — its sign-in stops working and its tokens are revoked.

🕑

Short-lived and one-time

A request lives 2 minutes, the code — 60 seconds and works once, access tokens — an hour; refresh tokens rotate on every use and can be revoked from the app.

Your own server

People from any Prizrak server

Your server doesn’t have to become an OAuth server: prizrak.im handles sign-in for the whole federation and asks your server to confirm. What’s needed is a Prizrak server 2.1.68 or newer and the app 2.1.132 (desktop) / 2.1.169 (Android) or newer. Websites registered from any server — through prizrak.im.

A fully closed network without prizrak.im? Any server can become a sign-in server of its own: "oauthProvider": true in the server config — and your own issuer, https://your-domain. Other servers of that network point to it with "oauthProviderDomain": "your-domain". For the public federation this is not needed.

Add «Sign in with Prizrak» to your website

Register the website in the app, paste three values into the plugin — and people from the whole federation can sign in without passwords.