Directory Privacy

Admin-side view of the per-subdirectory Basic Auth feature (M50). User-facing copy lives at user/directory-privacy; this page covers operator concerns.

Where it lives

Admin: /jabali-admin/domains/edit/:idSecurity tab → Directory Privacy. The form is the same as the tenant view.

Tenant: /jabali-panel/domains/edit/:idSecurity tab → Directory Privacy.

What ships on disk

File / location Owner / mode Purpose
/etc/jabali-panel/dir-privacy/<rule-id>.htpasswd root:www-data / 0640 bcrypt-hashed credentials. Generated; never edit by hand.
/etc/nginx/conf.d/jabali/sites/<domain>.conf reconciler-owned Contains the rendered auth_basic / auth_basic_user_file directives.

For path /, the directive lives at server scope. Sub-path rules render as location ^~ /<path>/ { auth_basic …; auth_basic_user_file …; }.

ACME interaction

LE renewal must work while a site-wide / rule is active. The vhost template includes a hard override:

location /.well-known/acme-challenge/ {
  auth_basic off;
  ...
}

Renewal is verified after every reconcile of a domain that has both LE certs and a / directory-privacy rule.

Zero-credentials state

A rule with no credential pairs renders an htpasswd file with a single impossible entry. The realm exists; no credentials can satisfy it. Used to take a directory offline without deleting it.

API

  • GET /api/domains/:id/directory-privacy — list rules.
  • POST /api/domains/:id/directory-privacy — add a rule.
  • PATCH /api/domains/:id/directory-privacy/:ruleId — update.
  • DELETE /api/domains/:id/directory-privacy/:ruleId — remove.

Mutations require domain.write on the target domain.

Audit

Every mutation appends an audit row: directory_privacy.rule.created, …updated, …deleted, plus per-credential …credential.added, …credential.removed. Passwords are never logged.

Troubleshooting

  • “Renewal failed after enabling /” — vhost was generated before the ACME override block was added. Force a reconcile (jabali admin reconcile <domain>); the override should appear.
  • “Browser shows realm but rejects every password” — confirm the rule has at least one credential pair. Zero-credential rules deny by design.
  • htpasswd missing on disk — usually a reconciler error; check journalctl -u jabali-reconciler for the rule ID.