Generate signed URLs to upload and download OSS objects

Updated at:
Copy as MD

This topic describes how to use an Object Table to generate signed URLs for uploading and downloading OSS objects.

Background

When you use MaxCompute Object Tables to process unstructured data in OSS, downstream services — such as image processing pipelines or machine learning jobs running on ECS — need to access those OSS objects directly. Two common approaches exist, but both carry drawbacks:

  • Permanent AccessKeys — Storing AccessKeys in third-party services creates a security risk. If they leak, any unauthorized party can access your OSS data.

  • Service role assumption — The role that MaxCompute assumes to access OSS is separate from the role a third-party service must assume. Managing both roles adds complexity to your code.

OSS signed URLs let external services download or upload objects directly over HTTP — no credentials required in the third-party code. Generate a URL in MaxCompute SQL, pass it to the downstream service, and the service uses it within the validity window. This keeps your credentials out of third-party systems and simplifies authentication code.

GET_SIGNED_URL_FROM_OSS

GET_SIGNED_URL_FROM_OSS generates a credential-free signed URL for downloading or uploading an OSS object. The URL can be used directly over HTTP.

Limitations

  • Object Tables can only be created within the OSS internal network.

  • This function is not supported for MaxQA query acceleration. Add SET odps.mcqa.disable=true; and run it with your SQL statement.

  • If Block Public Access is enabled for the OSS bucket, GET_SIGNED_URL_FROM_OSS cannot generate a publicly accessible signed URL. Make sure the bucket permissions allow generating and using signed URLs.

Syntax

STRING GET_SIGNED_URL_FROM_OSS (
  STRING <full_object_table_name>,
  STRING <key>
  [, INT <timeToLiveSeconds>]
  [, DATETIME <expiration>]
  [, STRING <httpMethod>]
)

Parameters

Parameter

Required

Data type

Description

Default

full_object_table_name

Yes

STRING

Full path of the Object Table in the three-layer model, such as project.schema.object_table. If RoleARN authentication was selected when creating the table, this parameter triggers automatic generation of a Security Token Service (STS) token to access OSS.

None

key

Yes

STRING

The name of the object to access in the Object Table. See the key field description in View Object Table properties.

None

timeToLiveSeconds

No

INT

Validity period of the signed URL in seconds. Valid range: 1 to 604,800 (7 days). Cannot be used together with expiration.

3600

expiration

No

DATETIME

Expiration time of the signed URL. Must be at least 1 second after the current time and no more than 604,800 seconds (7 days) after the current time. Cannot be used together with timeToLiveSeconds.

3600 seconds after the current time

httpMethod

No

STRING

HTTP method for the signed URL. GET downloads the object (reads from OSS). PUT uploads the object (writes to OSS).

GET

Return value

Returns a STRING — the generated signed URL.

Overloaded signatures

The function supports the following parameter combinations:

  • Minimal — expires in 3,600 seconds, GET method:

    STRING get_signed_url_from_oss (
      STRING <fullTableName>,
      STRING <ossKey>
    );
  • Custom expiration (seconds) — GET method:

    STRING GET_SIGNED_URL_FROM_OSS(
      STRING <fullTableName>,
      STRING <ossKey>,
      INT <timeToLiveSeconds>
    );
  • Custom expiration (seconds) and HTTP method:

    STRING GET_SIGNED_URL_FROM_OSS(
      STRING <fullTableName>,
      STRING <ossKey>,
      INT <timeToLiveSeconds>,
      STRING <httpMethod>
    );
  • Custom expiration (DATETIME) — GET method:

    STRING GET_SIGNED_URL_FROM_OSS(
      STRING <fullTableName>,
      STRING <ossKey>,
      DATETIME <expiration>
    );
  • Custom expiration (DATETIME) and HTTP method:

    STRING GET_SIGNED_URL_FROM_OSS(
      STRING <fullTableName>,
      STRING <ossKey>,
      DATETIME <expiration>,
      STRING <httpMethod>
    );

