Secure S3 File Sharing for Enterprises: A Complete Guide

Sharing files from S3 is easy. Sharing them with real auth, granular access, and an audit trail an auditor will accept — that's the part where most teams trip.

S3 ends up holding most of the important stuff. Reports, contracts, deliverables, exports, backups. Sooner or later, those files have to go somewhere. To your team, to a partner, to an auditor. And the second you start sharing, security stops being someone else's problem.

This is the playbook we use for building secure S3 file sharing, the parts that trip people up, and how to get each layer right.

Rule 1: Don't expose buckets directly. Ever.

The biggest, oldest mistake is making a bucket "just temporarily" public. Public bucket misconfigurations are still the cause of some of the largest data leaks on the internet. AWS has added a stack of guardrails (Block Public Access, explicit-deny bucket policies), but the only safe default is to never use bucket-level controls for user-facing sharing.

Everything goes through an authenticated API. Users never touch S3 directly. They sign in, the system checks what they're allowed to see, and only then does it generate a short-lived, scoped path to the specific file they're after. No exceptions.

Rule 2: Authenticate everything

You need a real identity layer. On AWS, Cognito User Pools are the obvious fit. Cognito handles registration, login, MFA, and tokens. Importantly, it federates over SAML 2.0 and OIDC, which means whatever your enterprise already runs (Okta, Azure AD, Google Workspace, Ping, anything standards-compliant), you can plug it in.

The flow you want:

  1. User logs in through Cognito, directly or via federated SSO
  2. Cognito hands back JWT tokens (ID, access, refresh)
  3. Every API call carries the token in the Authorization header
  4. The API validates the token, pulls out identity and group membership
  5. Authorization decisions happen based on those groups

This beats anything based on shared API keys, shared passwords, or URL tokens. The identity is a real person. Tokens expire on their own. If someone leaves, you disable them in Cognito and access dies the same minute.

Rule 3: Group-based access, mapped to prefixes

Not everyone gets to see everything. You need access control at the bucket and prefix level, mapped to user groups.

The pattern that works:

  • Cognito groups mirror your org structure ("finance", "external-auditors", "engineering")
  • Access policies map each group to specific bucket/prefix combinations
  • The API filters listings and downloads based on the requester's groups

Concrete example: "finance" gets s3://company-reports/quarterly/ and s3://company-reports/annual/. "external-auditors" gets only s3://company-reports/annual/audited/. Same bucket, different views.

The big win is that you're managing groups, not users. Someone joins the team? Add them to the Cognito group. Someone leaves? Remove them. You're not editing IAM policies or rebuilding bucket permissions every time HR sends an email.

Rule 4: Pre-signed URLs for the actual download

When a user clicks download, do not stream the file through your server or your Lambda. Generate a pre-signed S3 URL that grants temporary, scoped access to that one object, and let the browser pull it directly.

This buys you a few things at once:

  • Time-limited. URLs expire on a clock you set, usually 5–15 minutes
  • Object-scoped. Each URL is good for exactly one file
  • No credentials in flight. The URL holds a signature, not AWS credentials
  • No data path through your code. Bytes flow S3-to-browser directly. There's no proxy to scale, no proxy to secure, no proxy to break

The crucial bit: pre-signed URL generation has to come after the API has confirmed the user is who they say they are and is allowed to see this exact file. The URL is the delivery mechanism, not the gate.

Rule 5: Log everything you'd ever want to ask about later

SOC 2, HIPAA, ISO 27001 — they all want the same thing: who accessed what file, when, and from where. If you can't answer that quickly, you're going to have a bad audit.

What to capture:

  • User identity. Email, user ID, Cognito username. Whatever uniquely names the person
  • Action. Listed files, downloaded a file, browsed a folder
  • Resource. Bucket and object path
  • When. ISO 8601, UTC, no exceptions
  • Source IP and user agent

DynamoDB is a comfortable home for this kind of log in a serverless setup. It's durable, it scales, and it has TTL built in for aging records out. If you need long-term retention, stream into S3 via DynamoDB Streams and Kinesis Firehose.

S3 server access logs and CloudTrail are still useful — they catch the infrastructure-level view — but they don't know which application user triggered which action. You want both layers. App-level logs for the questions auditors ask, infra logs for the questions security asks.

Rule 6: Keep the data inside your account

For most enterprises, this is the one that matters more than any other. Files should never leave your AWS account. Full stop. That immediately rules out anything that proxies your data through a third-party service or stashes metadata externally.

The whole stack — app, auth, access control, audit logs, files — lives in one account, yours. No outbound calls to a vendor's API. No "we send anonymized telemetry, don't worry about it." Nothing.

This isn't just a compliance checkbox. It also makes your security review way shorter. There's no third-party DPA to negotiate, no cross-account audit, no external service to threat-model.

Putting it together

A good architecture is the boring sum of all six: real authentication, group-based access, pre-signed URLs, full audit logs, data that stays put. None of these are clever in isolation. The clever part is having them all working together without papering over the gaps.

You can absolutely build this from scratch. The pieces are well understood. You'll spend the time on the integration, the edge cases, and the long tail of "huh, didn't think about that" — and then the maintenance.

BucketDrive is all six rules, packaged. One CloudFormation stack into your AWS account. Cognito for auth, group-based access at bucket and prefix level, pre-signed URLs for downloads, every action logged to DynamoDB, all of it staying inside your account. If you've been wrestling with how to share S3 files without giving out console access, this is the shortest path to something secure that an auditor will sign off on.

Ready to simplify S3 file sharing?

BucketDrive implements enterprise-grade security out of the box. Deploys in 5 minutes. No servers to manage.

Try BucketDrive Free