Skip to main content

AWS Service Baseline

Status

Locked first-pass direction for #57.

VRDex uses AWS narrowly for early supporting infrastructure. The current baseline is intentionally small: transactional auth email first, private profile asset storage next, and no broad AWS application platform before the product needs it.

Scope

The first AWS baseline covers:

  • Amazon SES for Convex Auth password and email verification messages
  • Route 53 DNS records for the SES sender domain
  • IAM credentials scoped to SES sending for Convex
  • a planned S3 private asset bucket for owner-authored profile assets, tracked by #115
  • Terraform state in S3 for checked-in infrastructure stacks

Non-goals for this baseline:

  • full production AWS landing zone
  • multi-account AWS architecture
  • CloudFront image CDN and transformation pipeline
  • broad object lifecycle, malware scanning, moderation review, or asset-processing automation
  • moving the application runtime from Convex/Vercel to AWS

Email Delivery

Locked decision: use Amazon SES for auth verification and transactional email.

Current hosted baseline:

  • AWS account: BASIC BIT hosted production account; provider account IDs stay in provider configuration, Terraform state, or operator records rather than public docs
  • SES region: us-east-1
  • sending domain identity: vrdex.net
  • sender address: no-reply@vrdex.net
  • Route 53 hosted zone: vrdex.net hosted zone; provider-generated hosted zone IDs stay in provider configuration, Terraform state, or operator records rather than public docs
  • Terraform stack: infra/terraform/ses
  • Terraform state key: ses/terraform.tfstate

Verified state as of this baseline pass:

  • SES identity verification: Success
  • Easy DKIM: enabled
  • DKIM verification: Success
  • Terraform plan against the hosted stack: no changes
  • SES send quota: Max24HourSend=50000, MaxSendRate=14, SentLast24Hours=0

Convex deployments that send email must set:

  • AWS_SES_REGION
  • AWS_SES_FROM_EMAIL
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • VRDEX_APP_NAME optional display name for email copy

The access key is generated by Terraform only when create_iam_access_key=true. Store the secret in Convex or the relevant provider secret store, never in git.

Asset Storage

Locked first-pass direction: use a private Amazon S3 bucket for owner-authored profile assets.

The first asset-storage implementation should use:

  • S3 Block Public Access enabled at the bucket level
  • server-side encryption; SSE-S3 is acceptable for the first slice because S3 encrypts new object uploads by default
  • app-generated presigned upload URLs for controlled browser uploads
  • app-generated reads, or a controlled delivery layer owned by #115, instead of public bucket objects
  • deterministic object prefixes keyed by environment and asset owner/profile context
  • metadata sufficient to connect uploaded objects to profile records, uploader, upload time, and moderation/review state

Do not make profile asset buckets public. Public profile pages should render through a controlled URL path that can enforce profile visibility, moderation suppression, replacement, and deletion behavior.

Deferred follow-on work:

  • #115 S3 bucket Terraform/runtime baseline
  • Convex asset metadata schema
  • presigned upload endpoint/mutation
  • image validation and size limits
  • moderation or malware scanning
  • CloudFront or image optimization
  • lifecycle rules and deletion/retention policy

Candidate environment/config names for #115:

  • AWS_ASSET_REGION
  • AWS_ASSET_BUCKET
  • AWS_ASSET_UPLOAD_ROLE_ARN or a narrow access key only if the runtime cannot use role-based auth
  • VRDEX_ASSET_PUBLIC_BASE_URL only after a controlled public delivery layer exists

Terraform State

Terraform stacks use the S3 backend bucket vrdex-terraform-state in us-east-1 with stack-specific state keys and S3 native locking.

Current stacks:

  • infra/terraform/state-mgmt: local-state bootstrap stack for the shared S3 Terraform state bucket
  • infra/terraform/ses: SES domain identity, DKIM, MAIL FROM, Route 53 records, and optional IAM sender key
  • infra/terraform/posthog: hosted PostHog project metadata
  • infra/terraform/vercel: hosted Vercel PostHog client environment variables
  • infra/terraform/docs-site: hosted docs Vercel project/domain and Route 53 DNS

Keep stack state, plans, local provider caches, and terraform.tfvars uncommitted.

Self-Hosting Boundary

Self-hosted AWS usage is limited to the values this repo documents by name: SES sender identity, DNS zone, Terraform state location, and the S3 asset bucket tracked by #115.

This baseline does not claim complete self-hosting support. Alternative S3-compatible stores are out of scope until #115 creates the first asset abstraction and a follow-up issue or ADR covers provider portability.