Skip to main content

One post tagged with "adr"

View All Tags

ADR - public S3 bucket access

· 4 min read
Paweł Mantur
Solutions Architect
info

This post is an example of ADR - Architecture Decision Record. ADRs document the reasons behind architectural decisions. ADRs promote more transparent and fact-based decision making culture. ADRs are also an useful artefact from technical documentation perspective.

Context

When implementing this website (see related article for architecture overview), among other decisions, I needed to decide on how to setup AWS S3 bucket that hosts website files.

Decision

Although it is considered to be potentially unsafe, I have decided for Option 2: allowing public access 🙀. But let's not panic, I will explain why it is safe in this case.

Considered Options

❌ Option 1: Blocking public access to S3 bucket

  • Pros:
    • Safer option - zero trust is a holy rule of security, especially for public access. AWS console by default blocks public access when creating S3 buckets, it is also possible to block public access for whole AWS account. Moreover AWS IAM Access Analyzer tool reports public access to buckets as a security threat finding. AWS console and documentation really forces to think about that decision.
  • Cons - solution gets more complicated:
    • Hosting a static website using Amazon S3 functionality of S3 cannot be used, as it requires public access
    • since S3 website endpoint cannot be created, Cloud Front needs to access S3 REST API as origin
    • Docusaurus build creates a directory for each page/article and puts a single index.html file inside that directory. For better SEO, and nicer urls, we do not have index.html in links. Web servers know that in such case (when url points to a directory in webserver) index.html needs to be served. S3 website endpoint also knows how to handle that properly. But since we are using S3 REST API under the hood, it just follows the request as-is - if request is for https://pawelmantur.pl/blog/s3-public-bucket it finds out tha there is blog/s3-public-bucket directory in my s3, but since public access does not have directory listing permissions granted - it returns 403. To return index.html, as a web-server like nginx would do - we need to add CloudFront Function to handle this case and modify request URL to append index.html to the URL.
    • It is possible and relatively simple to try, but it requires introducing new components to the solution that can be avoided by leveraging existing AWS S3 website endpoints capability

✅ Option 2: Allowing public access to perform s3:GetObject action

  • Pros:
    • The bucket's only purpose is to host website files and this website is public by design, I want people to access my blog, I want it to be public.
    • S3 website endpoint can be used
    • Static website built with Docusaurus works properly out of the box with S3 website endpoint, no function needed
    • no additional cost related to CloudFront Functions, although it is ignorable for thi website
    • Simpler setup with less components means less room for errors
  • Cons:
    • There is a risk that I will put some confidential files into this bucket, but the risk is mitigated by automation: the only way in which this bucket is updated is by GH Action, it syncs only the build directory of Docusaurus website, which by design is public. Well defined, automated and tested process.

Consequences

Since public s3 buckets were introduced to architecture, I will have to be cautious what content I am putting there and what are the policies granted for public access. But since we are talking about a single person doing a blog, we can agree that related risks can be accepted.

If that decision was made in context of large organization, the use cases for public sharing would need to have special governance. If organization has no business workflows that would require public file sharing and different solutions are available for static websites hosting, then public access to S3 should not be allowed to avoid a risky setup.

References