Generate signed URLs to upload and download OSS objects
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_OSScannot 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 |
| Yes | STRING | Full path of the Object Table in the three-layer model, such as | None |
| Yes | STRING | The name of the object to access in the Object Table. See the | None |
| No | INT | Validity period of the signed URL in seconds. Valid range: 1 to 604,800 (7 days). Cannot be used together with | 3600 |
| 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 | 3600 seconds after the current time |
| No | STRING | HTTP method for the signed URL. |
|
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
Log on to the OSS console and upload the test file signedget.txt to the
object-table-test/object_table_folderdirectory. See Upload files for instructions.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;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**** | +---------------+------------+------------+---------------------+---------------+----------------------------------+--------------+------------+--------------------+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 | +----------------------------------------+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
Log on to the ECS console. In the left navigation pane, choose Instances & Images > Instances.
Switch to the China (Hangzhou) region, select the target instance, click Remote Connection, and connect using Workbench.
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:

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
Prepare the signedput.txt test file and upload it to the
/optdirectory on the ECS instance.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:

Step 3: Verify the upload
Refresh the table cache:
ALTER TABLE test_get_signed_url_from_oss REFRESH METADATA;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**** | +------------+------------+------------+---------------+---------------+------------+--------------+------------+--------------------+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).