← Časté otázky

Časté otázky sú napísané v angličtine a holandčine; zobrazujú sa v angličtine.

Časté otázky

Admin page (admin.euzos.eu)

FAQ › Profile server › Admin page · Nederlands

What is it?

The admin page is the web administration of the profile server, next to the CLI. It lives on a domain of its own: https://admin.euzos.eu for production (the sandbox has its own admin domain); / redirects to /beheer. Only accounts with the role beheerder (admin) can log in, with e-mail address and password, confirmed in the EUZOS app on a phone paired with that admin account (no TOTP or external authenticator app). It is own code (server/profile/src/admin_page/), works without JavaScript, and is only reachable from the IP allow list.

How do I…?

How do I make someone an admin?

On the VPS: euzos-profielserver admin-create <email> (an existing, active account). admins lists the admins and how many phones each has paired; admin-delete <email> removes the role. The admin pairs a phone in the EUZOS app like any user.

How do I log in?

  1. Open https://admin.euzos.eu/ (from an address on the allow list), enter e-mail address and password (POST /beheer/inloggen).
  2. The page shows a QR code with https://admin.euzos.eu/b/<id> and a 6-digit pairing code, and refreshes every 2 s.
  3. Scan it with the EUZOS app on your paired phone; the app shows "Log in to admin from <IP>" ("Inloggen op beheer vanaf <IP>") with the same code. Confirm with Face ID / fingerprint.
  4. The next refresh of the same browser logs you in.

Without a paired phone you cannot log in (the page says so after the correct password). Cancel on the page (POST /beheer/annuleer) or Decline in the app aborts.

How do I log out?

The logout button (POST /beheer/uit). A session also ends after 15 minutes without a click, after 4 hours in any case, after a server restart, or when the account is no longer an active admin.

What can I do on the admin page?

Page (path under /beheer/)WhatCLI counterpart
Dashboard (/beheer)counts: accounts per status, admins, phones, PC sessions, apps, admin log in 24 husers, devices, pc-sessions, apps
Accounts (accounts, accounts?q=)search, create (accounts/nieuw)users, user-create
Account (accounts/<id>)data; block/unblock, password (optionally revoke phones), change address, set/remove the admin policy beheer=, revoke phones, log out PCs, vault info and vault log, delete (GDPR, two steps)user-block, user-unblock, password, user-email, admin-policy, vault, user-delete
PC sessions (pcsessies)all logged-in PCs, log out (pcsessies/afmelden)pc-sessions
Phones (telefoons)all paired phones, revoke (telefoons/intrek)devices, device-revoke
App catalog (apps)list, set (apps/zet), delete (apps/wis)apps, app-set, app-delete
Download tokens (downloadtokens)record a revocation request (downloadtokens/intrek); tokens and revocations from the admin logdownload-token
Admin log (log)the last 500 lines, with who did itadmin-log
Server status (status)environment, domain, version, schema, signing key, vault, mail, flags, sessionskey

Why can't I block or delete my own account?

On their own account an admin cannot block, unblock, change password or address, or delete. That way nobody locks themselves out by accident; use the CLI or another admin.

How do I delete an account (GDPR) on the page?

On the account page: type the address again, then on a separate page "Yes, delete permanently" ("Ja, definitief wissen"; a one-time token valid for 5 minutes). Exactly what user-delete does then happens.

How do I revoke a download token from the page?

The page records the request in the admin log (downloadtoken-intrek …) and shows the command for the package server: sudo euzos-download revoke <jti> [comment]. The blocklist lives on the package server, not on the profile server. (A direct revoke endpoint on the package server is a proposal for later, planned.)

Why do I get 404 on the admin domain?

You are not on the allow list (Caddy answers 404 for the whole admin domain from outside the list, except the two app-link files), or admin_page = no (the default in production until switched on), or admin_domain is not set.

Details

Login rules: one error message for everything (no enumeration); throttling 10 attempts per network (IPv6 per /64 and /48) and 5 per account per quarter of an hour; Argon2 through the same gate as the rest of the server. The waiting request is valid at most 2 minutes, single use, bound to the browser (cookie __Host-euzos_beheer_wacht, only its hash on the server) and the IP address. Only phones of that same account count; another phone gets 410. The signed message is EUZOS-beheer-v1, so a PC-login signature never counts for admin and vice versa.

