How to Use Pocket ID: The Beginner's Guide to Passkey SSO (First Deploy, First OIDC Client, and Your First Connected App)
CodexFuse Team · 2026-11-01T07:07:24.029Z · 16 min read
Pocket ID gives your homelab or small team one passwordless login: passkeys only, no password resets. Deploy it with Docker Compose, finish the /setup passkey-first rule, add users and groups, create your first OIDC client, and connect a real app — the complete beginner guide.
How to Use Pocket ID: The Beginner's Guide to Passkey SSO (First Deploy, First OIDC Client, and Your First Connected App)
Learning how to use Pocket ID is the fastest way to give your self-hosted apps one passwordless login. Instead of a username and password on every service, Pocket ID becomes your single sign-on provider: you authenticate once with a passkey — your fingerprint, face, or a hardware key — and every connected app lets you in. This Pocket ID tutorial walks the full beginner arc: deploying it with Docker Compose, finishing the passkey-first setup before anything else, adding users and groups, creating your first OIDC client, and connecting a real app, all in one sitting. It is a Pocket ID for beginners walkthrough that assumes nothing about OIDC — every acronym is explained when it appears. If you already have a Docker beginner guide under your belt, you will be done in about an hour.
What Is Pocket ID?
Pocket ID is a self-hosted, OpenID Connect Certified provider that lets users sign in to your applications with passkeys instead of passwords. It is one small service, one database file, one Docker container — and it answers the question every homelab and small team eventually asks: can I have one login for everything without running a full identity platform? Pocket ID's answer is deliberately narrow: passkeys only, no password logins, no LDAP, no SAML. That narrowness is the whole point. The project is open source under the BSD-2-Clause license, lives at pocket-id/pocket-id on GitHub (about 9,837 stars, created August 2024, very actively pushed), and the current release line is v2, with v2.19.1 published in October 2026.
The Pocket ID team describes the goal in one sentence: be simple and easy to use where providers like Keycloak or ORY Hydra are too complex for simple use cases. And the passkey-first design is not a gimmick — passkeys are phishing-resistant, there is no password to leak, and one YubiKey can log you in to every self-hosted service you own.
Pocket ID vs Authentik: Which One Do You Actually Need?
Pick Pocket ID if you want passkey sign-in for your apps with the smallest possible setup; pick Authentik if you need full SSO with LDAP, SAML, and policy-based access control. This is the draw-the-line question everyone hits, so answer it before you deploy. Pocket ID does one thing — passkey-first OIDC logins. Authentik does everything — OAuth2, LDAP, SAML, SCIM, application-level access policies — at the cost of a genuinely complex first deployment.
Read the Authentik beginner guide if your situation needs the big platform: multiple identity backends, per-app policy rules, or enterprise-style user management. Stay here if your situation is simpler: a homelab or small team, a handful of apps, and the desire to stop typing passwords without learning an identity suite. The rest of this guide assumes the simpler path.
What You Need Before You Deploy Pocket ID
You need a server running Docker and Docker Compose, a domain name, and HTTPS on that domain. The domain and HTTPS are non-negotiable: browsers only allow passkey registration on secure origins, so Pocket ID behind plain HTTP cannot register a single passkey (localhost is the one exception, fine for try-outs). Something like id.example.com pointing at your server is the classic shape.
If the server part is new to you, start with our what is VPS hosting primer and the Docker beginner guide, then come back. You will also want a reverse proxy in front of Pocket ID for TLS — Caddy is the shortest path there, and our Caddy beginner guide covers exactly this pattern.
How Do You Install Pocket ID with Docker?
The official Pocket ID Docker install is the one the documentation maintains, so match it exactly rather than improvising your own compose file.
You install Pocket ID with one Docker Compose service using the official compose file, an .env with two required variables, and a single command. Here is the complete first-run arc:
- Grab the official files. Download docker-compose.yml and the .env example from the pocket-id/pocket-id repository's v2 branch into a directory on your server.
- Set the two required variables. In .env, set APP_URL to your public address (APP_URL=https://id.example.com) and set ENCRYPTION_KEY. Generate it with
openssl rand -base64 32; the docs require at least 16 characters, and the recommended path is ENCRYPTION_KEY_FILE pointing at a file instead. Note: v2 uses APP_URL, not the older PUBLIC_APP_URL name. - Review the optional variables. TRUST_PROXY (set true when behind a reverse proxy so Pocket ID sees the real client address), PUID and PGID (match them to your user so the data directory stays writable), and MAXMIND_LICENSE_KEY (empty by default — it powers geolocation lookups you probably do not need yet).
- Start the service. Run
docker compose up -d. Pocket ID listens on port 1411 inside its container and keeps its built-in SQLite database and uploads in ./data, mapped to /app/data — one file you can back up. - Wait, then open the setup page. Browse to https://id.example.com/setup. This page only works until the first account exists, so the moment you register, it is gone — by design.
- Register the admin account. Enter a username, email address, first name and last name, then click Sign Up.
- Add your passkey immediately. Pocket ID prompts for passkey setup right after signup — click "Add Passkey" and follow the browser prompt (fingerprint, face, hardware key, or a passkey in Bitwarden, 1Password, iCloud Keychain, or Google Password Manager). This passkey is now your only way back in.
- Confirm you can sign back in. Sign out and sign in again with the passkey. If this works, your foundation is solid.
- Note the image you just used. The v2 images are published as pocketid/pocket-id:v2 on Docker Hub and ghcr.io/pocket-id/pocket-id:v2. Older guides reference stonith404/pocket-id — that was the v1 image name, and it should not be used for new installs.
- Back up ./data. Your users, passkeys, groups and clients all live in that one directory. Copy it somewhere off the server before you do anything else.
If hand-writing compose files is not your favorite, the Docker Compose generator can scaffold the service shape — but the official file above is already minimal, and matching the official file exactly is the safest start.
| Environment variable | Required? | What it does |
|---|---|---|
| APP_URL | Yes | The public address of your instance, e.g. https://id.example.com — becomes the OIDC issuer URL |
| ENCRYPTION_KEY | Yes | Protects stored secrets; generate with openssl rand -base64 32 (minimum 16 chars) |
| ENCRYPTION_KEY_FILE | Alternative | Path to a file containing the encryption key — the recommended approach |
| TRUST_PROXY | Optional | Set true behind a reverse proxy so Pocket ID trusts X-Forwarded headers |
| PUID / PGID | Optional | User and group IDs for file ownership in the data directory |
| MAXMIND_LICENSE_KEY | Optional | Powers geolocation lookups; empty by default |
The Passkey-First Rule: Finish Setup Before Anything Else
The passkey-first rule is this: Pocket ID has no password logins at all, so the passkey you register at /setup is your only way back in — skip it and you are locked out of your own instance. This is the number-one beginner trap and the caution every experienced user repeats. Pocket ID only supports passkey authentication, full stop. There is no "reset password" email, no admin console bypass. If you finish the signup form and walk away before clicking "Add Passkey," you have an admin account you cannot log into.
The same rule applies to everyone you add later: only the user can add a passkey to their own account, so onboarding a new person always takes two steps — create the account, then get them in once so they can add their passkey. The official docs are explicit about this, and every beginner arc (the Appwrite integration guide, the hands-on homelab review) hits the same beat: register the admin passkey during setup, immediately, before you click anything else.
How Do You Add Users and Groups?
On your self hosted Pocket ID instance, you add users four ways — by hand, through signups, through the API, or with login codes and signup links — and you organize them into groups that decide who may sign in to which app. Open Administration → Users and click Add User, fill in username, email and name, and the person gets an account. Then the first-passkey problem: hand them a one-time login code. In Administration → Users, open the user's ⋯ menu, choose Login Code, pick a short lifetime and click Show Code. The user enters it under Alternative Sign In Methods → Login Code (or scans the QR), signs in once, and adds their passkey. Treat a login code like a passkey until it expires: send it only to the person, keep the lifetime short. With SMTP configured and "Email Login Code from Admin" turned on, you can mail the code instead of showing it on screen.
For self-service onboarding, use signup links: under Application Configuration → User Creation, set Enable User Signups to "Signup with token," then in Administration → Users open the Add User menu and choose Create Signup Token. You control when the token expires, how many accounts it may create, and which groups new accounts join. One warning from the official docs: "Open Signup" lets anyone who reaches your instance create an account — only use it when the instance is not public. Leave that on behind a public domain and strangers will register on your identity provider.
Groups are the access-control layer. You mark users as admin with the Admin Privileges toggle (which unlocks the admin pages) and freeze people with Account Disabled (blocks sign-in without deleting them). Groups decide which OIDC clients a member may use, and apps receive the groups in the groups claim so they can assign roles on their side — Jellyfin, Immich, and the nearly one hundred client examples in the official docs all lean on this. Users who need several devices add several passkeys under My Account, one per device or password manager.
How Do You Create Your First OIDC Client?
You create your first Pocket ID OIDC client under Administration → OIDC Clients, give it the app's callback URL, and hand the app three values: the client ID, the client secret, and the discovery URL. Every app that signs in with Pocket ID is an OIDC client. The exact shape depends on the app, but the official docs walk the shared steps with Immich at https://photos.example.com, and there are client examples for nearly a hundred apps.
Step one is finding the app's callback URL — sometimes called the redirect URI — in the app's own OIDC documentation. Pocket ID sends users back only to URLs you list here, so a typo in this field is the single most common reason a first sign-in fails. Step two is the form itself: enter a name, pick the client type, and add the callback URL. Then click Create, and the client's page shows the values the app needs.
The client type is the one decision that matters:
| Confidential client | Public client | |
|---|---|---|
| What it is | An app with a backend that can hold a secret | A single-page, mobile or desktop app that cannot keep a secret |
| Auth method | Signs requests with the client secret | Uses PKCE instead of a secret |
| Typical pick | Immich, Jellyfin, RomM, most server apps | Mobile apps, SPAs, desktop clients |
Most self-hosted apps have a backend, so most of your clients will be confidential. One caution from the official docs worth memorizing: the client secret is shown once — copy it into the app's settings immediately, because you cannot reveal it again later.
The Access-Tab Rule: Nobody Gets In Until You Allow Them
A new OIDC client lets nobody in until you choose who may use it. This is the access-tab rule, and it surprises every beginner exactly once. On the client's Access tab you either select the groups whose members may sign in, or choose All Users. Everyone else gets "You are not allowed to access this service" when they try. Combined with groups, this is your whole authorization story: put your family in a Family group, give the media apps to Family, and nobody else even sees a login button that works.
One practical detail from the official docs: the first time you sign in to a client, Pocket ID asks whether to share your details with it — it remembers the answer and only asks again when the app requests more than before. Users can revoke that consent under My Apps, and for trusted first-party apps you can skip the screen entirely with "Skip Consent Screen" on the client's General tab.
How Do You Connect a Real App to Pocket ID?
You connect a real app by creating the client, copying its ID, secret and discovery URL into the app's OIDC or SSO settings, and choosing who may sign in on the Access tab. Apps name the fields differently, but they map to the same values every time:
| The app asks for | Enter |
|---|---|
| Issuer, provider URL or authority | Your APP_URL, e.g. https://id.example.com |
| Discovery, well-known or configuration URL | https://id.example.com/.well-known/openid-configuration |
| Client ID | The Client ID from the client's page |
| Client secret | The Client secret — nothing for a public client |
| Scopes | openid profile email, plus groups if the app assigns roles by group |
Two gotchas live in this section. First, the issuer URL must work from the app's container too, not only in your browser — if the app fetches tokens from Pocket ID directly, its network has to reach your APP_URL. When apps live on the same Docker network but reach Pocket ID at a different internal address, the docs point at INTERNAL_APP_URL for exactly that. Second, some apps need "Emails Verified" ticked in Application Configuration before they will accept the login — the RomM integration docs call this out explicitly, and it is worth checking first when a well-configured app still refuses the session. RomM's side of the wiring is also a clean reference: enable OIDC, set the provider name to pocketid, add the client ID and redirect URI (its callback is https://your-host/api/oauth/openid), and make sure your RomM profile email matches your Pocket ID email exactly.
The official docs' client examples cover nearly a hundred apps — including Jellyfin, the media-server example everyone asks about — so your app is probably one search away from an exact walkthrough. If you would rather wire a developer platform, the Appwrite integration guide shows the same flow end to end: Pocket ID as the OIDC provider behind Appwrite's universal OIDC adapter, so users get "Sign in with Pocket ID" and land back in the app's dashboard.
What If an App Does Not Support OIDC?
When an app does not speak OIDC natively, you put an auth proxy in front of it and let the proxy speak to Pocket ID. Pocket ID alone is not enough for these apps — this is the main limitation the hands-on homelab review found — but the pattern is well worn: a Pocket ID OAuth2 Proxy pairing, where OAuth2 Proxy sits in front of the app, talks OIDC to Pocket ID on one side, and presents the app with an authenticated session on the other. The reviewer tested it with a whoami app: click "Sign in with Pocket ID," complete the passkey prompt, and land in the app. For simpler needs, tools like Tinyauth do the same job with less ceremony.
The honest summary: if your apps support OIDC natively, Pocket ID makes the whole thing trivial. If they do not, budget the proxy as part of the plan rather than discovering it mid-deployment.
Pocket ID vs Authentik vs Keycloak: The Lightweight OIDC Provider Choice
Pocket ID is the lightweight OIDC provider lane: one container, passkeys only, minimal configuration. If you are shopping the self hosted OIDC provider field, the honest comparison looks like this:
| Pocket ID | Authentik | Keycloak | |
|---|---|---|---|
| Core idea | Passkey-first OIDC, nothing else | Full identity platform: OAuth2, LDAP, SAML, policies | Enterprise identity and access management |
| Login methods | Passkeys only | Passwords, MFA, social, LDAP, more | Passwords, MFA, social, Kerberos, more |
| Deploy size | One service, built-in SQLite | Multiple services, PostgreSQL + Redis | Java stack, database required |
| Best for | Homelab or small team wanting one passwordless login | Teams needing full SSO with policies | Enterprises with complex identity needs |
The trap to avoid is choosing the biggest platform "just in case." A homelab does not need Keycloak's enterprise surface, and Authentik's power comes with real operational weight. Pocket ID's bet is that most self-hosters need about ten percent of an identity platform — the OIDC provider part — done well, with passkeys instead of passwords. For that job, it is the right-sized tool.
Common First-Week Problems
Sign-in fails right after configuring the app. Check the callback URL character for character against the app's actual redirect URI — the official docs' troubleshooting section names this as the usual cause, and it is the fix most of the time.
Passkey registration never offers a passkey prompt. You are not on HTTPS. Browsers only allow passkey ceremonies on secure origins. localhost is the exception for try-outs; every real deployment needs TLS on its domain.
The app cannot reach Pocket ID from inside Docker. The issuer URL must resolve and connect from the app's container, not just your browser. If internal and external addresses differ, set INTERNAL_APP_URL so the token, userinfo and JWKS endpoints answer at the address the app can reach.
Everything configured, but the app rejects the login. Check "Emails Verified" in Application Configuration — some apps require the verified claim before accepting the session.
You lost the client secret. It is shown once at creation. There is no reveal button later — create a new client or regenerate per the docs' flow, then update the app.
Sources
- Pocket ID official documentation — Installation (docs/setup/installation) — pocket-id.org — fetched 2026-11-01.
- Pocket ID official documentation — Connect an app with OpenID Connect (docs/setup/connect-an-app) — pocket-id.org — fetched 2026-11-01.
- Pocket ID official documentation — Add users and set up their passkeys (docs/setup/user-management) — pocket-id.org — fetched 2026-11-01.
- Pocket ID official documentation — Jellyfin client example (docs/client-examples/jellyfin) — pocket-id.org — fetched 2026-11-01.
- GitHub — pocket-id/pocket-id releases (v2.19.1, published 2026-10-22) — api.github.com — fetched 2026-11-01.
- GitHub — pocket-id/pocket-id repository (~9,837 stars, BSD-2-Clause, created 2024-08-11) — api.github.com — fetched 2026-11-01.
- GitHub — pocket-id/pocket-id v2 branch docker-compose.yml (image pocketid/pocket-id:v2, port 1411, ./data:/app/data) — raw.githubusercontent.com — fetched 2026-11-01.
- GitHub — pocket-id/pocket-id v2 branch .env.example (APP_URL, ENCRYPTION_KEY, TRUST_PROXY, PUID/PGID) — raw.githubusercontent.com — fetched 2026-11-01.
- virtualizationhowto.com — "I Tried Pocket ID to Simplify Home Lab Logins" (2026-10-19) — OAuth2 Proxy + whoami test arc, passkey-only limitation — fetched 2026-11-01.
- matejbaco.eu — "Passkey authentication in any app with Pocket ID and Appwrite" — OIDC adapter integration arc — fetched 2026-11-01.
- thesynack.com — "Securing Self-Hosted Apps with Pocket ID / OAuth2-Proxy" — reverse-proxy security arc — fetched 2026-11-01.
- docs.romm.app — "OIDC Setup With PocketID" — RomM env vars, Emails Verified requirement — fetched 2026-11-01.
- docs.netbird.io — Pocket ID as a self-hosted identity provider (updated 2026-06-03) — fetched 2026-11-01.
- blackvoid.club — Pocket ID passkey OIDC provider on Synology DSM (512 days) — fetched 2026-11-01.
Frequently Asked Questions
Is Pocket ID free and open source?
Yes. Pocket ID is open source under the BSD-2-Clause license, hosted at pocket-id/pocket-id on GitHub, and free to self-host with no paid tiers gating the OIDC provider itself. You bring your own server and domain.
Does Pocket ID support passwords?
No. Pocket ID supports passkeys only — your fingerprint, face, hardware key, or a passkey in a password manager. There is no password login and no password reset. That is the design, and it is why the admin passkey at /setup must be registered before anything else.
Does Pocket ID need a database?
No separate database. Pocket ID ships with a built-in SQLite database stored in its data directory (./data in the official compose file), so one backup of that directory covers users, passkeys, groups and clients.
Can Pocket ID work with apps that do not support OIDC?
Not directly — but you can put an auth proxy like OAuth2 Proxy or Tinyauth in front of such an app. The proxy speaks OIDC to Pocket ID and hands the app an authenticated session, which is the standard pattern for apps without native OIDC support.
How is Pocket ID different from Authentik?
Pocket ID is a single-purpose passkey-first OIDC provider: one container, minimal config, no passwords. Authentik is a full identity platform with OAuth2, LDAP, SAML, and access policies, at the cost of a heavier deployment. Choose Pocket ID for simple passwordless SSO; choose Authentik when you need the full SSO suite.