← FAQ

Die FAQ sind auf Englisch und Niederländisch verfasst; sie werden auf Englisch angezeigt.

FAQ

Environments (SBX and PROD), IP allow list and deploy

FAQ › Profile server › Environments and deploy · Nederlands

What is it?

The profile server runs in two separate environments, plus a local one for development:

Wire nameProfile domainReachable
SBX (sandbox)sandbox<internal-host>only from addresses on the IP allow list
PROD (production)productieprofile.euzos.eupublic (the admin domain only from the allow list)
locallokaala LAN address with portdevelopment only

Each environment has its own Ed25519 signing key, database, accounts, phone keys, vault key, admin key, proxy secret and Graph app registration. The environment name and domain are in every signature, so a signature from one environment is worth nothing in the other. The package server download.euzos.eu is shared by both.

How do I…?

How does a PC know which environment to use?

A production build of EUZOS (EUZOS_ENV=production) knows only PROD: server and public key are built in (EUZOS_PRODUCTION_KEY), and from \EOS\FW\PROFILE.TXT only private= and language= count (legacy prive=, taal=). A test build takes its default from PROFILE.TXT (environment=sandbox|production|local; legacy omgeving=sandbox|productie|lokaal is still read); a login prefix sbx:<e-mail> or prod:<e-mail> in the e-mail field chooses the environment per login, and the console command environment [sbx|prod] sets the default (active after a reboot). The whole session (pc token, vault, profile folder, app catalogue, reports) follows the environment of the login.

How do I see which environment a server is?

euzos-profielserver key prints the public key and the lines for PROFILE.TXT; GET /api/app/v2/server returns environment, server, key_id and public_key; the admin page's Server status shows it too. A SANDBOX label appears on the PC's login screen and taskbar for SBX.

How do I give someone access to the sandbox (the allow list)?

On the VPS, as root: euzos-whitelist add <ip-or-net> [comment]; euzos-whitelist list, euzos-whitelist delete <ip-or-net>, and euzos-whitelist refresh (rewrite the Caddy files and reload, after a new Caddyfile). Old subcommands lijst, voeg, wis, vernieuw still work. The list itself lives only on the VPS, never in git.

What exactly does the allow list protect?

  • Sandbox: the whole profile site (Caddy cuts off everyone else) and SSH (a UFW rule per address).
  • Production: SSH and the admin domain; the rest of the profile site (port 443) is public.
  • On the admin domain, the two app-link files under /.well-known/ are let through for everyone (Apple and Google fetch them).
  • On the package server, a separate SSH allow list protects port 22; 80/443 are open.

How do I deploy a new profile server version?

From the Mac, after a commit:

server/profile/deploy/deploy.sh sandbox [--build-only]
server/profile/deploy/deploy.sh production [--build-only]     # also: productie, prod
server/profile/deploy/deploy.sh prod --binary <path>          # exactly the sandbox binary

Production needs a server-v* tag on HEAD and the same SHA-256 as deployed earlier on the sandbox. Hosts and options come from ~/.config/euzos/deploy.conf (old name uitrol.conf), outside git.

What does deploy.sh do?

  1. Checks: a clean work tree; for production a server-v* tag and the same binary hash as on the sandbox.
  2. Tests (cargo test --locked) and builds reproducibly (cargo zigbuild --release --locked --target x86_64-unknown-linux-musl).
  3. With --build-only it stops here.
  4. Copies the binary to the VPS, checks its SHA-256 and installs it under /opt/euzos-profiel/releases/<git-hash>/.
  5. Compares configuration, systemd unit and Caddyfile with deploy/ and shows differences (never overwrites; those are set up by hand per VPS).
  6. Backs up the database, switches the huidig link and restarts the service. If the secrets are not in place yet, it only switches the link and does not start.
  7. Verifies: the service is active, no panic in the journal, the server API reports the right environment and the same public key as before.
  8. On an error: rolls back to the previous release; on success appends a line to ~/.config/euzos/deploy.log.

How are the production secrets placed?

By the owner only, on the production VPS, with the script euzos-prod-geheimen (deploy/prod-geheimen.sh): proxy secret, a new vault key, the admin key, the client id and secret of the production Graph app registration, and the signing key (the server creates it and shows the public key for PROFILE.TXT). Until then the server does not start (euzos-profiel-klaar, deploy/geheimen-klaar.sh). Secrets never go into git or into the configuration file itself.

How do I deploy the package server?

server/download/deploy/deploy.sh [--build-only] (tests, builds, copies, sets up user and folders if needed, installs unit and Caddyfile after caddy validate, restarts, checks for 401 without a token, otherwise rolls back). Publishing packages: see Apps and downloads.

Details

Mix-up protection: the server refuses to start with a key or database of another environment. A sandbox domain must contain sbx; production refuses such a domain and sandbox requires one. Production may never use the sandbox's Graph app registration.