Examples

The following examples use the China (Hangzhou) region. They show how to generate a signed URL and use it to download or upload an OSS object from an Elastic Compute Service (ECS) instance.

Replace project_name and schema_name with your actual project and schema names.

Download an OSS object from an ECS instance using a signed URL

Step 1: Generate a URL to download the OSS object

  1. Log on to the OSS console and upload the test file signedget.txt to the object-table-test/object_table_folder directory. See Upload files for instructions.

  2. Use a local client (odpscmd) or create a MaxCompute SQL node in DataWorks to create an Object Table and refresh its metadata cache.

    -- Object Tables in MaxCompute projects support schemas. Enable the three-layer model.
    SET odps.namespace.schema=true;
    
    -- Select the target MaxCompute project.
    USE <project_name>;
    
    -- Select the target schema.
    USE SCHEMA <schema_name>;
    
    -- Object Tables in MaxCompute projects support the 2.0 data type system.
    SET odps.sql.type.system.odps2=true;
    
    -- This feature is not currently supported for MaxQA query acceleration.
    SET odps.mcqa.disable=true;
    
    -- Create an Object Table.
    CREATE OBJECT TABLE IF NOT EXISTS test_get_signed_url_from_oss
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/object-table-test/object_table_folder/';
    
    -- Refresh the table cache.
    ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;
  3. Query the Object Table metadata.

    SELECT * FROM test_get_signed_url_from_oss;

    The following result is returned:

    +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+
    | key           | size       | type       | last_modified       | storage_class | etag                             | restore_info | owner_id   | owner_display_name |
    +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+
    | signedget.txt | 38         | Normal     | 2025-06-04 01:36:52 | Standard      | 96D8258845DAB51BC9B****6E61A2563 | NONE         | 13****     | 13****             |
    +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+
  4. Read the object data using the GET_DATA_FROM_OSS function.

    SELECT
      STRING(
        GET_DATA_FROM_OSS(
          '<project_name>.<schema_name>.test_get_signed_url_from_oss',
          key
        )
      )
    FROM test_get_signed_url_from_oss;

    The following result is returned:

    +----------------------------------------+
    | _c0                                    |
    +----------------------------------------+
    | test maxcompute download files by url  |
    +----------------------------------------+
  5. Query the Object Table and generate a signed URL.

    SELECT GET_SIGNED_URL_FROM_OSS(
      '<project_name>.<schema_name>.test_get_signed_url_from_oss',
      key)
    FROM test_get_signed_url_from_oss;

    The following result is returned:

    +------------+
    | _c0        |
    +------------+
    | http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsignedget.txt?Expires=17490****&OSSAccessKeyId=STS.****&Signature=****&security-token=**** |
    +------------+

Step 2: Download the object from an ECS instance

  1. Log on to the ECS console. In the left navigation pane, choose Instances & Images > Instances.

  2. Switch to the China (Hangzhou) region, select the target instance, click Remote Connection, and connect using Workbench.

  3. In the terminal, run the following commands to download the OSS object:

    # Switch to the /opt directory.
    cd /opt
    
    # Download the OSS object using the signed URL.
    curl -o /opt/ecs_signed.txt "http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsignedget.txt?Expires=17490****&OSSAccessKeyId=STS.****&Signature=****&security-token=****"

    The following figure shows the returned result:

    yuddd

Upload an OSS object from an ECS instance using a signed URL

Step 1: Generate a URL to upload the OSS object

Use the test_get_signed_url_from_oss Object Table created in the previous section. Query it with httpMethod set to PUT to generate an upload URL.

SELECT get_signed_url_from_oss(
  '<project_name>.<schema_name>.test_get_signed_url_from_oss',
  key,
  3600,
  'PUT'
)
FROM test_get_signed_url_from_oss;

The following result is returned:

