Tuesday, August 19, 2025

Building Mobile App that lets Users Access S3 without shipping Credentials in the App | Overview.

 

 Building  mobile app that lets users access S3 (read, list, upload) without  shipping credentials in the app - Overview.

Scope:

  • Intro,
  • The core problem,
  • Four common patterns (+ when to use which),
  • Direct S3 with Cognito Identity Pools (STS AssumeRole),
  • Pre-signed URLs (server issues short-lived URLs),
  • CloudFront in front of S3 (read path),
  • twtech API as a proxy (upload and download stream through backend),
  • Reference architectures (Serverless minimalCognito + S3 ...direct)
  • Reference architectures (Control everythingAPI Gateway Lambda pre-sign CloudFront),
  • Sample  IAM policy (per-user home prefix),
  • Sample Bucket CORS (Cross-Origin Resource Sharing) for mobile/web,
  • Upload strategies (mobile-friendly),

  • Server code sketch (Node.js Lambda) to pre-sign multipart parts,
  • Download strategies,
  • Security checklist (non-negotiables),

  • Cost & performance tips,
  • Sample twtech-S3bucket policy (CloudFront OAC for read; deny direct public),
  • Mobile-side implementation,
  • Quick Decision guide ,
  • What to build for most apps.

Intro:

Building a mobile app that accesses Amazon S3 without hardcoding credentials requires using a temporary security credential system like Amazon Cognito Identity Pools for authentication and authorization. 

The core problem

    •         Goal: Give each signed-in user controlled access to a subset of objects in S3 (e.g., their own “home” prefix) with good performance and low cost.
    •         Constraints: No embedded AWS keys; least privilege; ability to revoke; work on flaky mobile networks; handle large files.

Four common patterns (when to use which)

1.     Direct S3 with Cognito Identity Pools (STS AssumeRole)

   How it works:
    • App authenticates with an IdP (Cognito User Pool, Apple/Google/Facebook, OIDC, SAML). 
    • Cognito Identity Pool exchanges that identity for temporary AWS creds via STS. 
    • The mobile SDK uses those creds to call S3 directly.
    Pros: 
    • First-party AWS flow, no backend needed for basic CRUD; great for many small/medium objects; multipart upload built in.
   Cons: 
    • Fine-grained policy design is on twtech. 
    • Revoking already-issued creds is non-instant (short TTL helps).
   Use when: 
    • twtech needs both upload + read + list from the device and want minimal backend.

2.     Pre-signed URLs (server issues short-lived URLs)

   How it works: 
    • twtech backends (API Gateway + Lambda or any server) checks app authz and returns a pre-signed URL for GET/PUT (or multipart). 
    • The app talks to S3 using the URL—no AWS creds on device.
   Pros:
    • No AWS creds on device; per-request authorization; very tight TTL and object-specific scope; easy to inject server-side business rules (quota, file type checks).
   Cons: 
    • Pre-signed URLs cannot be revoked until they expire; listing still needs a server API (twtech doesn’t want to pre-sign a list).
   Use when: 
    • twtech wants maximum control and auditing of each access, or twtech doesn’t want STS creds on devices.

3.     CloudFront in front of S3 (read path)

   How it works: 
    • Private S3 bucket CloudFront with Origin Access Control (OAC)
    • App fetches via CloudFront using signed URLs/cookies or with twtech  token auth at the edge (Lambda@Edge/CloudFront Functions).
   Pros:
    • Global cache, great performance and cost for read-heavy workloads; easy key rotation for signed URLs; hides S3.
   Cons: 
    • Not for uploads (twtech still need pre-signed URLs or STS for PUT).
   Use when: 
    • Read-heavy media/doc delivery where CDN performance and revocation controls matter.

4.     twtech API as a proxy (upload and download stream through backend)

   Pros:
    • Centralized policy & scanning; simple client; can transform on the fly.
   Cons: 
    • Backend becomes a bandwidth and cost bottleneck. 
    • Usually avoid for large files.
  Use when:
    • Files are small, or content must be inspected/transformed server-side before reaching S3.

NB:

Most mobile apps mix #2 for uploads (pre-signed multipart) and #3 for downloads (CloudFront).

    • If twtech also need client-side listing or rename/move semantics, it will combine with #1 or provide list endpoints in its API.

