Skip to content
Not released yet: nothing on these pages installs until 0.1, the first release. Run it on the sample tenant today.

Security

The last step is a checklist of what keeps this server safe. Each item passes, or says why not and what to change. When all ten steps pass, the setup is complete.

The checklist here covers what can be checked on a running deployment. The evaluator’s checklist covers the controls built into the code, each with the test that proves it. Secrets and tokens explains where each secret is kept.

  • Steps 1 to 3 have passed, because several items read their results.
  • A terminal in the folder that holds your compose.yml.
  1. On step 10, Security, press Check the security checklist.
  2. Read the items. Each shows its name, then passes, fails or explained, and one sentence.
  3. Fix each item that fails, using the table, and press the button again.
Item Passes when If it fails
https PUBLIC_BASE_URL is https. Serve the api over https at the proxy and set the address. See Address.
cookies_secure Always passes: cookies are Secure, HttpOnly and SameSite=Lax. Nothing to change.
scanner_secret_worker_only The scanner’s secret is encrypted for the worker only. Enter the scanner’s secret again on The scanner. A secret saved there is encrypted for the worker alone.
app_registration_read_only The app registration’s check has passed, so it holds nothing that writes. Finish The app registration.
expiry_<name> An Entra or sign-in secret has the expiry date you entered. Enter the secret again with its date, such as pbmb admin secrets set powerbi_app_client_secret --expires 2027-10-26. Use the date Entra shows.
identity_volume_private Only the api’s own user can read its identity volume (/var/lib/pbmb/identity). Mount the api_identity volume there, and run docker compose exec api chmod 700 /var/lib/pbmb/identity.
worker_identity_volume_private Always explained: the api cannot see the worker’s volume. Check it yourself, below.

If you give the api its identity in API_AGE_IDENTITY, identity_volume_private is explained, because no volume holds it.

The worker’s volume is the one item you check by hand:

Terminal window
docker compose exec worker ls -ld /var/lib/pbmb/identity

The line must start with drwx------. Back up the identity volumes apart from the database dump: a dump alone holds no usable secret, and a lost volume means entering that container’s secrets again.

The step passes when no item fails. The same check runs from a terminal and exits 1 while an item fails, so a script can wait on it:

Terminal window
pbmb admin check security
pbmb admin status

pbmb admin status lists failing checks and the secrets that expire within 30 days. The checks run again every day. If a sentence appears, find it on When a check fails.