Operations#
Keeping HAPMan running: updates, the Entra secret, changing its address, break-glass, backups and remote access.
Updating HAPMan#
Download the latest zip into the folder above your old hapman folder, extract it over the top and run the installer again:
curl -LO https://downloads.andykemp.com/hapman/latest/hapman.zip
unzip -o hapman.zip && cd hapman
sudo ./install.sh
Settings, routes, history, the audit log and certificates are all kept. The version is shown next to the HAPMan name at the top of every page, and the changes are in What's new.
Rotating the Entra secret#
The client secret lasts 12 months by default. HAPMan shows a banner 30 days before it expires (red in the last 7 days). Once it has expired, nobody can sign in. Settings shows the expiry date at any time.
To rotate it:
-
On your Windows or Mac machine, run the script again with the same hostname:
It updates the existing app and adds a new secret. Existing role assignments are kept.
-
On the server, from the
hapmanfolder: -
Paste the new setup code. HAPMan restarts with the new secret.
- Once you've signed in, delete the old secret from the app registration in the Entra admin centre (App registrations > HAPMan > Certificates & secrets). Each secret is named
hapman-serverand the date it was created.
Changing the hostname, port or certificate#
This asks the hostname, port, Entra and certificate questions again. After changing the hostname or port, run New-HAPManApp.ps1 again with the new -HostName and -Port, then sudo ./install.sh --entra, so the Entra redirect URI matches. Otherwise sign-in fails with a redirect URI mismatch.
Giving someone else access#
In the Entra admin centre, go to Enterprise applications > HAPMan > Users and groups and assign them, or a group they're in, the HAPMan Admin role. You can also run New-HAPManApp.ps1 with their UPN or the group's name in -AssignTo, though that also creates a new secret.
Logs#
Break-glass: when Entra ID is unavailable#
HAProxy keeps routing whatever happens to HAPMan or Entra ID. If you must change routing without the web page:
- SSH in and edit
/etc/haproxy/haproxy.cfg. -
Check it:
-
Reload HAProxy:
HAPMan shows your edit as a difference on the Changes page, and its next apply replaces it, so make the same change in HAPMan once it's back.
To undo HAPMan's last apply:
sudo cp /etc/haproxy/haproxy.cfg.hapman-prev /etc/haproxy/haproxy.cfg && sudo systemctl reload haproxy
Files and backup#
| Path | What |
|---|---|
/opt/hapman |
Application code and virtual environment (owned by root) |
/etc/hapman/hapman.env |
Settings and secrets (root:hapman, 640) |
/etc/hapman/tls/ |
HAPMan's certificate and key |
/etc/hapman/cloudflare.ini |
Cloudflare API token (root, 600) |
/var/lib/hapman/hapman.db |
Routes, settings, history and audit log (SQLite) |
/usr/local/sbin/hapman-apply |
The only command HAPMan can run as root |
/etc/sudoers.d/hapman |
That one sudo rule |
/etc/haproxy/haproxy.cfg |
The generated HAProxy config, with haproxy.cfg.hapman-prev as the backup |
/etc/letsencrypt/ |
certbot's copy of the Let's Encrypt certificate and renewal settings |
Back up /var/lib/hapman/hapman.db and /etc/hapman/ to keep everything. A VM snapshot or backup does the same job. hapman.env and cloudflare.ini hold secrets, so keep the backup somewhere safe.
To change a setting in hapman.env by hand, edit it and run sudo systemctl restart hapman.
Putting it behind Global Secure Access#
To reach HAPMan from outside your LAN without forwarding a port, publish it with Entra Private Access:
- Install a Private Network connector on a machine that can reach the HAProxy VM (if you don't have one already).
- Create a Private Access enterprise application with an application segment for
hapman.contoso.com, TCP 8443, using that connector group. - Assign it to the people who use HAPMan.
The HAPMan Entra sign-in still applies on top, so you get Global Secure Access and Conditional Access on the HAPMan app itself. Your device needs to resolve hapman.contoso.com: a Cloudflare record set to DNS only, pointing at the internal IP, works, or add the name to Private DNS in Global Secure Access.