I'm designing a multi-tenant workflow that generates HTML previews, documents, images, and intermediate files. Reviewers need short-lived access links, users must be isolated from one another, approved outputs must remain recoverable, and disposable intermediates should expire automatically. Would you use immutable object keys with a small manifest pointing to the current approved revision, or stable keys with S3 Versioning? I'd also like guidance on where to store metadata such as tenant and owner IDs, run IDs, approval state, content type, and retention policy; how narrowly to scope presigned URLs; and whether S3 Object Lock is useful or unnecessary. The goal is clear rollback and auditability without making every read perform a complicated lookup.
3 Answers
Separate approved artifacts from review and temporary data with prefixes or buckets, and apply different lifecycle rules and access policies to each. Keep content type and similar object-specific properties on the object itself, but don’t rely on S3 metadata for business state because overwrites and ad hoc uploads can make it unreliable. S3 Versioning is still useful as a recovery safeguard, but it shouldn’t replace immutable application-level revisions and an explicit approval pointer.
Use immutable keys for each generated revision, then keep a manifest or database record that identifies the current approved artifact. A failed upload or incorrect content type becomes an unused revision instead of silently replacing a working object, and rollback is just changing the approved pointer. For frequently accessed approved content, you can also materialize a stable alias, but treat the manifest as the source of truth. Validate that the artifact actually renders—not merely that the object returns HTTP 200.
S3 should hold the bytes, while a database such as DynamoDB or a relational store holds tenant ownership, run and revision IDs, approval status, current-version pointers, and audit events. Store immutable identifiers in the record and enforce tenant authorization before generating a presigned URL. Scope each URL to one exact object, use a short expiration, and issue it only after checking the caller’s permissions. Lifecycle rules can remove intermediate and rejected objects automatically, while approved revisions can use a longer retention policy.

Object Lock is worthwhile only when you have a compliance or tamper-resistance requirement, such as a mandatory retention period. For ordinary rollback, immutable keys, restricted delete permissions, versioning, and an audit log are usually simpler. If you do use Object Lock, apply it to approved or audit-critical objects rather than disposable review files.