Skip to content

S3 Storage Buckets

DaraMex uses two S3 buckets provisioned via AWS CDK (infra/aws/):

BucketPurposePublic
daramex-storageAvatars, product imagesYes — anonymous GetObject
daramex-private-storageInternal docs per userNo — fully blocked

Dev buckets use a -dev suffix (e.g. daramex-storage-dev).


Architecture

CDK App (bin/aws.ts)
  └── AwsStack (lib/aws-stack.ts)
        └── StorageConstruct (lib/constructs/storage.construct.ts)
              ├── PublicBucket  (daramex-storage[-dev])
              ├── PrivateBucket (daramex-private-storage[-dev])
              ├── StoragePolicy (ManagedPolicy — min perms on both)
              ├── StorageUser   (IAM User DaramexStorageUser[-dev])
              └── AccessKey     (programmatic access)

Public Bucket

  • Block public ACLs: yes — ACL-based access is disallowed
  • Block public policy: no — bucket policy grants anonymous read
  • Resource policy: s3:GetObject for Principal: * on arn:…/*
  • Versioning: off (public media is replace-on-upload)
  • Encryption: SSE-S3 (at-rest compliance)
  • Removal policy: RETAIN (prod) / DESTROY (dev)

Private Bucket

  • Block public access: BLOCK_ALL
  • Versioning: enabled (internal document recovery)
  • Encryption: SSE-S3
  • Removal policy: RETAIN (prod) / DESTROY (dev)

CORS (dev only)

Applied to both buckets when isDev = true (CDK context -c env=dev or CDK_ENV=dev):

Allowed origins:  http://localhost:5173, https://daramex.org, https://*.daramex.org
Allowed methods:  GET, PUT, POST, DELETE, HEAD
Allowed headers:  *
Max age:          3000 s

The https://*.daramex.org pattern matches any single-level subdomain (for example https://panel.daramex.org). The apex origin https://daramex.org is listed separately because S3’s wildcard does not match the bare domain.


IAM

One ManagedPolicy (DaramexStoragePolicy[-dev]) covers both buckets with minimum permissions:

ActionResource
s3:PutObjectbucket/*
s3:GetObjectbucket/*
s3:DeleteObjectbucket/*
s3:ListBucketbucket (ARN only)

An IAM user DaramexStorageUser[-dev] has this policy attached. An access key is created for programmatic API access.


CloudFormation Outputs

OutputValue
StorageUserAccessKeyIdAccess key ID
StorageUserSecretAccessKeySecret access key (NoEcho)
PublicBucketNamePublic bucket name
PrivateBucketNamePrivate bucket name

Deployment

bash
# Dev stack
cd infra/aws
pnpm cdk synth -c env=dev   # inspect template
pnpm cdk deploy -c env=dev

# Prod stack
pnpm cdk synth
pnpm cdk deploy

Retrieve credentials from CloudFormation Outputs or AWS Secrets Manager after deploy.


Environment Detection

The isDev flag is resolved in bin/aws.ts with this priority:

  1. CDK context: cdk deploy -c env=dev
  2. Env var: CDK_ENV=dev
  3. Default: production (→ isDev = false)