Last updated: Oct-31-2023
When storing images, videos or other files in Cloudinary, both the originals and their transformed versions are publicly available through a CDN, by default. You can use randomly generated Public IDs for your assets, which makes it harder for end users to guess your media URLs, but you may want more formal ways to control who can access your media files and when.
|Strict transformations||Prevent transformations from being dynamically applied to media assets, except for any transformations that you specifically allow to be used dynamically, or that you have pre-generated.|
|Signed delivery URLs||A signed Cloudinary delivery URL is a dynamic URL that has its signature validated before making it available for view.|
|Private media assets||Original assets are only accessible by a signed URL.|
|Authenticated media assets||Original assets and their asset derivations are only accessible through signed URLs.|
|Access controlled media assets||Another layer separate from delivery type (upload / private / authenticated). Access-controlled assets can only be viewed with an authentication token, except during an optional time-limited date range when the asset is defined as publicly accessible.|
|Token-based authentication (premium feature)||Assets can be secured so that even if someone has the delivery URL they still need a token to access the asset. Tokens can be restricted to a specific time frame, IP address, a specific pattern ACL (Access Control List) or even a specific user (session cookie).|
|Allowlisting or blocklisting access to your product environment's assets (premium feature)||Submit a request to the Cloudinary support team with a list of ACLs to allow/block.|
Cloudinary's transformation URLs are dynamic, which means that if the requested transformed asset does not already exist, then it is created on the fly. This is a powerful feature, but you may not want your end users to play with these options on your assets. To control this, you can enable Strict Transformations in your product environment to prevent transformations from being dynamically applied to media assets. Except for any transformations that you specifically allow to be used dynamically, your users will be restricted to accessing only pre-generated transformed assets (generated eagerly during upload or with an authenticated request to our API). To allow the asset to be delivered, the file extension and the transformation part of the URL used to request an asset must be identical to one of the pre-generated transformations.
Enable the Strict Transformations setting in the Security page of your Cloudinary Console Settings. To mark a specific transformation as allowed, either use the Admin API, open the Named Transformations or Transformation Log pages of the console. Next to each transformation you can open the menu and toggle to either allow or restrict the transformation.
- If the order of the transformation parameters changes. For example,
w_300,c_scaleis considered a different transformation to
c_scale,w_300, even though the delivered media looks the same.
- If the file extension is different. For example,
.jpgis considered a different transformation than
.jpeg, or a JPEG file with no extension specified, even though a JPEG file is the delivered format in each case.
- Whether or not the file format is specified as a transformation. For example, specifying
f_jpgas a transformation parameter for a JPEG file is considered a different transformation than delivering the same transformation with a
.jpgextension, even though a JPEG file is delivered in each case.
Trying to dynamically generate and deliver an allowed transformation will work:
Trying to access any other transformation, either disallowed or non-existing, will not succeed.
Allowedtransformation is changed to
Disallowed. Any derived image that was generated while a particular transformation was still allowed, remains accessible. Certain transformation combinations also need to be adapted to work with Strict Transformations enabled, so we recommend that you contact us to help identify any potential issues with the transition.
It is possible to specify automatic format in a strict transformation, even though the
f_auto parameter is only converted to the relevant formats at the CDN level. Cloudinary takes this into account and allows all format variations for the transformation.
You cannot use
f_auto directly within a named transformation, so you will need to combine
f_auto and your named transformation in a dynamic transformation, and then allow that as a strict transformation.
For example, first create a new transformation named
mytx, then create a new dynamic transformation, select the named transformation
mytx as the base transformation, and add the automatic format parameter (
f_auto,t_mytx). You can then mark this new transformation as allowed.
You can use the Allowed strict referral domains setting to set the referrer domains that are allowed to generate unsigned dynamic transformations, even when strict transformations are enabled. This setting can be found in the Security page of the Cloudinary Console Settings.
A signed Cloudinary delivery URL is a dynamic URL that has its signature validated before making it available for view (see the article about on-the-fly image transformations secured with signed urls for more details). Signed delivery URLs are generally used to:
- Deliver specific derived assets when strict transformations are enabled
- Apply add-on based transformation directives that require signing the URL
- Fetch assets from specific URLs when "Fetched URLs" are restricted
- Allow access to private/authenticated assets
A signed delivery URL contains a signature component of the format
/s--SIGNATURE--/. The signature is automatically generated by Cloudinary's backend SDKs by adding the
sign_url boolean parameter to the helper method and setting it to true (you can manually generate a signature by taking the first 8 characters of a base64 encoding of an SHA digest of a 'public_id/transformation' string concatenated with your API secret. See Generating delivery URL signatures for more information).
signature_algorithmSDK configuration parameter to
sha256. If you want to limit your account to allow only the SHA-256 digest for all your validations, submit a request.
For example, to create an image tag for the authenticated image
secret_couple resized to a height and width of 300 pixels using the fill resize mode, while signing the transformation URL using the first 8 characters of an SHA signature.
And the same for a video tag, using the same transformations:
Once a derived image or video has been generated (whether dynamically on first access or eagerly during upload), the signature checking is skipped and the signature itself can be omitted (except for Authenticated assets, which always require either a signature or another authentication token).
Images and videos can be uploaded as
private to restrict access to the original asset and only allow access to derived (transformed) versions of the asset. The original asset can be accessed only with a signed URL, but by default, all derived versions of the asset are accessible. To deliver a transformation of an asset uploaded as private, set the
type parameter in the delivery URL to
private (instead of the default
An asset that was uploaded as 'private' cannot be accessed publicly without a signed URL. For example, the following delivery URL for the
sample image returns an error:
Delivering any derived versions of the image is still possible. For example, the
sample private image with a width of 300 pixels:
By default, all derived versions of the image are accessible, but the generation of derived images can also be restricted by activating the Strict Transformations mode. This mode prevents dynamically generating derived versions of the image, except for those that have been specifically enabled (e.g., with watermarks) that can then be generated on the fly. With Strict Transformations enabled you need to either eagerly generate all derived images or mark specific dynamic transformations as allowed.
You can make a private original asset temporarily accessible (for example, to enable a customer to access a stock photo on your site after purchasing it) by generating a time-limited and signed URL with the
private_download_url method of the Cloudinary API. For example, to generate a link to the
my_picID original image in JPEG format:
This generates a link similar to the following:
The generated URL delivers the image via a secure authenticated API request to Cloudinary each time. The image is not cached on the CDN.
public_id- The identifier of the uploaded asset.
format- The asset file format.
resource_type- The resource type (
raw) of the file to deliver. Default:
type- The delivery type of the file to deliver. Possible values: upload, private, authenticated, Default: private.
expires_at- The date (UNIX time in seconds) for the URL expiration. Default: 1 hour from the time the URL is generated.
attachment- If true, the URL downloads the image as an attachment. Otherwise, the image is displayed. Default:
Images and videos can be stored with an authenticated delivery type.
authenticated delivery type is an element of the URL. Therefore, an asset uploaded with this type is always an authenticated asset. Changing the type also requires changing the delivery URL, which can be done using the
to_type parameter of the Rename method.
When an asset is set as authenticated, access to both the original asset URLs and all derived (transformed) versions of the asset are restricted. These assets and their derived versions cannot be accessed without some form of authentication. This authentication can take one of the following forms:
Signed-URL authentication - Only for assets using the
- Token-based authentication (premium feature)
- Cookie-based authentication (premium feature)
Access to your assets can be controlled on an individual basis by restricting access to the asset to a specified time frame. If the current date does not fall within the time frame defined then the asset is not delivered.
You can set the access to your assets by passing the
access_control parameter when uploading or updating assets. The parameter accepts an array of access types for the asset, and the asset is accessible as long as one of the access types is valid. Possible values for each
access_type in the array:
token- Requires token based authentication to access the asset.
anonymousallows public access to the asset. The anonymous access type can optionally include start and/or end dates (in ISO 8601 format) that define when the asset is publicly available. You can only include a single 'anonymous' access type in the array.
For example, to set an asset as requiring token based authentication except for the period from the 15th of December 2022 until the 20th of January 2024 when it will be publically available:
The token-based authentication feature allows you to limit the validity of your asset delivery URLs and give access to your assets. This is also the only way to access any assets with an
access_control value of 'token'.
The validity of the token can be restricted in the following ways:
- To a specific time frame or expiration date
- To a specific IP address
- To a specific pattern ACL (Access Control List)
- To a specific user (session)
The authentication token can be used in one of 2 ways:
- Added as query parameters to a delivery URL, when generating the URL with one of Cloudinary SDK URL creation methods. See Delivering token-based authenticated media assets
- Set as a cookie so that only users with a valid cookie have access. See Cookie-based authentication
The basic features of each of the authentication options are summarized in the table below:
|Pattern-based access (ACL)||No||Yes||Yes|
|Customizable access per image||No||Yes||Yes|
The Cloudinary SDKs provide methods for creating delivery URLs (e.g., cl_image_tag and cl_video_tag in Rails). To create a token-based authentication URL for the asset, add the
sign_url parameter (set to
true) and the
auth_token parameter to the SDK method. The
auth_token parameter includes the following set of parameters:
key– (Required) - the token must be signed with the encryption key received from Cloudinary.
acl– (Optional) – an Access Control List for limiting the allowed URL path to a specified pattern (e.g., /video/authenticated/*). The pattern can include any of Cloudinary's transformations to also apply to the delivered assets. Note that if you add an overlay (e.g., for a watermark), you should also include the fl_layer_apply flag to ensure the layer cannot be modified. This parameter is useful for generating a token that can be added to a number of different URLs that share a common transformation. Without this parameter, the pattern defaults to the full URL path of the requested asset.
ip– (Optional) - only this IP address can access the resource.
start_time- (Optional) - timestamp of the UNIX time when the URL becomes valid. Default value: the current time.
duration– (Optional)1 – the duration that the URL is valid in seconds (counted from start_time).
expiration- (Optional)1 - timestamp in UNIX time when the URL expires.
expiration must be provided (if both are provided,
duration is ignored).
Example 1: To create a token-based authentication URL that allows access to the
sample authenticated image for 5 minutes and is signed with 'MyKey':
Example 2: To create a token-based authentication URL that allows access to the
dog authenticated video until 1/1/2018 (1514764800 in UNIX time) and is signed with 'MyKey':
The cookie-based authentication feature allows you to limit the delivery of authenticated assets, so that only users with a valid cookie have access.
An authentication cookie needs to be created for accessing authenticated assets with the
generate_auth_token method that accepts the following variables:
key– (Required) - the cookie must be signed with the encryption key received from Cloudinary.
acl– (Required) – an Access Control List for limiting the allowed URL path (e.g., /image/authenticated/*). The URL path can include any of Cloudinary's transformations to also apply to the delivered assets. You can also set multiple Access Control Lists by passing them as an array of values. Note that if you add an overlay (e.g., for a watermark), you should also include the fl_layer_apply flag to ensure the layer cannot be modified. See examples below.
ip– (Optional) – a specific IP Address that can access the authenticated assets.
duration– (Optional)1 – the duration that the cookie is valid in seconds. This value should be set reasonably, making sure to update the cookie as frequently as needed according to the desired session (e.g., matching the session expiration).
expiration- (Optional)1 - timestamp in UNIX time when the cookie will expire.
start_time- (Optional) - timestamp in UNIX time when the cookie becomes valid. Default value: the current time.
expiration must be provided (if both are provided,
duration is ignored).
Example 1: To create a cookie that is valid for 5 minutes (300 seconds), allows access to all authenticated images, and is signed with MY_KEY:
Example 2: For allowing access only to authenticated videos that are delivered with a specific named transformation (t_authorized):
The named transformation may add a watermark with the name of the employee, group or role who is accessing the image. In this case, a named transformation should be created via the Cloudinary Console for every user, group or role (respectively).
Example 3: For allowing access only when the name of the user is applied as a text overlay on the image:
So the following URL will be allowed (assuming the current user is John Smith):
But if a different user's name is applied, it won't match the cookie contents and will be unauthorized.
Example 4: For allowing access to authenticated images and videos, only when the red, bold, 50 pixel sized text 'Confidential' is added as a text overlay:
The cookie token returned from the
generate_auth_token method is a string that includes the cookie name (always
__cld_token__) and its value, for example:
Set the cookie on your main domain, e.g., app.customer.com or on the sub-domain that points to Cloudinary, e.g., images.app.customer.com.
You can submit a request to the Cloudinary support team to allowlist ACL access to your delivered assets, or conversely, you can request to blocklist certain ACLs from accessing your delivered assets. You can control access by providing one or more of the following types of ACL: Domain, IP, Country code, Path, User-Agent, Referer, and Content Type (Mime Type).
Keep in mind that if you choose the allowlist option, you must supply Cloudinary support with a complete list of every ACL to allow. For example, if you want to enable Facebook (or any other social network) to fetch your images or videos, make sure to include the relevant ACLs in the allowlist you supply.
With either of these options, the domains that you allow (via allowlist or those not specified in your blocklist) will still be limited as usual by any of the access control features described on this page.