Object storage – Versioning

Overview

Versioning allows to store multiple variants of an object in the same bucket.

Variants – also called versions – are identified with a unique version id in object’s metadata VersionId.


Every PUT action adds a new version that becomes current (meaning a GET will retrieve this version).

The previous current version of the object becomes non current and other versions are kept unmodified.


A DELETE action adds a delete marker that becomes current (meaning a GET will result in a “NoSuchKey” or “Not Found” error).

A delete marker contains no data.


The current object’s version, whether it’s data or a delete marker, is identified with the boolean metadata IsLatest value “true”.

Object’s versions are never deleted unless you specify a version id.


If a delete marker is current, a GET (without version id) will result in a NoSuchKey error.

If an object’s version is current, a GET (without version id) will retrieve this version.


Typical use cases: recover from accidental deletion or overwrite (unintended user actions or application failure).

Use cases with AWS CLI

AWS CLI (Command Line Interface) is an open source tool that enables you to configure and use object storage with commands in a text interface (Linux shell or Windows command line).

A user guide is available at https://docs.aws.amazon.com/cli/latest/userguide/.

Prerequisite : enable versioning

Versioning can be enabled at bucket level.

Check versioning state

Versioning enabled :

Versioning suspended (after being enabled) :

In default state (versioning has not been enabled), the request produces no output :

List object’s version and delete marker

Below, a list of object’s version and delete marker after the following actions (in a new bucket with versioning enabled):

  1. PUT object1 (size 102400 bytes)
  2. DELETE object1
  3. PUT object1 (size 1048576 bytes)

What happened :

  1. The initial PUT created a version that is not current anymore ("IsLatest": false) because of action 2.
  2. The DELETE created a delete marker that is not current anymore because of action 3.
  3. The last PUT created a version that is current ("IsLatest": true).

If you GET object1, you will retrieve the 1048576 bytes object.


Note that the list (JSON format) contains 2 arrays, one for versions and the other for delete markers.

Cancel previous action using DELETE with version id

By deleting either a version or a delete marker with a version id, it’s possible to go back in time (cancel previous actions).


Using the previous example (above), let’s go back to initial state in 2 steps:

  1. cancel the 2nd PUT by deleting a version
    (the delete marker becomes current)

2. cancel the DELETE by deleting a delete marker
(the initial object version becomes current)

Suspend versioning

Any existing object’s version and delete marker are kept intact.

Once versioning is suspended, version id will always be set to null.


PUT adds a new object’s version with version id null.

The object is overwritten if it already exists with version id null.

DELETE adds a new delete marker with version id null.

The current object’s version with version id null is deleted.

When an object is deleted, a PUT (same object) automatically removes the delete marker.

Best practices

About security

Never use a root Access Key

With a root AK, you can disable versioning and delete all object’s versions (including delete markers).

Restrict permissions

For everyday use (PUT objects in a bucket), you should apply a policy removing (deny) the following permissions :

  • s3:PutBucketVersioning (to prevent versioning change)
  • s3:DeleteObjectVersion (to prevent any delete of object’s version and delete marker)
  • s3:PutLifeCycleConfiguration (to prevent deleting with a lifecycle configuration)

Usage management

When versioning is enabled on a bucket, it is highly recommended to setup a lifecycle configuration.

It’s an easy way to keep control of your storage usage.


A bucket’s lifecycle configuration allows to automatically expire (delete):

  • non current object’s versions
  • obsolete delete markers (a delete marker with zero non current object’s version, useless because there’s no more data)
  • current object’s versions