Session: 256-bit token in the cookie __Host-euzos_beheer (Secure, HttpOnly, SameSite=Strict), hash in memory only, bound to the IP; at most 64 sessions at once.

CSRF: every POST under /beheer/ needs Sec-Fetch-Site: same-origin or an Origin of the admin domain, and the session's CSRF token in the form. The login form uses a double-submit cookie (__Host-euzos_beheer_inlog). Redirects only go to paths under /beheer. Strict CSP (script-src 'none').

Domains: on the admin domain only /beheer…, /b/<id> and the two /.well-known/ files answer; on the profile domain GET /beheer… gives a 308 to the admin domain (until 26-10-2027, then 404). The app API for confirming (/api/app/v2/admin/…) stays on the profile domain, because the app only talks to its own pinned server.

Admin log: every action goes into the table admin_log with the same (Dutch) action names as the CLI (gebruiker-blokkeer, wachtwoord, app-zet, …), plus beheer-inloggen, beheer-inloggen mislukt, beheer-uitloggen, pc-afmelden <ref>, apparaat-intrek <id>, downloadtoken-intrek …. The column admin_id is the admin's account id (NULL = the CLI).

Planned (plan B): a separate admin VPS for admin.euzos.eu that calls a shielded admin API on the profile server (docs/ADMIN-PAGE.md, "Plan B").

Reference

CLI commands

CommandArgumentsWhat it does
admin-create<email>give an active account the role beheerder
admin-delete<email>remove the role
admins—accounts with the role, and their number of paired phones
admin-log—what the admin commands and the admin page changed

Legacy names: beheerder-maak, beheerder-wis, beheerders, beheerlog.

Functions and modules

Function / moduleRole
euzos_profileserver::admin_page::router, gateroutes and the domain gate (admin_domain)
euzos_profileserver::admin_page::login (login, cancel, link_page)password step, waiting request, /b/<id> page
euzos_profileserver::admin_page::pages (show, action)the GET pages and POST actions
euzos_profileserver::admin_page::app (request, confirm, reject)the app API for confirming
euzos_profileserver::admin_page::db (role, set_role, admin_log_by, admin_log_last, search_accounts, counts, schema; ADMIN_ROLE)database helpers
libs/qrthe QR code (own encoder, as SVG)

Config files

Key (server configuration)DefaultMeaning
admin_page (legacy beheerpagina)on in local and sandbox, off in productionswitch the admin page on or off
admin_domain (legacy beheer_domein)—the admin domain; without it no admin page anywhere
apple_app_id, android_package—needed to serve the app-link files with /b/*

On the VPS: the allow list for the admin domain is generated by euzos-whitelist into a Caddy snippet; see Environments and deploy.

On-disk config keys and typed confirmation words are English since 27-10-2026 (for example WIS-… → WIPE-…, omgeving= → environment=; docs/ENGLISH.md); the Dutch names stay accepted. The profile server's wire formats (pc line protocol, signed profile, signed phone messages, settings keys) stay Dutch.

API endpoints

MethodPathLegacy Dutch pathPurpose
GET/beheer, /beheer/<page>— (user-visible paths)the pages
POST/beheer/inloggen, /beheer/annuleer, /beheer/uit, /beheer/<action>—login, cancel, logout, actions
GET/b/<id>—the link target of the QR code (explanation without the app)
GET/api/app/v2/admin/<id>/api/app/v1/beheer/<id>the app fetches the request
POST/api/app/v2/admin/<id>/confirm/api/app/v1/beheer/<id>/bevestigconfirm ({time, signature})
POST/api/app/v2/admin/<id>/reject/api/app/v1/beheer/<id>/weigerreject

Protocol messages and formats

GET /api/app/v2/admin/<id> → {kind: "beheer", session, environment, server, user, admin_ip, phone_ip, same_network, text, code, created, expires, challenge, device}; errors 401 niet_aangemeld, 410 verlopen, 429, 404 (admin page off).

Signed with the chip key (ECDSA P-256, SHA-256, DER, base64); keys stay Dutch:

EUZOS-beheer-v1
omgeving=<environment>
server=<server>
sessie=<id>
beheerip=<admin_ip>
gebruiker=<user>
tijd=<Unix time of the phone>
uitdaging=<challenge>
apparaat=<device>

Confirm → 200 {ok: true, admin_ip}; 401 (signature), 409 (fetch first), 400 (clock more than 2 minutes off), 410, 429.

See also