← DUK

DUK parašyti anglų ir nyderlandų kalbomis; rodomi anglų kalba.

DUK

Profile server CLI

FAQ › Profile server › CLI · Nederlands

What is it?

The profile server is one program, euzos-profielserver (crate euzos-profileserver, source server/profile/src/main.rs). The same binary both runs the server (start) and manages it from the command line: accounts, admins, phones, PC sessions, the vault, reports, the app catalogue, download keys and tokens, offline policy, organisations, workplace servers and registered PCs. Every command works directly on the SQLite database named in the configuration file; the server itself does not have to be stopped.

The binary keeps its Dutch name euzos-profielserver (the path on the VPS and the systemd unit use it). The commands and flags are English; the old Dutch command names and flags still work as hidden aliases for one release.

Next to it there is a second, much smaller program for the download server, euzos-download (server/download), with its own three commands (see below).

How do I…?

…run a CLI command on the server?

euzos-profielserver [--config <file>] <command> [arguments]

The configuration file comes from --config <file>, otherwise from the environment variable EUZOS_PROFILE_CONFIG (the old name EUZOS_PROFIEL_CONFIG is still read). On the VPS the systemd unit starts the server as /opt/euzos-profiel/huidig/euzos-profielserver --config /etc/euzos-profiel/profiel.conf start; CLI commands are run the same way, as the service user (sudo -u euzos-profiel …), so they use the same database and keys (docs/PROFILESERVER-SETUP.md). --help or -h (or no command) prints the usage text.

…create an account?

user-create <email> [--first-name F] [--last-name L] [--city C] [--display-name "Name"] [--language nl|en] [--password-stdin]. You are asked for the password twice (or one line on stdin with --password-stdin); at least 10 characters. The account gets the two profiles Werk of school and Privé, status niet_geverifieerd, and a mail with link and code (valid 24 hours). Logging in only works once the address is confirmed. In an emergency (no mail) user-verify <email> confirms by hand; that is recorded in the admin log.

…block, unblock or delete an account?

  • user-block <email>: no more logins; logs out all PCs and revokes all phones.
  • user-unblock <email>: status back to actief; phones must be paired again.
  • user-delete <email> [--yes <email>]: GDPR erasure of everything (PCs, phones, vault including the storage key, reports, profiles, settings, verifications, mail counters). It asks you to type the address again, or takes it from --yes. The admin log keeps only a hash of the address.

…reset a password?

password <email> [--password-stdin] [--revoke-devices]: a new password; all PCs are logged out, and with --revoke-devices all phones are revoked too.

…make someone an admin of the admin page?

admin-create <email> (the account must be actief). The admin then logs in on https://<admin domain>/beheer with e-mail address and password and confirms in the EUZOS app on a paired phone. admin-delete <email> removes the role, admins lists the admins and how many phones they have paired. See Admin page.

…limit what admin commands a user may run on a PC?

admin-policy <email> [<policy> | geen | --delete]. The policy is a comma-separated part of console,sshd,log,profiel, or geen (none). It is put, signed, into that user's profile (beheer= line). Without a policy argument the command shows the current one; --delete removes it (the PC then follows its build: a test build allows everything, production nothing). Changing it logs out the account's PCs.

…publish an app (Chromium) in the catalogue?

app-set <name> --version <n> --size <bytes> --sha256 <hex> --url <https://…/NAME.APP> [--url <mirror>]… [--package <https://…>]…. The version comes from the .sig, size and SHA-256 from the package (tools/chromium/install.sh --create shows them). --url is the signed description (.sig next to it), --package the package itself (without it: next to the description); the first URL is tried first, the rest are mirrors. apps shows the catalogue, app-delete <name> removes an app. See Apps and downloads.

…set up download tokens?

Once per environment: download-key-create creates the download key in the file named by download_key_file (permissions 0600; it refuses to overwrite) and prints the line for the download server's key list. download-key shows the key id (kid) and that line again. download-token <app> <version> makes a token (valid 2 hours) for admin work and tests; it is written to the admin log.

…set the offline-login policy?

offline-policy shows the rules; offline-policy <*|@domain> <0..30> sets the number of days for this whole environment (*) or one organisation (@domain); 0 means not allowed; without a rule the default is 14 days. offline-policy-delete <*|@domain> removes a rule, offline-revoke <email> revokes every offline vault of an account, offline-tokens lists the valid ones. See PC login and docs/OFFLINE-LOGIN.md.