+------------+
| _c0        |
+------------+
| http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsinged_put?Expires=17490****&OSSAccessKeyId=****&Signature=****&security-token=**** |
+------------+

Step 2: Upload the object from an ECS instance

  1. Prepare the signedput.txt test file and upload it to the /opt directory on the ECS instance.

  2. In the Workbench terminal, run the following command to upload the file to OSS:

    # Switch to the /opt directory.
    cd /opt
    
    # Upload signedput.txt to OSS using the signed URL.
    curl -X PUT -T /opt/signedput.txt -i "http://object-table-test.oss-cn-hangzhou-internal.aliyuncs.com/object_table_folder%2Fsinged_put?Expires=17490****&OSSAccessKeyId=****&Signature=****&security-token=****"

    The following figure shows the result:

    opopopo

Step 3: Verify the upload

  1. Refresh the table cache:

    ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;
  2. Query the Object Table metadata to confirm the uploaded object appears:

    SELECT * FROM test_get_signed_url_from_oss;

    The following result is returned:

    +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+
    | key        | size       | type       | last_modified | storage_class | etag       | restore_info | owner_id   | owner_display_name |
    +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+
    | signedget.txt | 38         | Normal     | 2025-06-03 01:36:52 | Standard      | 96D8258845DAB51BC****546E61A2563 | NONE         | 13**** | 13****   |
    | singed_put | 44         | Normal     | 2025-06-03 19:31:23 | Standard      | F5EA64DF895CF08C3****7D3FD09F12 | NONE         | 13**** | 13****   |
    +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+
  3. Read the uploaded object data to confirm the content:

    SELECT
      string(
        get_data_from_oss(
          '<project_name>.<schema_name>.test_get_signed_url_from_oss',
          key
        )
      )
    FROM test_get_signed_url_from_oss;

    The following result is returned:

    +------------+
    | _c0        |
    +------------+
    | test maxcompute download files by url  |
    | test  Object Table upload file to oss by url |
    +------------+

FAQ

The function returns an error about the table path not matching

The error message looks like:

ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: Can't do ObjectTableTwoPhasesSplitting process (Caused by: java.lang.IllegalArgumentException: The first arg[xxx.default.test_get_signed_url_from_ossxxxxxx] of function GET_SIGNED_URL_FROM_OSS({object_table_full_name}, {object_key}, ...) can't be found in the underlying object table scans[xxx.default.test_get_signed_url_from_oss])

The table name in the first argument doesn't match the table being queried in the FROM clause. Use the existing Object Table name in project.schema.table format, and make sure it matches the table in the FROM clause exactly.

The timeToLiveSeconds value is out of range

The error message looks like:

ODPS-0121095:[1,8] Invalid argument - The parameter <timeToLiveSeconds> of the function GET_SIGNED_URL_FROM_OSS() you specified (0) is invalid, it should be in the range [1, 604800]

Set timeToLiveSeconds to an integer between 1 and 604,800.

The httpMethod value is invalid

The error message looks like:

ODPS-0121095:[1,8] Invalid argument - The parameter <httpMethod> of the function GET_SIGNED_URL_FROM_OSS() you specified 'PU' is invalid, it can only be 'GET' or 'PUT'

httpMethod accepts only GET (download) or PUT (upload). Check for typos.

The curl command returns "Request has expired"

The signed URL expired before the curl command ran. This happens when the validity period is too short or there is a delay between generating the URL and using it. Set timeToLiveSeconds to a value that gives enough time to complete the operation, but avoid setting an unnecessarily long period.

The function cannot resolve the three-part table name

The error message looks like:

ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: Can't do ObjectTableTwoPhasesSplitting process (Caused by: java.lang.IllegalArgumentException: Invalid parameter of object table full name[str=xxx.test_get_signed_url_from_oss], which should be split up into 3 parts by '.' like '${project}.${schema}.${table}')

The schema syntax switch is not enabled. Add set odps.namespace.schema=true; before your SQL statement to enable three-layer model syntax (project.schema.table).