Image & Video APIs

Media access methods

Last updated: Aug-31-2025

By default, Cloudinary assets are accessible via a public CDN once uploaded using the upload delivery type. While you can use randomly generated public IDs to make URLs harder to guess, this alone doesn't prevent access.

For greater control, Cloudinary offers multiple access protection features, from simple delivery restrictions to advanced, token-based authentication.

Access protection options

Protect delivery and transformations

These options prevent unauthorized transformations and may also restrict access to original or derived assets.

Feature What it Does Best Used For
Transformation Control
Strict transformations Blocks on-the-fly transformations unless explicitly allowed (via eager, signed, or referral-domain sources). Preventing unauthorized manipulation of image and video transformations (e.g., removing overlays, bypassing cropping).
Restrictive Delivery Types
Set explicitly on upload
Private 1 Requires a signed URL to access the original asset, while derived versions remain public.

Use with strict transformations to prevent unauthorized creation of new derived assets.

Protecting original files while allowing public access variations (e.g., resized or watermarked).
Authenticated 1 Requires a signed URL to access both original and derived assets. Prevents users from guessing signed URLs or modifying their transformations. Fully restricts access to assets and transformations.
Enforcement Mechanism
Signed URLs 2 Authorizes access to private and authenticated assets, and dynamic transformations when using strict transformations.

Caution: Doesn't prevent link sharing. Once a URL is exposed (e.g., on your website), anyone with it can access the asset.

Validating URL authenticity and restricting unauthorized access.

Footnotes
  1. To prevent sensitive private and authenticated assets from appearing in search engine results, use the explicit endpoint's optional header parameter to include X-Robots-Tag: noindex when uploading or configuring the asset's response headers.
  2. You'll also need to sign delivery URLs when using transformation add-ons that require it (e.g., OCR Text Extraction and Cloudinary AI Content Analysis), or when delivering assets using the fetch delivery type if Fetched URL is selected as a Restricted media type in your product environment settings.

Control who can access assets and when

These options prevent access to existing files and control who can view them:

Feature What it Does Best Used For
Access Control
Access-controlled assets Requires a valid token or cookie to access.
(Allows you to define time-limited public access.)
Gaining full control over who can access an asset and when.
Time-limited public access Allows public access during a specific time window for otherwise restricted assets. Temporarily exposing an access-controlled asset before restricting it.
Token-based access
Premium feature
Appends a signed token to URLs to restrict access by time, IP, or a specific URL pattern (using an Access Control List). Delivering personalized or short-lived access (e.g., post-purchase, internal tools).
Cookie-based access
Premium feature + CNAME
Similar to token-based access, but uses a signed browser cookie instead of a URL token. Enforcing session-based access (e.g., logged-in web or mobile users).
Product Environment Rules
Product environment-level ACLs
Premium feature
Globally allows or blocks access based on IP, country, Referer, User-Agent, and more. Blocking unwanted traffic (e.g., bots, regions, or referrers) at the environment level.


Strict transformations

Cloudinary transformation URLs are dynamic by default. If a transformed version doesn't exist, it's generated on the fly. While flexible, this can lead to unintended usage (e.g., transformation spamming or bypassing overlays).

To prevent this, you can enable Strict Transformations from the Security page in your Cloudinary Console. Once enabled, transformations can only be created through:

Define allowed transformations

Once you've enabled strict transformations for your product environment, you can allow specific transformations either using the Admin API or the UI.

Using the Admin API

Using the update transformation method of the Admin API, set allowed_for_strict to true for the transformation you want to allow.

For example, allow a transformation by name (here, on_sale_overlay is a named transformation):

Or, allow a transformation by parameter listing:

Note
If running the CLI command on Windows, you need to escape the double quotes within the curly braces using either \ or ", for example, \"text\" or ""text"".

Using the UI

Open the Manage Transformations page in the Image product of the Console: Image > Manage Transformations.

You can find your transformations listed in both the Named Transformations or Log tabs.

For each relevant transformation, open the kebab menu and toggle the Allowed for strict transformations option.

enable transformation

Once allowed for strict transformations, you can use the transformation on any asset to generate and deliver the transformed version of that asset on the fly.

For transformations that aren't allowed, if you try to apply the transformation to an asset you'll see a 404 error.

Unique transformations

Some transformations deliver the same result, but aren't seen as identical by Cloudinary. Therefore, ensure you allow each variation of a transformation as required. Here are some examples where you may think the transformation is the same, but Cloudinary sees it as a different transformation:

  • If the order of the transformation parameters changes. For example, w_300,c_scale is 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, .jpg is 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_jpg as a transformation parameter for a JPEG file is considered a different transformation than delivering the same transformation with a .jpg extension, even though a JPEG file is delivered in each case.

Important
There are certain considerations to be aware of if enabling strict transformations after using your Cloudinary product environment for some time. For example, any derived asset generated while a particular transformation was still allowed, remains accessible until the cache is invalidated. You'll need to adapt certain transformation combinations to work with Strict Transformations enabled, so we recommend that you contact us to help identify any potential issues with the transition.

