Pocket ID
A simple OIDC provider that authenticates users via passkeys.
Pocket ID is a lightweight, self-hosted OIDC identity provider that uses passkeys (WebAuthn) as the sole authentication method — no passwords. It provides OIDC/OAuth2 endpoints for applications to integrate SSO. Self-hosting means full control over your identity provider without paying for Auth0, Okta, or similar cloud services.
Alternatives considered
Cloud Hosted
| Tool | Open Source | Free Tier | Monthly Cost |
|---|---|---|---|
| Auth0 | No | Limited | From $35/mo |
Self Hosted
| Tool | Open Source | Full Features | Notes |
|---|---|---|---|
| Keycloak | Yes | Yes | Full IAM suite; much heavier |
| Authentik | Yes | Yes | Modern IdP with more auth methods |
Installation
Architecture
- Deployment: Single
pocketiddeployment in thepocketidnamespace - Image:
ghcr.io/pocket-id/pocket-id:v2.5.0(digest-pinned) - Database: CNPG PostgreSQL cluster with Longhorn-encrypted PVCs
- Storage: Longhorn PVC (
pocketid-data) for app files - Networking: ClusterIP service on port 80, HTTPRoute via public gateway
Security
- Runs as
runAsUser: 0,runAsNonRoot: false - Longhorn PVC and CNPG PVCs encrypted at rest via SOPS-managed keys
Updates
Managed by Renovate. Image is digest-pinned.
Data Management
- Database: CNPG PostgreSQL cluster (Longhorn-encrypted PVCs)
- PVC:
pocketid-data(Longhorn-encrypted) for passkey registrations and app files - Backups: k8up
Schedulebacks up CNPG Longhorn PVCs to Hetzner S3. CNPG annotated withk8up.io/backupcommand: pg_dump.
User Management
Pocket ID is the OIDC provider for this cluster — it does not consume OIDC itself. Clients registered include DefectDojo, Gatus, RomM, and others. Users register passkeys via the web UI.
Configuration Management
- SMTP credentials for email notifications from SOPS-encrypted secret (
allinkl-smtp-credentials) - Database connection string injected from CNPG-generated secret
ANALYTICS_DISABLEDand other app settings from env vars
Administration
Usage
Register passkeys via the web UI for passwordless authentication. Add OIDC clients for applications that need SSO. Users authenticate by scanning a QR code or using a device passkey. Email notifications for account events are sent via the configured SMTP server.
Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/pocketid/README.md.
Cluster Deployment
Pocket ID — Talos cluster
Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/pocketid.mdx.
Deviations from defaults
Defaults live in docusaurus/docs/apps/pocketid.mdx — document anything this cluster does differently here, with a one-line reason.
- Image:
ghcr.io/pocket-id/pocket-id:v2.8.0@sha256:a073640418b2cfc8587c488a7270580b3ab95cae2c543f5d64bbbe1fd7ccbae8
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app: pocketid
name: pocketid
namespace: pocketid
spec:
replicas: 1
selector:
matchLabels:
app: pocketid
ingress: public
strategy:
rollingUpdate: null
type: Recreate
template:
metadata:
labels:
app: pocketid
ingress: public
spec:
containers:
- env:
- name: ANALYTICS_DISABLED
value: 'true'
- name: SMTP_TLS
value: starttls
- name: SMTP_HOST
valueFrom:
secretKeyRef:
key: host
name: allinkl-smtp-credentials
- name: SMTP_FROM
valueFrom:
secretKeyRef:
key: from
name: allinkl-smtp-credentials
- name: SMTP_PORT
valueFrom:
secretKeyRef:
key: port
name: allinkl-smtp-credentials
- name: SMTP_USER
valueFrom:
secretKeyRef:
key: username
name: allinkl-smtp-credentials
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: allinkl-smtp-credentials
- name: DB_CONNECTION_STRING
valueFrom:
secretKeyRef:
key: uri
name: cnpg-app
envFrom:
- secretRef:
name: pocketid
image: ghcr.io/pocket-id/pocket-id:v2.8.0@sha256:a073640418b2cfc8587c488a7270580b3ab95cae2c543f5d64bbbe1fd7ccbae8
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 1411
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 2
name: pocketid
ports:
- containerPort: 1411
readinessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 1411
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 2
volumeMounts:
- mountPath: /app/data
name: pocketid-data
securityContext:
seccompProfile:
type: RuntimeDefault
volumes:
- name: pocketid-data
persistentVolumeClaim:
claimName: pocketid-data