…set up an organisation for Microsoft (Entra) login?

org-create <name>, then org-tenant <name> <tenant id> (the GUID from Entra, Overview) and org-domain <name> <domain> for every allowed e-mail domain. orgs lists them. See Organisations and docs/WORK-LOGIN.md.

…register a workplace server or an EUZOS PC for Server Admin?

  • Workplace server: normally the server installer registers it itself (POST /api/workplace/v1/register). By hand: workplace-register <name> <key> [--network <ip>[,<ip>]] with the 64-hex key shown by workplace on the workplace server.
  • PC: pc-register <name> <key> <org> with the device key from pckey on the PC.
  • Admin rights: org-admin <org> <email> [--off].

Compare the fingerprint the command prints with the one on the server/PC.

Details

  • Everything is logged. Commands that change something write a line to the admin log (admin-log shows it). The action texts in that log are stored data and stay Dutch (gebruiker-maak, beheer …, app-zet, werkplek-registreer, …).
  • Accounts are e-mail addresses. Every <email> is normalised; the user name is always the address.
  • Mail limits. Verification mails: 1 per minute and 5 per day per address.
  • Passwords are read without echo (asked twice) or from stdin; 10 to 200 characters.
  • Legacy names. Old Dutch commands (gebruiker-maak, kluis, werkplekken, …) and flags (--voornaam, --ja, --wis, --uit, …) are mapped to the English ones before the command runs (tables LEGACY_COMMANDS and LEGACY_FLAGS in main.rs, plus small maps in org.rs, offline.rs, workplace.rs, workplace_admin.rs).
  • Values stay Dutch. Some arguments are wire values and are typed as such: the policy word geen, the parts console,sshd,log,profiel, the status names (actief, niet_geverifieerd, geblokkeerd), the environment names (lokaal, sandbox, productie).

Note on names. Config keys are moving to English names; the Dutch ones are still accepted (see the config table below). This page shows the names the code uses today.

Reference

Commands of euzos-profielserver

Global option: --config <file> (or EUZOS_PROFILE_CONFIG).

Server

CommandArgumentsWhat it doesOutputLegacy name
start—Starts the HTTP(S) server (tokio, at most 64 blocking threads). Locally it can do TLS itself (tls_chain/tls_key); in sandbox/production it listens on localhost behind Caddy.Start line on stderr: environment, address, domain, key id, number of users, how mail is sent (never secrets).—
key—Opens the server (creates the signing key on first use).Environment, domain, key id, and the lines for \EOS\FW\PROFIEL.TXT on an EUZOS PC, still in the legacy Dutch form (server=, omgeving=, sleutel= public key); the PC reads these as well as the English PROFILE.TXT keys (environment=, key=).sleutel

Accounts

CommandArgumentsWhat it doesOutputLegacy name
user-create<email> [--first-name F] [--last-name L] [--city C] [--display-name "Name"] [--language nl|en] [--password-stdin]Creates an account with profiles Werk of school and Privé, status niet_geverifieerd, sends link + code. Display name: first + last name, otherwise --display-name, otherwise the local part of the address.Confirmation; whether the mail was sent.gebruiker-maak
user-email<current address or old name> <new address>Requests a new address (must be confirmed by mail). For an active or blocked account the old address stays valid until then; an unconfirmed account is renamed at once.What happened.gebruiker-email
user-verify<email>Emergency: confirms an unconfirmed account, or carries out a pending address change, without mail. Logged.Confirmation.gebruiker-verifieer
user-block<email>Blocks the account; logs out all PCs, revokes all phones.Counts of PCs/phones.gebruiker-blokkeer
user-unblock<email>Back to actief (only if blocked).Confirmation.gebruiker-deblokkeer
user-delete<email> [--yes <email>]GDPR erasure of the whole account (gdpr::user_delete). Asks for the address again unless --yes matches.Counts per kind of data; the address hash written to the admin log.gebruiker-wis
password<email> [--password-stdin] [--revoke-devices]New password; logs out all PCs; optionally revokes all phones.Counts.wachtwoord
users—All accounts.Columns: e-mail address, status, profiles, devices; pending new address.gebruikers

Admins and admin policy

