Host a static website with Google Cloud Storage using Firebase Cloud Function as a proxy to secure the access with HTTP basic authentication

That is a fucking long title.

I wanted a cheap hosting for a static website. So I though “Hey let’s use Google Cloud Storage”! It can be used easily to host a static website.

But my website has to be protected by username/password authentication. A HTTP basic Authentication is enough for my use case. The thing is: it is super hard to achieve this with Google Cloud Storage… I can restrict the access to my bucket with IAM, that’s for sure. But when my users access my static website hosted on GCS, no one is going to include a nice “Authorization” header or whatever. So it is “Access denied”.

So I wanted to create a Proxy to access my bucket. By creating a service account, I can provide READ access to any server to my bucket. But I still want a cheap solution. So I will definitely not run a VM 24/7 just to provide a proxy to a website rarely used.

Firebase proposes some cheap plan (pay as you go) and allow us to run Cloud Function with basically any NPM module I want, including Express, which provide Proxy middleware.

So I started to build a proxy to access my GCS hosted website. But I never achieve the expected result because of this

fail_google.png

There is a Github issue about a similar error but damn, there is no solution for this; It looks like Google will just not allow Firebase to access GCS via HTTP.

So after a lot of struggles and try-but-failed workaround, I ended up downloading locally the requested file from GCS and stream it as a request.

All is left to do is create a nice CNAME for my firebase project.

See this gist to access the final code I used.

AWS CloudFront S3, Basic HTTP authentication – password protection

This is a post it to this article explaining how to use a Lambda function to protect a CloudFront-S3 distribution using Basic HTTP Authentication.

Some additional notes:

  • The Lambda Function must be in the region us-east-1 (US East N. Virginia)
  • You must create a new version of the Lambda function
  • The ARN of the Lambda function you provide to CloudFront must inlude the lambda version
  • The Lambda function’s role must have the following Trust Policy

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "edgelambda.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }