Password protect a Netlify site through GitHub Actions
Recently I’ve published an article on how to set up CI/CD with GitHub Actions and Netlify. When working on my last project I needed to password protect develop
and staging
sites which were deployed on different repos. Netlify already has solutions for access control like OAuth or password/JWT secret restriction or even through _headers
file with basic authentication. But what I wanted was to password protect my sites at the beginning with a single access and then add other accesses on need and maybe only for some routes, all managed through GitHub actions and deployed for each site.
Password protection only works with the paid Netlify plans
Selective protection with basic authentication met my needs very well. The only problem is that at the beginning I had to push _headers
file on GitHub with credentials, which did not seem very clean and not very safe to me. So I thought it would be better to use GitHub environment variables in _headers
file. The idea is to push this file without any credentials but simply a string that will be replaced.
How to do?
1- Push _headers
file with Basic-Auth followed by a string that will be replaced.
/*
Basic-Auth: SITE_ACCESS_USER:SITE_ACCESS_PASSWORD
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
What will interest us is Basic-Auth: SITE_ACCESS_USER:SITE_ACCESS_PASSWORD
. You can also notice that with /*
we will password protect all website routes. We could also set it only for specific routes and this is the advantage of this solution.
2- In your Github secrets add SITE_ACCESS_USER
and SITE_ACCESS_PASSWORD
3- In your workflow add a Setup Netlify access step in which we have to retrieve SITE_ACCESS_USER
and SITE_ACCESS_PASSWORD
variables through GitHub secrets. Then we try to find SITE_ACCESS_USER:SITE_ACCESS_PASSWORD
matching pattern and replace it with our credentials with sed
command.
- name: Setup Netlify access
env:
SITE_ACCESS_USER: ${{ secrets.SITE_ACCESS_USER }}
SITE_ACCESS_PASSWORD: ${{ secrets.SITE_ACCESS_PASSWORD }}
shell: bash
run: sed -i.bak "s/SITE_ACCESS_USER:SITE_ACCESS_PASSWORD/$SITE_ACCESS_USER:$SITE_ACCESS_PASSWORD/g" $(pwd)/public/_headers && rm $(pwd)/public/_headers.bak
Voilà 🎉
The complete workflow code is available at https://gist.github.com/itsabdessalam/ee5dfe83d832bf5015b096016cc923f4
Deployment logs overview
Test
See also
- https://docs.netlify.com/visitor-access/password-protection
- https://docs.netlify.com/routing/headers/#syntax-for-the-headers-file
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme
- https://docs.github.com/en/actions
- https://www.digitalocean.com/community/tutorials/the-basics-of-using-the-sed-stream-editor-to-manipulate-text-in-linux
Before you leave…
Thanks for reading! 😊