CommandArgumentsWhat it doesOutputLegacy name
admin-policy<email> [<policy> | geen | --delete]Shows/sets/removes the signed admin-command policy (console,sshd,log,profiel,ports,device or a part, or geen; device: the login screen background). Setting it logs out the account's PCs.Current or new policy.beheer
admin-log—Prints the admin log.date who action per line.beheerlog
admin-create<email>Gives an active account the admin role (beheerder) for the admin page.Confirmation, number of paired phones, login hint.beheerder-maak
admin-delete<email>Removes the admin role (open sessions end at the next click).Confirmation.beheerder-wis
admins—Accounts with the admin role.Address, status, phones paired.beheerders

Phones and PC sessions

CommandArgumentsWhat it doesOutputLegacy name
devices[<email>]Paired phones (all, or of one account).Device id, user, platform, name, last used, status (active / revoked <date>).apparaten
device-revoke<device id>Revokes a phone; the PCs that logged in with it are logged out.Confirmation or error.apparaat-intrek
pc-sessions—Logged-in PCs.ref, profile, PC IP, device (or password / web page), since, expires.pc-sessies

Reports and vault (GDPR)

CommandArgumentsWhat it doesOutputLegacy name
reports—How full the report database is (DriverEnricher, BrowserFeedback).Path, MB used of the limit, devices, browser reports (with screenshot). Or "reports are off".meldingen
reports-delete<email>Deletes all reports of an account.Counts.meldingen-wis
vault<email>What is in the account's vault (never the content), its desktop backgrounds (id and size, never the picture) and the vault log (90 days; desktop-background with stored, fetched, deleted).profile, kind, key, changed; then the log.kluis
vault-delete<email>Deletes the whole vault of the account, including the storage key (the encrypted profile directories become unreadable), and its desktop backgrounds (sealed with that key).Number of secrets deleted.kluis-wis

App catalogue and download tokens

CommandArgumentsWhat it doesOutputLegacy name
apps—The app catalogue (what GET /api/apps returns).Per app: version, size, SHA-256, date, description URLs, package URLs.—
app-set<name> --version <n> --size <bytes> --sha256 <hex> --url <https://…/NAME.APP> [--url <mirror>]… [--package <https://…>]…Adds or replaces an app (apps::App::check: up to 4 URLs per kind, description must end in /<NAME>.APP). Warns if the version goes down (PCs refuse a lower version).The catalogue lines of the app.app-zet
app-delete<name>Removes an app; PCs then report "not available".Confirmation.app-wis
download-key-create—Creates the download key (Ed25519) in download_key_file, mode 0600, refuses if it exists.Environment, kid, the line for the download server's key file.downloadsleutel-maak
download-key—Reads the download key.Environment, kid, key line.downloadsleutel
download-token<app> <version>A download token (2 hours) for admin work and tests, account "beheer"; logged with its jti.The token on stdout; jti and expiry on stderr.downloadtoken

Offline login

CommandArgumentsWhat it doesOutputLegacy name
offline-policy[<*|@domain> <0..30>]Without arguments: shows the default (14 days) and the rules. With: sets the days for * (this environment) or @domain (an organisation); 0 = not allowed.The rules / the new rule.offline-beleid
offline-policy-delete<*|@domain>Removes a rule.Confirmation.offline-beleid-wis
offline-revoke<email>Revokes all offline vaults of the account (the PC wipes its vault and logs out when it reconnects).Number revoked.offline-intrek
offline-tokens—Valid offline vaults.account, ref, profile, since, expires.—

Organisations (org.rs)

CommandArgumentsWhat it doesOutputLegacy name
org-create<name>Creates an organisation (Microsoft work login).Hint to run org-tenant and org-domain.org-maak
org-tenant<name> <tenant id> | --deleteSets (or removes) the Entra tenant id (a GUID). Without a tenant, Microsoft login is not possible.The tenant.—
org-domain<name> <domain> [--delete]Adds (or removes) an allowed e-mail domain.The domain list.org-domein (flag --wis)
orgs—All organisations.name, tenant, domains, number of accounts.—
org-admin<org> <email> [--off]Makes an account admin of an organisation (workplaces, Server Admin), or not any more with --off.Confirmation.org-beheerder (flag --uit)

Workplace servers and registered PCs (workplace.rs, workplace_admin.rs)

