Login & security
Node64 is secure out of the box: no default password, passwords hashed with argon2id, encrypted secrets and an audit log. On top of that you can add two-factor login, passkeys, single sign-on via OpenID Connect, or forward auth through your reverse proxy.
Login and admin account
Node64 has one admin account, which you create yourself on first start. There is no default password. The setup wizard at /setup only appears as long as no user exists.
- Username: 3 to 64 characters – letters, digits, dot, hyphen and underscore (default
admin). - Password: at least 10 characters. Only an argon2id hash is stored.
- For automated installs:
NODE64_ADMIN_USERandNODE64_ADMIN_PASSWORDcreate the account on the very first start and are ignored afterwards. See Configuration.
You can change language, time zone and password at any time under Settings. The local user with a password always remains the foundation – every other login method only adds to it.
Sessions and brute-force protection
| What | Value |
|---|---|
| Idle session | expires after 12 hours |
| Maximum session length | 7 days, then you log in again |
| Cookies | HttpOnly, SameSite=Lax, plus Secure over HTTPS |
| Failed logins | 5 attempts per IP and per username, then one new attempt every 30 seconds |
| Forms | CSRF protection for every request that changes something |
| Web interface | security headers, a Content Security Policy without external sources, TLS 1.2 or newer |
Two-factor login (TOTP)
With two-factor login enabled, Node64 asks for a code from an authenticator app after your password – for example Aegis, 2FAS or Google Authenticator.
- Open Settings → Two-factor authentication (
/settings/2fa) and click Set up. - Scan the QR code with your app, or type in the secret manually.
- Enter the code from the app and enable two-factor login. All other sessions are signed out.
- Store the eight recovery codes somewhere safe. Each code works exactly once and is shown only this one time.
On the login page you can enter a recovery code instead of the app code. If a code is rejected, check the device clock first – TOTP codes depend on the time.
Forgot your password: emergency access
Forgot or lost your password? There is deliberately no "forgot password" e-mail – Node64 runs on your own hardware and needs no mail server. Instead, you set a new password with a command in the running container. Only someone with access to the Docker host can do that – you, not someone on the network.
- Run the command on the Docker host
bashWith docker compose:docker exec node64 /node64 reset-passworddocker compose exec node /node64 reset-password(replacenodewith the service name from your compose file). - Read the new password
The command generates a random 20-character password and shows it once. All existing sessions are ended. - Log in and change the password
Log in with the new password and set your own under Settings.
| Option | Effect |
|---|---|
-user NAME | choose the user (only needed if there are several) |
-password 'NEW' | your own password instead of a random one, at least 10 characters – but it then ends up in your shell history |
-disable-2fa | also switches off two-factor login if both the authenticator app and the recovery codes are gone |
- The node keeps running; data, checks and settings stay unchanged.
- The action is recorded in the audit log ("password changed", note "reset-password (command line)").
- Passkeys and linked SSO accounts are kept – if set up, they get you in without a password as well.
Available from the Node64 version that includes this command; update older versions first (see Update). If your container has a different name, replace node64 with it (docker ps shows it).
Passkeys
Passkeys let you log in without a password and without a username: click Sign in with a passkey on the login page and confirm with your fingerprint, Face ID, device PIN or a security key such as a YubiKey.
- Requirement: the node must be opened via HTTPS with a host name, for example
https://node64.example.com. Browsers don't allow passkeys on an IP address. The only exception ishttp://localhost. - A passkey only works for the host name it was created under.
- Create them under Settings → Sign-in → Passkeys (
/settings/login). You can register several per user, e.g. your phone and a YubiKey. - A passkey is a complete login on its own, not a second factor on top of your password. Password and app-based 2FA stay available alongside it.
The easiest way to get your own name with a valid certificate for the web interface is the central certificate management – for example with a free domain from ipv64.net.
Single sign-on via OpenID Connect
If you already run an identity provider in your homelab, you can use it to log in to Node64 too. Any OIDC provider works, such as Authelia, Authentik, Keycloak, Pocket ID, Zitadel or Kanidm.
Only someone who has linked their SSO account to the local user beforehand can log in. Users that exist at the provider do not get an account in Node64 automatically. For this kind of login, the provider handles the second factor.
Setting it up
- Create a confidential client at your provider: authorization code flow with PKCE, scopes
openid profile email. - Use the address Node64 shows under Settings → Sign-in as the redirect URI. It looks like
https://<node>/login/oidc/callback. - Enter the issuer URL, client ID and client secret in Node64. The secret is stored encrypted.
- In your own user, under Linked accounts, click Link with … and sign in to the provider once.
- From now on the login page shows Sign in with ….
| Field in Node64 | Meaning |
|---|---|
| Issuer URL | address of the provider, e.g. https://auth.example.com |
| Client ID / client secret | from the provider; the saved secret stays hidden (leave empty to keep it) |
| Button label | text on the login page; empty = the provider's host name |
| Scopes | default openid profile email; Node64 adds openid itself if it's missing |
| External address of this node (optional) | only needed if the node is reachable under a different address behind a reverse proxy; empty = the address from the browser |
The flow is protected with state, nonce and PKCE. Every SSO login is recorded in the audit log.
Example: Authelia
identity_providers:
oidc:
clients:
- client_id: node64
client_name: Node64
client_secret: '$pbkdf2-sha512$...' # hash of the secret you enter in Node64
public: false
authorization_policy: two_factor
require_pkce: true
pkce_challenge_method: S256
redirect_uris: ['https://node64.example.com/login/oidc/callback']
scopes: [openid, profile, email]
token_endpoint_auth_method: client_secret_basicThe issuer URL in Node64 is then your Authelia address, e.g. https://auth.example.com.
Example: Authentik
- Create an OAuth2/OpenID provider of type Confidential and enter the redirect URI from Node64.
- Create an application with the slug
node64and attach the provider. - Issuer URL in Node64:
https://authentik.example.com/application/o/node64/
Example: Keycloak
The same basics apply to Keycloak: a client with client authentication turned on (confidential), the authorization code flow, the redirect URI https://node64.example.com/login/oidc/callback and the scopes openid profile email. The issuer URL is typically the address of your realm, such as https://keycloak.example.com/realms/homelab.
Forward auth via your reverse proxy
If Node64 sits behind Traefik, Caddy or Nginx with Authelia or Authentik doing forward auth, the proxy passes the signed-in user in an HTTP header – Remote-User by default. Node64 then logs you in without showing its own login page.
# Forward auth: the proxy tells Node64 who is signed in Browser Reverse proxy Node64 ┌────────┐ HTTPS ┌─────────────────────┐ Remote-User ┌────────────────────┐ │ You │ ──────► │ Traefik/Caddy/Nginx │ ──────────► │ 1. connection from │ └────────┘ │ + Authelia or │ admin │ proxy network? │ │ Authentik │ │ 2. local user │ │ (login + 2FA) │ │ "admin" exists? │ └─────────────────────┘ └────────────────────┘ # Direct, without the proxy: not from the proxy network, header ignored Browser ─────────────────────────────────────────► Node64 (normal login)
- Off by default. Turn it on under Settings → Sign-in → Forward auth via the reverse proxy.
- Trusted proxy networks: the header is only accepted on connections from the proxy addresses you enter – single IPs or networks in CIDR notation, separated by commas. Node64 checks the address of the connection itself, never
X-Forwarded-For. "All addresses" (0.0.0.0/0or::/0) is blocked. The page shows which address your current request comes from. - Exactly one user: the name in the header must match the local username exactly, so use the same name in Authelia or Authentik as in Node64.
- Checked on every request: sign out at the proxy and you're signed out of Node64 as well.
- The header name is configurable in case your proxy uses a different one.
- The proxy must set the header itself and overwrite any value sent by the browser. Authelia and Authentik forward auth do exactly that.
- If the node is also reachable directly, that's fine: direct requests don't come from the proxy address and end up at the normal login.
Anyone connecting from a trusted network could claim to be any user. Only enter your proxy's address, for example 192.0.2.5 or the proxy's Docker network.
API keys
For scripts, automations and Prometheus you create API keys. You'll find them under the API menu item (page /api/docs, section API keys).
- A key starts with
node64_and is shown only once. Node64 stores just a hash, plus a name, a short hint and "last used". - Send it as the header
Authorization: Bearer node64_…– it only works for paths under/api/. - A key acts with the permissions of your user. So create one key per purpose (e.g.
prometheus,backup-script) and delete it once you no longer need it. - Node64 slows down wrong keys per IP: after 5 failed attempts, only one attempt every 30 seconds.
More in the local API docs.
Audit log
The audit log at /audit records who changed what and when: time, actor, action, target, details, IP address and origin. Every login is listed; for SSO, passkey and forward auth it also shows how the login came in (sso …, passkey, forward-auth …). Actions made with an API key carry the origin api:<key name>.
How long entries are kept is set under Settings → Data & backup (Keep audit log): 90, 180, 365 days (default), 730 days or unlimited. Older entries – including calls via the AI interface – are deleted.
You can filter by area:
| Area | Contains, for example |
|---|---|
login | setup, login and logout, 2FA, passkeys, SSO, API keys |
settings | settings, logging, notifications, channels, modules, backup, configuration |
healthchecks | creating, changing and deleting checks |
dyndns, cdn64, dns64 | changes in the respective modules |
certs | certificates, including downloads of private keys |
sync | the ipv64.net connection and the cluster |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"http://node64.lan:8080/api/audit?area=login&limit=50"Logs and log level
Under Logs (/logs) you see the last 2000 lines right in the web interface and can download them. Node64 also writes everything to standard output, so it shows up in docker logs node64.
- Levels:
debug,info(default),warn,error. At startup you set the level withNODE64_LOG_LEVELand the format withNODE64_LOG_FORMAT(textorjson). - Change it at runtime: under Settings → Logging, globally or per area (module).
- Automatic reset: a changed level falls back after 30, 60 (default) or 240 minutes – or stays if you pick "never". That way debug logging doesn't keep running by accident.
- Secrets stay masked: values that look like a password, token or key never appear in plain text in the log, not even at debug level.
- Via the API:
GET /api/logsas well asGETandPUT /api/logging.
Encrypted secrets (secret.key)
Channel tokens, SMTP passwords, the OIDC secret, the ipv64 API key and private certificate keys are stored in the database encrypted with AES-256-GCM. The key for this is the file /data/secret.key, which Node64 creates on first start.
Without secret.key the secrets in the database can no longer be read. The plain database download does not contain the key. So back up the whole /data volume or use the encrypted backup archive – see Update & backup.
Node64 sends no telemetry. The check for new versions stays off until you turn it on, and then it only fetches a version file from ipv64.net.
Security tips
- Use a long, unique password plus two-factor login or a passkey.
- Don't expose the web interface to the internet. Port 8080 belongs in your home network. For remote access, use a VPN or put a reverse proxy with forward auth or SSO in front.
- HTTPS with your own name instead of a self-signed certificate – passkeys need it anyway. Node64 speaks HTTP and HTTPS on the same port.
- Behind your own reverse proxy, set
NODE64_TRUST_PROXY=true. Node64 then sees the real client IP (audit log, rate limiting) and recognises HTTPS and the host name for passkeys and the SSO redirect. Without your own proxy, leave it off. - One API key per purpose – and delete keys you no longer need.
- Only mount the Docker socket if you need it. Node64 only sends read requests, but the socket still grants a lot of power. A socket proxy that only allows container queries is the safer choice (see Health checks).
- Keep the container lean: Node64 runs as non-root (UID 65532) in an image without an operating system or shell, and optionally with a read-only root file system. Only
/datahas to be writable. - Check the audit log now and then – especially after unexpected logins. If Honeypot64 is running, it reports attacks on the login itself.
- Keep backups including
secret.keysomewhere other than the server itself.
Something unclear, missing, or a question about Node64? Ask in the official forum v64.tech.