Reference architectures

A) “Serverless minimal”: Cognito + S3 (direct)

        AuthN:
    • Cognito User Pool (hosted UI or native SDK).
        AuthZ:
    • Cognito Identity Pool role mapping IAM roles with conditions restricting to a user prefix.
        Data path:
    • App S3 (SDK; multipart uploads).
        When to pick: 
    • Simple per-user storage, light business logic, low ops.

Sample  IAM policy (per-user home prefix)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListUserHome",
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::twtech-S3bucket",
      "Condition": {
        "StringLike": {
          "s3:prefix": ["home/${cognito-identity.amazonaws.com:sub}/*"]
        }
      }
    },
    {
      "Sid": "twtechCRUDUserHome",
      "Effect": "Allow",
      "Action": ["s3:GetObject","s3:PutObject","s3:DeleteObject","s3:AbortMultipartUpload","s3:ListMultipartUploadParts"],
      "Resource": "arn:aws:s3:::twtech-Sbucket/home/${cognito-identity.amazonaws.com:sub}/*"
    }
  ]
}

# Sample Bucket CORS (Cross-Origin Resource Sharing)  for mobile/web

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
  </CORSRule>
</CORSConfiguration>


B) “Control everything”: API Gateway + Lambda pre-sign + CloudFront

        AuthN:
    • Cognito User Pool (JWT).
        AuthZ:
    • Lambda validates JWT/entitlements; issues pre-signed URLs for PUT/GET and performs server-side checks (quota, content type, virus scan ticket).
        Read path: 
    • Clients fetch via CloudFront (private S3 with OAC). 
    • Use CloudFront signed URLs/cookies or a simple custom header/token validated at the edge.
        Upload path: 
    • Client requests pre-signed multipart URLs from API; then uploads directly to S3.
        When to pick: 
    • twtech wants revocation, cache, analytics, and business rules.

Upload strategies (mobile-friendly)

        Single-part PUT
    • Simple for small files (<5–10 MB typical).
        Multipart upload: 
    • Required for large files; enables pause/resume and parallelism.
      •     Client with STS creds: Use the AWS Mobile SDK multipart APIs.
      •     Client without creds: Backend generates pre-signed URLs per part; client PUTs each part, then backend (or client) completes the upload.

Server code sketch (Node.js Lambda) to pre-sign multipart parts

import { S3Client, CreateMultipartUploadCommand, UploadPartCommand, \
CompleteMultipartUploadCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: process.env.AWS_REGION });
export async function handler(event) {
  const { key, parts } = JSON.parse(event.body); 
// validate: path, size caps, content-type, user ownership
  const create = await s3.send(new CreateMultipartUploadCommand({
    Bucket: process.env.BUCKET,
    Key: key,
    ContentType: "application/octet-stream",
    ACL: undefined // ACLs off (Bucket owner enforced)
  }));
  const urls = await Promise.all([...Array(parts)].map((_, idx) =>
    getSignedUrl(s3, new UploadPartCommand({
      Bucket: process.env.BUCKET,
      Key: key,
      UploadId: create.UploadId,
      PartNumber: idx + 1
    }), { expiresIn: 900 }) // 15 minutes
  ));
  return { statusCode: 200, body: JSON.stringify({ uploadId: create.UploadId, urls }) };
}

Download strategies

        Private S3 via CloudFront + OAC:
    •  Best performance. Use signed URLs with short TTL; rotate keys. For per-user access checks, have twtech origin URL include a user-scoped path, or validate JWT at the edge (Lambda@Edge/Functions).
        Pre-signed GET from backend: 
    • Great for one-off files; keeps S3 fully private; TTL seconds–minutes.

