Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Basic HTTP Authentication for CloudFront with Lambda@Edge
'use strict';
exports.handler = (event, context, callback) => {
// Get request and request headers
const request = event.Records[0].cf.request;
const headers = request.headers;
// Configure authentication
const authUser = 'user';
const authPass = 'pass';
// Construct the Basic Auth string
const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');
// Require Basic authentication
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
const body = 'Unauthorized';
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: body,
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
callback(null, response);
// Continue request processing if authentication passed
callback(null, request);
Copy link

rkz commented Sep 29, 2020

@nachmore that was it :) Thank you

Copy link

Habbie commented Dec 15, 2020

Line 23 is broken - the realm parameter is mandatory! This is documented in RFC7617 section 2 and I found out because Python's urllib's AuthHandler classes do not recognise the header without realm=.

Copy link

jeroenvollenbrock commented May 15, 2021

This is now also possible, cheaper and faster with the newly launched CloudFront Functions (

Copy link

malcolmm83 commented Apr 13, 2022

@rkz - make sure that your trigger CloudFront Event is Viewer Request and not Origin Request. The auth headers are stripped out of Origin.

I added the 'Authorization' header to the cache key and it now comes through to the 'Origin Request'. My issue is that I need both this header as well as the origin domain for my lambda, and I can't determine the domain from the 'Viewer Request' . Wish this stuff was documented better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment