Storage
Intermediate 13 min read Storage

Storage Security and Encryption

Locking data at rest, in transit and at the API

Storage security is layered: identity (who can call the API), encryption (data at rest and in transit), and access boundaries (public access blocks, policies, presigned URLs). Most storage breaches are accidental public exposure.

encryptionKMSSSEbucket policypublic accesspresigned URLS3
Before we start

What you will learn

  • Enable encryption at rest with provider keys or your own KMS
  • Configure identity-based and bucket/container policies
  • Block public access and use presigned URLs safely
In 60 seconds

Block public access by default, encrypt at rest (SSE-KMS / SSE-S3 / Azure SSE / GCS CSEK), encrypt in transit with TLS, and authorize every read/write with IAM + policies so nothing is world-readable unless you make it so.

Introduction

What is this?

Encryption at rest: AWS SSE-S3 (keys managed), SSE-KMS (customer-managed), SSE-C (your keys); Azure Storage Service Encryption + customer-managed keys; GCP default server-side encryption or CSEK/CMEK. Access: bucket policies, ACLs, IAM roles, presigned URLs (time-limited), signed headers; Azure SAS tokens; GCP signed URLs. Public access blockers (S3 Block Public Access, Azure public network access, GCP uniform bucket-level access) lock the footgun.

Motivation

Why do you need it?

  • Public exposure is the most common real breach story in cloud audits.
  • Encryption-at-rest satisfies compliance (PCI, HIPAA, GDPR) by default.
  • Presigned/SAS URLs give time-limited external sharing without opening a bucket.
  • A single policy review line ('no public read') reduces incident risk enormously.
Think about it

Mental model

Imagine

A bonded warehouse with a sign-in desk, encrypted lockers, and courier passes

Think of

Storage security

The desk (identity) checks who enters; lockers (encryption) keep contents unreadable if a thief gets past; courier passes (presigned URLs) let specific people take one crate for a short time only.

Mechanics

How it works

  • Identity: IAM/Entra/Service Account decides 'who' with scoped permissions.
  • Policy: bucket/container policies grant and deny at the resource level with conditions.
  • Encryption: object write is encrypted with the bucket's key; reads decrypt at the API edge.
  • Presigned URLs: sign GET/SAS for N minutes; the URL alone is the credential.
  • Audit: storage access logging and CloudTrail/event logs record who did what.

Storage access decision.

Request
Identity auth
Policy check
Encryption
Allow / Deny
Hands-on

Examples

Lock a bucket down

Lock a bucket down
# AWS: block all public access + encrypt by default
aws s3api put-public-access-block --bucket my-bucket \
--public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
aws s3api put-bucket-encryption --bucket my-bucket \
--server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms"}}]}'
# share one object silently via presigned URL
aws s3 presign s3://my-bucket/secrets/report.pdf --expires-in 600

Block public access, enforce KMS encryption by default, and share time-limited URLs rather than opening the bucket.

Real world

In production

  • An HR system holds PII in an S3 bucket with public-access block, SSE-KMS, and a deny-policy for anonymous principals.
  • Azure storage accounts use managed identity SAS to give an azure function read-only access to a container.
  • GCS buckets use Uniform bucket-level access: no per-object ACLs, policy only, CMEK enforced.
Guidelines

Best practices

  • Start deny-by-default: block public access on every new bucket/container.
  • Use managed keys where you don't need rotation control; CMEK for strong governance.
  • Audit access logs and bucket policies; set a 'public read' alarm.
  • Prefer presigned/SAS URLs over ACL grants for all external sharing.
Watch out

Common mistakes

  • Granting public-read to 'check quickly' and forgetting to revoke.
  • Using the account-wide key when a bucket- or app-scoped key is safer.
  • Sharing full-account credentials instead of scoped presigned URLs.
  • Encryption disabled by default and never revisited after compliance flag.
Root cause analysis

Common issues

Error
Bucket policy denies programmatic access
Root cause

IAM vs bucket policy overlap and conditions

Fix

Use AWS IAM policy simulator (or Azure role explorer) to see effective permissions; align the bucket policy.

Error
Object appears 'public' after ACL change
Root cause

ACL still grants Everyone read

Fix

Enable S3 Block Public Access / uniform access and remove object ACLs.

When things break

Debugging tips

  • 403 on a 'public' bucket: the public-access block may override the policy — check both.
  • 'Shared with anyone' errors: ACLs + policy conflict — enable uniform/consistent access.
  • To find stray public buckets fast: run the provider hygiene report (Trusted Advisor / Azure Security / GCP Security Command Center).
Interviews

Interview checkpoint

Practice

Hands-on lab

Harden an Object Store and Share via Presigned URL
30 min · intermediate
In progress
Objectives
  • Enable encryption + block public access on a bucket
  • Exercise a presigned URL end to end
  • Audit the effective policy

Harden an Object Store and Share via Presigned URL

30 min · intermediate

0/4 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/1
1

What's the safest way to let an external user download one object, temporarily?

Go deeper

Official documentation