CommandArgumentsWhat it doesOutputLegacy name
workplace-register<name> <key> [--network <ip>[,<ip>]]Registers a workplace server by its public key (64 hex, shown by workplace on the server). Name 1–64 characters. Without --network the catalogue uses the public address of the sign-in.Id and fingerprint; the network setting.werkplek-registreer (flag --netwerk)
workplaces—The workplace servers.id, name, state (active, not active, never signed in, REVOKED), installed by, external address, lan, public, network.werkplekken
workplace-revoke<id>Revokes a workplace server: no sign-in, no download tokens, not in the catalogue.Confirmation.werkplek-intrek
workplace-network<id> <ip>[,<ip>]|autoFor which networks (at most 16) the catalogue names this workplace server to PCs; auto = the public address of its sign-in.Confirmation.werkplek-netwerk
workplace-org<id> <organization>|geenSets the organisation of a workplace server (needed for Server Admin).Confirmation.werkplek-org
pc-register<name> <key> <org>Registers an EUZOS PC's device key (64 hex, from pckey on the PC) with an organisation.Fingerprint to compare.pc-registreer
pcs—Registered PCs.key, name, organisation, REVOKED.—
pc-revoke<key>Revokes a PC key: no more admin proofs for that PC.Confirmation.pc-intrek

Legacy flags (hidden)

OldNew
--voornaam--first-name
--achternaam--last-name
--woonplaats--city
--weergavenaam--display-name
--taal--language
--wachtwoord-stdin--password-stdin
--ja--yes
--trek-apparaten-in--revoke-devices
--wis--delete
--versie--version
--grootte--size
--pakket--package
--netwerk--network
--uit--off

Configuration file (profiel.conf)

key = value lines, # starts a comment (config::read_lines). Relative paths are relative to the configuration file. Every key can also be given as an environment variable EUZOS_PROFILE_<KEY> (upper case), which wins over the file; the old prefix EUZOS_PROFIEL_ (with the English or the Dutch key) is still read. A secret itself (SMTP password, admin token, vault key, Graph secret) is refused in the file: it must be in its own file, named by the *_file key. Examples: server/profile/deploy/lokaal.conf, sandbox.conf, productie.conf. Values are never shown here.

