A simple, low cost, fast, and secure way to restrict access to an AWS CloudFront Distribution using a CloudFront Edge Function and HTTP Basic Auth.
/**
* This function is for a viewer request event trigger.
* Choose viewer request for event trigger when you associate this function with a distribution.
*/
function handler(event) {
if (!event.request.headers.authorization) return respond401();
var auth = event.request.headers.authorization.value;
if (!auth || !auth.startsWith('Basic ')) return respond401();
var users = [
'Basic <credential>'
];
var user = users.find(function (user) {
return user === auth;
});
if (!user) return respond401();
return event.request;
}
function respond401() {
return {
statusCode: 401,
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': { value: 'Basic' }
}
};
}
Associate the Cloudfront Edge Function above to your distribution after replacing the <credential>
in the function code with the result of running a base64 function on a username and password, like:
// username:password
btoa('[email protected]:password123')
// outputs: 'amltQGV4YW1wbGUuY29tOnBhc3N3b3JkMTIz'
// replace <credential> in the function code above with amltQGV4YW1wbGUuY29tOnBhc3N3b3JkMTIz
Also, make sure your distribution is using HTTPS!
Also, restrict access to who can view the source of your CloudFront Edge Function, since the credential is embedded in the function source. At the time of writing this gist, CloudFront Edge Functions don't support environment variables or network calls for loading secrets. For a more advanced and secure, but slower and more costly solution, use Lambda@Edge Functions or Cognito.
This solution is mainly useful for quickly getting something online and securing it until a user-facing authentication mechanism that supports signups can be put in place.