Behind Caddy: sandbox and production listen only on localhost; Caddy terminates TLS (Let's Encrypt) in front. The client IP is taken from X-Forwarded-For only when the request comes from localhost and carries the proxy secret in X-Euzos-Proxy (proxy_secret_file); otherwise the connection address counts. Locally the server does TLS itself (tls_chain, tls_key).

Defaults that differ: admin_page is off in production; reports is off in production (and only allowed there together with admin_token_file); registration_open is no unless set; allow_v1 only locally.

Names on the VPS stayed Dutch after the English conversion (renaming needs a migration): binary euzos-profielserver, service euzos-profiel, folders /opt/euzos-profiel, /etc/euzos-profiel/profiel.conf, /var/lib/euzos-profiel/, an outbound-traffic unit euzos-uitgaand.service with uitgaand.nft.

Reference

CLI commands

CommandWhereWhat it does
euzos-profielserver [--config <file>] startprofile VPSrun the server
euzos-profielserver key (legacy sleutel)profile VPSpublic key and the PROFILE.TXT lines
deploy.sh sandbox|production [--build-only] [--binary <path>]Macdeploy the profile server
server/download/deploy/deploy.sh [--build-only]Macdeploy the package server
euzos-whitelist list|add <ip> [comment]|delete <ip>|refreshVPS (root)the IP allow list
euzos-prod-geheimenproduction VPS (owner)place the production secrets
environment [sbx|prod], profile [sandbox|production|local [key]]EUZOS console (test build)the PC's default environment

The configuration file comes from --config or EUZOS_PROFILE_CONFIG (old EUZOS_PROFIEL_CONFIG); single keys from EUZOS_PROFILE_<KEY> (old prefix EUZOS_PROFIEL_).

Functions and modules

Function / moduleRole
euzos_profileserver::config::Config (load, Environment::parse)reads the configuration, legacy keys, mix-up rules
euzos_profileserver::config::LEGACY_KEYSDutch → English key table
euzos_profileserver::other_site, routerCSRF check and the router with security headers
Kernel: libs/profile/src/config.rs (Config::production_only, Config::for_environment, split_prefix)the PC's environment choice

Config files

Example files in server/profile/deploy/: sandbox.conf, productie.conf, lokaal.conf; on the VPS /etc/euzos-profiel/profiel.conf.

Key (legacy)Meaning
environment (omgeving)lokaal, sandbox or productie
address (adres)listen address ip:port
domain (domein)the public domain (in QR codes and signatures)
databasethe SQLite database
key (sleutel)the Ed25519 signing key file (created at the first start, 0600)
tls_chain (tls_keten), tls_key (tls_sleutel)local TLS only
behind_proxy (achter_proxy)trust X-Forwarded-For from Caddy (default on outside local)
proxy_secret_file (proxy_geheim_bestand)file with Caddy's proxy secret
admin_token_file (beheer_token_bestand)admin key of the agent APIs (DriverEnricher, BrowserFeedback)
vault_key_file (kluis_sleutel_bestand)vault key
download_key_file (download_sleutel_bestand), download_base (download_basis)download tokens
reports (meldingen), reports_database (meldingen_database), reports_max_mb (meldingen_max_mb, default 1024)the report database
web_fallback, allow_v1, registration_open, pc_password, admin_page, admin_domainfeature switches (see the other pages)
qr_duration, confirm_duration, token_duration, app_duration, web_durationlifetimes in seconds
apple_app_id, android_package, android_fingerprintsuniversal links / app links
mail, mail_dir, smtp_*, graph_*, sender, reply_toe-mail
entra_client_id, entra_check_sMicrosoft login

Secrets (SMTP password, admin key, vault key, Graph secret) are refused as values in the configuration; only *_file keys pointing to files with mode 600/640 are allowed.

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. In the server configuration the English key wins when both are present.

API endpoints

MethodPathLegacy Dutch pathPurpose
GET/api/app/v2/server/api/app/v1/serverenvironment, domain, key id, public key (used by deploy checks and the app)

Protocol messages and formats

PROFILE.TXT on the PC (the key is public). The PC writes and prefers the English keys:

server=<domain>
environment=<local|sandbox|production>
key=<public Ed25519 key, 64 hex>
key-id=<16 hex>              (optional)
private=on|off               (optional)
language=<code>              (optional)

euzos-profielserver key still prints the legacy Dutch form (header In \EOS\FW\PROFIEL.TXT …, then # EUZOS-profielserver, omgeving <environment>, server=, omgeving=<lokaal|sandbox|productie>, sleutel=; Server::profile_txt). A current PC reads both forms (and both file names); a Dutch key and its English one count as the same key, so having both is an error.

Every response carries Cache-Control: no-store, Referrer-Policy: no-referrer, X-Content-Type-Options: nosniff, X-Frame-Options: DENY and Server: euzos-profielserver. A changing request from another site gets 403 fout / reden=andere_site; an unknown path 404 fout / onbekend pad.

See also

  • docs/ENVIRONMENTS.md
  • docs/PROFILESERVER-SETUP.md, "Deploying with one command", "Differences for production", "Taking production into use"
  • docs/DOWNLOADSERVER.md, "Setup and management"
  • docs/ADMIN-PAGE.md, "Own domain and allow list"
  • Admin page · Apps and downloads · CLI