Security checklist (non-negotiables)

        Never embed IAM access keys in the app
    • Only STS temp creds or pre-signed URLs.
        S3 bucket private (no public ACLs); 
    • enable Object Ownership: Bucket owner enforced (disables ACLs).
        Least privilege IAM with conditions (prefix, tags, request context).
        Short TTLs:
    •  STS creds (≤1h typical), pre-signed URLs (≤15m typical), CloudFront signed URLs (minutes–hours).
        Revocation plan: 
    • Short TTL + key rotation; with CloudFront you can rotate key pairs. 
    • For pre-signed S3, twtech can’t revoke—expire fast.
        KMS encryption (SSE-KMS): 
    • For sensitive data; use per-app CMKs and limit who can decrypt.
        Input validation
    • Enforce allowed Content-Type, max size, allowed extensions before issuing upload URLs.
        Malware scanning
    • Trigger Lambda on ObjectCreated:* (S3 Event) -> scan (e.g., ClamAV layer) -> tag/quarantine; expose only scanned objects to users (tag-based access).
        Data privacy controls:
    •  Separate customer data by account or S3 Access Points; don’t rely solely on prefixes for multi-tenant SaaS with strong isolation—consider per-tenant buckets or access points.
        Observability:
    •  CloudTrail data events for S3; CloudFront logs; S3 server access logs or CloudWatch access logs; metrics on 4xx/5xx; alarms on unusual activity.
        Avoid wildcards in bucket policy;
    •  prefer identity-scoped conditions.
        CORS (Cross-Origin Resource Sharing):
    •  Tighten as needed; expose ETag for optimistic concurrency.

Cost & performance tips

        CloudFront on reads
    • offload S3, lower TTFB globally.
        Transfer Acceleration:
    • On uploads if users are global and large files are common.
        Compression/transcoding:
    • For media (server-side or via Object Lambda).
        S3 Object Lambda or Lambda@Edge:
    • For dynamic transformations (thumbnails, redactions) without making the object public.
        Multipart tuning
    • 5–15 MB part size is a good starting point on mobile; retry with exponential backoff.
        Client caching
    • Keep small metadata locally; consider an index API rather than listing deep prefixes from the device.
        Tag objects 
    • with owner/userId; use lifecycle to transition/expire.

Sample twtech-S3bucket policy (CloudFront OAC for read; deny direct public)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "twtechOnlyAllowCloudFrontOriginAccessControl",
      "Effect": "Allow",
      "Principal": { "Service": "cloudfront.amazonaws.com" },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::twtech-S3bucket/private/*",
      "Condition": {
        "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::accountID:distribution/E123ABC456" }
      }
    },
    {
      "Sid": "twtechDenyNonTLS",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": ["arn:aws:cloudfront::accountID:distribution/E123ABC456","arn:aws:s3:::twtech-S3bucket/*", \
           "arn:aws:s3:::twtech-S3bucket"],
      "Condition": { "Bool": { "aws:SecureTransport": "false" } }
    }
  ]
}

Mobile-side implementation 

        Token storage: 
    • Store IdP/Cognito tokens in the OS-secure keystore (Keychain/Keystore); refresh silently.
        Retry/backoff: 
    • Handle transient 5xx and throttling; support pause/resume for uploads.
        Background uploads:
    • Queue + persist multipart state (uploadId, completed parts).
        Progress & ETag: 
    • Capture ETag per part and on final object; use ETag for cache/concurrency.
        Do not log secrets (pre-signed URLs, JWTs).
    • Redact in telemetry.

Quick Decision guide 

  •   Need read at scale + revocation? CloudFront + OAC for reads.
  •   Need uploads from device with tight server control? Pre-signed multipart via API.
  •   Want no backend and okay with IAM complexity? Cognito Identity Pool + STS direct S3.
  •   Very strict compliance & scanning? Proxy uploads through API (or pre-signed + post-ingest scanning).

What to build for most apps

        Auth: 
    • Cognito User Pool (federation allowed).
        AuthZ & control plane: 
    • API Gateway + Lambda to issue pre-signed multipart URLs (15-minute TTL), enforce quotas/types, and return object metadata lists.
        Read path: 
    • CloudFront (OAC) in front of the S3 bucket’s private/ prefix; use signed cookies for session access or validate a JWT at the edge.
        Bucket: 
    • Private, Object Ownership: Bucket owner enforced, SSE-KMS, lifecycle rules.
        Post-upload: 
    • S3 Event Lambda malware scan + tag only tagged “clean” objects are served.





No comments:

Post a Comment

Amazon EventBridge | Overview.

Amazon EventBridge - Overview. Scope: Intro, Core Concepts, Key Benefits, Link to official documentation, Insights. Intro: Amazon EventBridg...