KeyLegacy (Dutch) keyMeaningDefault
environmentomgevinglokaal, sandbox or productie (required).—
addressadresWhere the server listens (ip:port); in sandbox/production only localhost (Caddy in front).— (required)
domaindomeinPublic host[:port] as in the QR code, the signature and the app.— (required)
database—The SQLite database.— (required)
keysleutelThe Ed25519 signing key file (created at first start, 0600).— (required)
tls_chaintls_ketenLocal only: certificate chain files (comma-separated).none
tls_keytls_sleutelLocal only: the TLS private key file.none
behind_proxyachter_proxyTake the client IP from X-Forwarded-For (only from localhost with the proxy secret).yes, except local
proxy_secret_fileproxy_geheim_bestandFile with the secret Caddy sends in X-Euzos-Proxy. Required behind Caddy.none
admin_token_filebeheer_token_bestandFile with the admin key for the agent APIs (DriverEnricher, BrowserFeedback). Without it those APIs are 404.none
vault_key_filekluis_sleutel_bestandFile with the vault's server key. Without it the vault is 404.none
download_key_filedownload_sleutel_bestandThe download key file. Without it /api/apps/token is 404.none
download_basedownload_basisBase URL of the package server (https://<host>/); URLs under it need a download token.none
reportsmeldingenKeep DriverEnricher/BrowserFeedback reports.yes in local/sandbox, no in production
reports_databasemeldingen_databaseReport database path.meldingen.db next to the database
reports_max_mbmeldingen_max_mbLimit of the report database in MB.1024
web_fallbackweb_terugvalThe web page with password as a fallback without the app.yes
allow_v1sta_v1_toePolls without PC secret (old 8.5 format); local only.yes local, else no
registration_openregistratie_openUsers may register themselves (app, PC, web page).no
pc_passwordpc_wachtwoordLogging in on the PC with e-mail and password (POST /api/pc/login).yes
admin_pagebeheerpaginaThe admin page /beheer.yes, except production
admin_domainbeheer_domeinThe admin page's own domain (e.g. <internal-host>); must differ from domain.none
qr_durationqr_duurSeconds a QR login session that no phone fetched stays valid.30
confirm_durationbevestig_duurSeconds a fetched session waits for approval.120
token_durationtoken_duurSeconds a PC token (and the signed profile) is valid.43200 (12 h)
app_durationapp_duurSeconds an app sign-in with password (eza_) is valid.900
web_durationweb_duurSeconds a sign-in on the web page is valid.3600
apple_app_id—iOS universal links (TEAMID.eu.euzos.app).none
android_packageandroid_pakketAndroid app links: package name.none
android_fingerprintsandroid_vingerafdrukkenAndroid app links: signing certificate fingerprints (comma-separated).none
mail—graph, smtp or map (folder). Required in sandbox/production.map locally
mail_dirmail_mapFolder for mail = map.mail
smtp_host—SMTP host.—
smtp_portsmtp_poort587 (STARTTLS) or 465 (TLS).587
smtp_usersmtp_gebruikerSMTP user.—
smtp_password_filesmtp_wachtwoord_bestandFile with the SMTP password.—
graph_tenant—Microsoft Graph mail: tenant GUID.—
graph_client_id—Graph app registration (production must use its own, never the sandbox one).—
graph_secret_filegraph_geheim_bestandFile with the Graph client secret, or…—
graph_certificate_filegraph_certificaat_bestand…certificate file, together with…—
graph_key_filegraph_sleutel_bestand…its key file.—
senderafzenderSender of the mails.EUZOS <no-reply@euzos.eu>
reply_toantwoordadresReply-to address.none
entra_client_id—Client id (GUID) of the EUZOS Entra app; without it /api/pc/entra is 404.none
entra_check_sentra_controle_sHow often (s) an Entra account is re-checked with Microsoft (minimum 60).900

yes/no values also accept ja/nee, true/false, 1/0. Config::check refuses dangerous mixes: outside local the server must listen on localhost, may not do TLS itself, may not allow v1 polls, and needs proxy_secret_file behind Caddy; production may not use the sandbox Graph app registration.

Environment variables

VariableMeaning
EUZOS_PROFILE_CONFIG (legacy EUZOS_PROFIEL_CONFIG)Path of the configuration file when --config is not given.
EUZOS_PROFILE_<KEY> (legacy EUZOS_PROFIEL_<KEY>, also with the Dutch key)Overrides one configuration key, e.g. EUZOS_PROFILE_DATABASE.

The download server CLI (euzos-download)

server/download/src/main.rs: the token check behind Caddy's forward_auth for download.euzos.eu (see API).

CommandArgumentsWhat it doesLegacy name
start[--address 127.0.0.1:8091] [--keys <file>] [--blocklist <file>]Runs the check server on localhost. Defaults: keys /etc/euzos-download/sleutels.txt, blocklist /etc/euzos-download/zwarte-lijst.txt; both are re-read when they change.flags --adres, --sleutels, --zwarte-lijst
revoke<jti> [comment]Puts a token's jti (32 lowercase hex, from the log) on the blocklist.intrek
keys—Lists the known key ids (kid).sleutels

Functions and modules

FunctionRole
main::runParses --config, maps legacy names (command, flag_name), loads Config, dispatches.
main::startThe server: euzos_profileserver::router on axum (TLS via rustls locally).
main::adminsadmin-create, admin-delete, admins.
config::Config::load, config::read_lines, config::english_keyConfiguration file + environment, legacy keys (LEGACY_KEYS).
gdpr::user_deleteuser-delete.
offline::clioffline-policy*, offline-revoke, offline-tokens.
org::cliorg-create, org-tenant, org-domain, orgs.
workplace::cliworkplace-register, workplaces, workplace-revoke, workplace-network.
workplace_admin::cliworkplace-org, pc-register, pcs, pc-revoke, org-admin.
download_token::Key::create / read / tokenDownload key and tokens.
apps::App::check / linesValidating and printing a catalogue entry.

The Python prototype

tools/profileserver/profileserver.py is the earlier prototype from milestone 8.5 ("for now on the Mac", Python standard library only), with the commands start, user-create, password and users. It is not the production server. It is only still started by make profileserver PKI=/path (local HTTPS on port 8444, milestone 8.5; the Makefile also mentions it for creating a user); the real server runs with make profileserver-rs.

See also

  • API · Admin page · Environments and deploy
  • docs/PROFILESERVER-SETUP.md
  • docs/PROFILE-PROTOCOL.md
  • docs/ENGLISH.md ("Profile server CLI", "Database, configuration, CLI")
  • docs/OFFLINE-LOGIN.md · docs/WORK-LOGIN.md · docs/WORKPLACE.md · docs/DOWNLOADSERVER.md