HTTP Basic authentication puts a browser login prompt in front of a whole site or a single folder. It is the quickest way to keep a staging site out of search engines, add a second lock in front of an admin panel, or share files privately. This guide shows how to password protect a directory on Nginx and Apache using an htpasswd file.
Before you start
- Root access to the server, with HTTPS enabled. Basic auth sends the password with every request, encoded but not encrypted, so never use it over plain HTTP.
- On cPanel hosting, use cPanel → Files → Directory Privacy instead; it creates the same files for you.
Create the htpasswd file
- Install the tool:
- Ubuntu/Debian:
sudo apt install apache2-utils - AlmaLinux/Rocky:
sudo dnf install httpd-tools
- Ubuntu/Debian:
- Create the file with a first user, using bcrypt (
-B):sudo htpasswd -c -B /etc/nginx/.htpasswd alice - Add more users without
-c(which would overwrite the file):sudo htpasswd -B /etc/nginx/.htpasswd bob - Remove a user:
sudo htpasswd -D /etc/nginx/.htpasswd bob. - Restrict permissions so only root and the web server can read it:
sudo chown root:www-data /etc/nginx/.htpasswd && sudo chmod 640 /etc/nginx/.htpasswd
Keep the file outside the web root so it can never be downloaded. For Apache, /etc/apache2/.htpasswd or /etc/httpd/.htpasswd are common locations.
Nginx: protect the whole site
server {
server_name staging.example.com;
auth_basic "Staging - authorised users only";
auth_basic_user_file /etc/nginx/.htpasswd;
# rest of the server block
}Nginx: protect one folder
location ^~ /admin/ {
auth_basic "Admin area";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ /index.php?$args;
}If the folder contains PHP, the PHP files must also be handled inside this location (with its own fastcgi_pass) or by a nested PHP location; otherwise the general \.php$ regex location matches them first and skips the password. The ^~ modifier plus a nested location avoids that. See location matching order.
Apache: protect a folder
In the vhost (preferred) or an .htaccess inside the folder:
<Directory /var/www/example.com/public/admin>
AuthType Basic
AuthName "Admin area"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>In .htaccess, leave out the <Directory> lines. The folder needs AllowOverride AuthConfig. The same .htaccess rules work on LiteSpeed.
Skip the password for trusted IPs
Nginx
satisfy any;
allow 203.0.113.10;
deny all;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;Requests from 203.0.113.10 get in directly; everyone else must log in. Use satisfy all to require both the IP and the password.
Apache
<RequireAny>
Require ip 203.0.113.10
Require valid-user
</RequireAny>Exclude paths that must stay public
Let's Encrypt validation and health checks must not hit the password prompt:
location ^~ /.well-known/acme-challenge/ { auth_basic off; }In Apache, a <Location "/.well-known/acme-challenge/"> block with Require all granted does the same.
Test
curl -sI https://staging.example.com/ | head -1
curl -sI -u alice:YOURPASSWORD https://staging.example.com/ | head -1The first should be 401, the second 200.
Troubleshooting
- 500 error after adding auth: wrong path to the htpasswd file, or the web server can't read it.
- Login prompt keeps reappearing: the password hash format isn't supported (use
-B), or the user doesn't exist. - PHP pages bypass the password in Nginx: the PHP regex location matched first. Nest PHP handling inside the protected location.
- WordPress admin-ajax breaks: front-end features call
/wp-admin/admin-ajax.php; exclude it from protection.
FAQ: password protecting folders
Is Basic auth secure enough?
Over HTTPS with strong passwords and rate limiting, it's a solid extra layer, but not a replacement for app login security.
Will search engines index a protected site?
No. They get 401 and can't see content.
Can I log out of Basic auth?
Browsers cache the credentials until closed; there is no proper logout.
