Form K-00 · Installation
Install
One container, one volume, one port. All data lives in a single SQLite file.
Docker (recommended)
docker run -d --name keeyo \
-p 5390:5390 \
-v keeyo-data:/data \
--restart unless-stopped \
ghcr.io/ans-ib/keeyo:latest
Docker Compose
services:
keeyo:
image: ghcr.io/ans-ib/keeyo:latest
container_name: keeyo
restart: unless-stopped
ports:
- "5390:5390"
volumes:
- keeyo-data:/data
volumes:
keeyo-data:
Then open http://localhost:5390. Your first visit creates the admin account — there is no default password and no open registration.
Build from source
git clone https://github.com/ans-ib/keeyo.git && cd keeyo
docker compose up -d
Without Docker
Needs Node.js 22.13+ — Keeyo uses Node's built-in SQLite, so there are no native modules to compile.
git clone https://github.com/ans-ib/keeyo.git && cd keeyo
npm install
npm start # http://localhost:5390, data in ./data
Configuration
| Variable | Default | What it does |
|---|---|---|
PORT | 5390 | Web server port. |
DATA_DIR | /data | Where the SQLite database lives. |
SESSION_TTL_DAYS | 30 | How long sign-ins last. |
REGISTRY_REFRESH_DAYS | 7 | How often the FIDO device registry is re-fetched. |
KEEYO_OFFLINE | unset | Set 1 to block all outbound requests (registry updates off). |
TRUST_PROXY | unset | Set 1 only behind a reverse proxy so X-Forwarded-* headers are honored. |
KEEYO_DISABLE_MFA | unset | Set 1 to skip every sign-in second factor — security keys and authenticator codes (lockout recovery). |
Reverse proxy & HTTPS
Keeyo speaks plain HTTP; put your reverse proxy in front for TLS and set TRUST_PROXY=1. Caddy example:
keys.example.com {
reverse_proxy keeyo:5390
}
⚠HTTPS matters more than usual here. The WebAuthn features — key scanning, identification, tap-to-reveal, security-key login — only work from
localhost or an HTTPS origin. On a plain-HTTP LAN IP they politely disable themselves. Browsers also refuse WebAuthn on raw IP addresses, so use a hostname.Backups
- Everything: back up the
/datavolume — the SQLite file is the complete state, file attachments included. - Portable: Settings → Account → Export data gives a JSON file with keys, services, registrations, catalog and secret notes (in plain text — guard it). Attachments are not in the JSON.
- Human-readable: CSV export and a printable register sheet exist for paper people.
Locked out?
On the server (or in the container):
docker exec -it keeyo node scripts/reset-password.js <username> <new-password>
This resets the password, signs out all sessions and removes every second factor on the account — sign-in security keys, the authenticator app, and recovery codes. Alternatively, start Keeyo once with KEEYO_DISABLE_MFA=1 to skip the second factor.