Using automatic format in strict transformations

You can specify f_auto (automatic format) in a transformation that you want to allow when you have strict transformations enabled because Cloudinary allows all format variations for the transformation in this case.

You can't use f_auto directly within a named transformation, so you need to combine f_auto and your named transformation, and then allow that transformation.

Here's one way to do that if you already have strict transformations enabled:

  1. Create a new transformation using the Transformation Builder. Save the transformation as a named transformation. In this example, it has the name scale356. Notice that the builder signs the delivery URL if you've enabled strict transformations.

    Transformation builder
  2. Use the Cloudinary CLI to create a signed URL for that named transformation together with the f_auto parameter. You can use any asset; in this example we use cld-sample-5.jpg:

  3. The CLI returns a signed URL, but doesn't create the derived asset. To create the derived asset, causing the t_scale356/f_auto transformation to be visible in the Log, use a cURL command to request the derived asset, for example:

  4. You'll then see the transformation t_scale356/f_auto present in the Log, which you can allow for strict transformations. Allow f_auto with a named transformation

Allowed strict referral domains

You can use the Allowed strict referral domains setting to set the referrer domains that you want to permit to generate unsigned transformations on the fly, even when you've got strict transformations enabled. Specify the domain(s) in the Security page of the Cloudinary Console Settings. Separate multiple domain entries with a newline.

Note
Keep in mind that this option only determines which referral domains can generate new unsigned transformations. It doesn't restrict other domains from accessing a transformation URL once the transformed asset is generated (via a signed request or by an allowed domain).

Restrictive delivery types

Delivery types control access behavior and must be set at upload using the type parameter. These delivery types do not work in isolation. They require signed URLs and may integrate with asset-level access control.

Private media assets

When you upload images and videos as private, the original file is protected and only accessible via a signed URL However, by default, any derived (transformed) versions of the asset are publicly accessible.

For example, the following delivery URL for the sample image returns an error:

https://res.cloudinary.com/demo/image/private/sample.jpg

But a derived version is accessible, such as the sample private image with a width of 300 pixels:

https://res.cloudinary.com/demo/image/private/w_300/sample.jpg

To deliver a derived version of a private asset, set the type parameter in the delivery URL to private (instead of the default upload).

To prevent public access even to derived assets, you can enable Strict Transformations which blocks transformation URLs unless they are explicitly whitelisted or signed.

Providing time-limited access to private media assets

You can make a private 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.

The generated URL delivers the image via a secure authenticated API request to Cloudinary each time. The image isn't cached on the CDN.

Important
You shouldn't embed these time-limited URLs on your website as they cost twice the bandwidth when delivering them.

Required parameters:

  • public_id - The identifier of the uploaded asset.
  • format - The asset file format.

Optional parameters:

  • resource_type - The resource type (image, video or raw) of the file to deliver. Default: image.
  • 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: one 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: false.
  • transformation - A transformation to apply to the delivered image or video (not currently supported by the SDKs).

Example 1: Image with default expiry time

Generate a link to the my_picID image in JPEG format, which is valid for one hour:

This generates a link similar to the following:

https://api.cloudinary.com/v1_1/private-demo/image/download?timestamp=1753601889&public_id=my_picID&format=jpg&signature=d994c2b972c30d84d33fde684aa377fc17878be6&api_key=824698761754661

Example 2: Video with extended expiry time

Generate a link to the my_video video in MP4 format, which is valid for two hours:

This generates a link similar to the following:

https://api.cloudinary.com/v1_1/private-demo/video/download?timestamp=1753443184&public_id=my_video&format=mp4&expires_at=1753450172&signature=013b1ff88c8b7e81ca9eb93ee5b31cce86ca709d&api_key=824698761754661

Authenticated media assets

When you upload images and videos as authenticated, the original file and any derived (transformed) versions are protected and only accessible via a signed URL.

For example, the following delivery URL for the auth_sample image returns an error:

https://res.cloudinary.com/demo/image/authenticated/auth_sample.jpg

Derived versions also return an error, such as the auth_sample image with a width of 300 pixels:

https://res.cloudinary.com/demo/image/authenticated/_w_300/auth_sample.jpg


To access the asset, you'll need to use the exact signature in the delivery URL:


You can’t create on-the-fly transformations for authenticated assets. Instead, you can only access derived assets that were generated ahead of time during upload or update using eager transformations. Each of these includes its own signature, which you can retrieve from the upload or update response.

Note
The 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.

Enforcement mechanism: Signed delivery URLs

A signed Cloudinary delivery URL is a delivery URL that has its signature validated before making the asset available for view (see the article about on-the-fly image transformations secured with signed urls for more details). Signed delivery URLs allow you to:

Note
You'll also need to sign delivery URLs when using transformation add-ons that require it (e.g., OCR Text Extraction and Cloudinary AI Content Analysis), or when delivering assets using the fetch delivery type if Fetched URL is selected as a Restricted media type in your product environment settings.

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 eight 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).

Note
By default, Cloudinary supports both SHA-1 and SHA-256 digests for validation, and you can use either. The SDK methods use the SHA-1 algorithm by default, but you can use the SHA-256 algorithm instead by setting the signature_algorithm SDK 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 eight 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 access token).

See also: Delivery URL signatures.

Access-controlled media assets

Access control allows you to restrict the validity of your asset delivery URLs, allowing access only via:

Important
Access control is available to all Cloudinary accounts. However, token-based and cookie-based access require the Advanced plan or higher. If your account doesn't support tokens, setting access_type: token will make the asset completely inaccessible, unless you define a public access time window.

To activate access control:

  • At a minimum, you must include { "access_type": "token" } in the access_control array at upload or update. This disables public access unless overridden by a matching token, signed cookie, or public time window rule.

    Example: Restrict the sample.jpg image to require secure delivery (via token, cookie, or public time window).

    Note
    If running the CLI command on Windows, you need to escape the double quotes within the curly braces using either \ or ", for example, \"text\" or ""text"".

Tips

Time-limited public access

You can include an anonymous access rule to make the asset temporarily available to the public during a defined time window, no token or authentication needed. Outside this window, access is blocked unless a valid token or cookie is provided.

Use cases include:

  • Post-purchase downloads

  • Temporary event or campaign materials

  • Embargoed content

To set time-limited public access:

  • Combine both token and anonymous rules in the access_control array. The asset will be delivered if either condition is valid.

    Example: Asset requires secure access, except between Dec 15, 2022 and Jan 20, 2024, when it's publicly accessible.

Token-based and cookie-based access (premium features)

Token-based and cookie-based access let you flexibly and securely restrict the delivery of media assets using signed tokens. Both methods use the same token format and enforce the same access rules. Token-based access adds the token as a query string to the URL, while cookie-based access stores the token in a browser cookie.

These features are available on the Advanced plan or higher. Contact us to receive an encryption key provisioned for your Cloudinary product environment. You need this key to generate tokens and cookies. We also configure your environment for token validation at the CDN level.

Important
Cookie-based access additionally requires using a Custom delivery hostname (CNAME) at additional cost.

The following access rules apply to both token-based and cookie-based access:

  • A specific time frame or expiration date

  • A specific IP address

  • A specific URL pattern (using an Access Control List)

To access an asset with "access_type": "token" (outside of any public access window, if defined) the request must include a valid signed token.

Important
Before you start, make sure that you have set up your framework to access Cloudinary's APIs. For details, see the relevant SDK framework documentation.

Generating access tokens (for token-based and cookie-based access)

For token-based (URL) access, pass the token parameters to a Cloudinary SDK method (e.g., cl_image_tag in Rails) using auth_token and sign_url: true, and the SDK generates and signs the token internally.

For cookie-based access, use the generate_auth_token method to generate the token string, which you then set as a browser cookie.

Shared token parameters

Both token-based (URL) and cookie-based access use the following parameters to define when and how to grant access:

  • 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, and restrict access to a specific path, or even to a specific asset. 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 can't 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.

1 Either duration or expiration must be provided (if both are provided, duration is ignored).

Delivering token-based media assets

When using Cloudinary SDKs to create delivery URLs (e.g., cl_image_tag or cl_video_tag in Rails), you can include a token in the URL by adding:

Example 1: To create a token-based access URL that restricts access to the sample authenticated image for 5 minutes and is signed with 'MyKey':


Example 2: To create a token-based access URL that restricts access to the dog authenticated video until 1/1/2018 (1514764800 in UNIX time) and is signed with 'MyKey':

Creating the access cookie

To create a cookie based access token, you pass the shared token parameters to generate_auth_token, and set the resulting string as the value of a browser cookie named __cld_token__.

Example 1: To create a cookie that's 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, where their public IDs start with 'eyes_only', only when the red, bold, 50-pixel-sized text 'Confidential' is added as a text overlay:


Cookie placement

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.

Product environment Access Control List (premium feature)

For each product environment, you can configure an Access Control List (ACL). This controls who can access your assets based on their country, IP address, the path segment of the request URL, content type, Referer and User-Agent.

Note
These options are available only for Cloudinary accounts on a paid plan.

To configure the ACL, navigate to the Delivery page of the Console Settings and set the ACL Settings.

ACL settings

  • Use * to match any number of characters at the start, middle or end of a string.
  • Use | to separate optional matches (OR operand).
  • Use ! to specify exceptions (NOT operand).
  • Use NULL for testing non-existent Referer and User-Agent strings.

The conditions are tested in the following order:

  1. If any of the ALLOW conditions match, the request is allowed and none of the DENY conditions are considered.
  2. If none of the ALLOW conditions match, the DENY conditions are considered.
  3. If any of the DENY conditions match, the request is denied, otherwise it’s allowed.

You can test out the logic by setting values in the ACL Tester tab.

Tip
Regardless of these settings, access to assets is still subject to the access control features described on this page.

✔️ Feedback sent!

Rate this page: