This feature is not enabled on accounts by default. Contact Technical Support or your Customer Success representative to enable it.
This guide explains how to manage database-level permissions for the Iceberg Catalog using the Permission Management API.
The Permission Management API controls which users can access Iceberg catalog databases when querying from Data Workbench. Permissions are managed per-user and are scoped to databases within your TD account.
Scope: This access control applies only to queries executed via Data Workbench. It does not apply to access from cloud data warehouses (e.g., Databricks, Snowflake) or to Data Workbench databases.
Only admin users can manage permissions. Regular users can view their own permissions but cannot modify them.
- Your account must have Iceberg catalog resources provisioned (status:
active)
For authentication details and API endpoints by site, see Use Iceberg Catalog Management API.
Each permission entry has three components:
| Field | Description | Values |
|---|---|---|
resource_type | The type of resource | DATABASE |
resource_names | List of database names | td{account_id}_{site}_... or * (wildcard) |
operation | Access level granted | FULL, READ, WRITE |
| Operation | SQL Commands Allowed |
|---|---|
FULL | All operations (SELECT, CREATE TABLE, DML, SHOW, etc.) |
READ | SELECT, SHOW, information_schema access |
WRITE | CREATE TABLE, CREATE TABLE AS, INSERT, UPDATE, DELETE, SHOW |
- Example:
td10000_us01_export - Use
*to grant access to all databases in the account
You can only assign permissions for databases that belong to your own account. Cross-account database names are rejected.
PUT /v1/iceberg/catalog/permissions
Authorization: TD1 <admin_api_key>
Accept: application/json
Content-Type: application/jsonThis endpoint replaces all existing permissions for the target user. To add a permission, you must include all existing permissions in the request along with the new one.
curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "READ"
}
]
}'{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "READ"
}
]
}user_id(optional): Target user. Omit to update your own permissions.- You can find the user ID using the get user list API, for example:
curl -s -X GET https://api.treasuredata.com/v3/user/list -H "Authorization: TD1 <api_key>" | jq -cM '.users[] | [.id, .name]'permissions(required): Full list of permissions to set.
{
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "READ"
}
]
}The response shows permissions after automatic compaction (duplicate/redundant entries are merged).
GET /v1/iceberg/catalog/permissions
Authorization: TD1 <your_api_key>
Accept: application/json# Get your own permissions
curl "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <your_api_key>" \
-H "Accept: application/json"
# Get another user's permissions (admin only)
curl "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions?user_id=12345" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json"| Parameter | Required | Description |
|---|---|---|
user_id | No | Target user ID. Omit to view your own permissions. Admins can view any user. |
{
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "READ"
}
]
}Returns an empty list if the user has no permissions configured.
curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "FULL"
}
]
}'curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["*"],
"operation": "FULL"
}
]
}'curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "READ"
}
]
}'curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": [
{
"resource_type": "DATABASE",
"resource_names": ["td10000_us01_export"],
"operation": "WRITE"
}
]
}'Send an update with an empty permissions list. This removes all access for the user.
curl -X PUT "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/permissions" \
-H "Authorization: TD1 <admin_api_key>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"user_id": 12345,
"permissions": []
}'- First, GET the user's current permissions.
- Add the new permission entry to the list.
- PUT the combined list back.
The API automatically merges redundant permissions on write:
| Input | Result |
|---|---|
FULL(*) + READ(td10000_us01_export) | FULL(*) |
READ(*) + READ(td10000_us01_export) | READ(*) |
| Status | Meaning |
|---|---|
| 400 | Invalid database name format |
| 403 | Non-admin attempting to manage permissions, or write-only API key |
| 404 | Target user not found or does not belong to your account |
| 422 | Validation error (e.g., empty resource_names array) |
When a user runs a query, their permissions are evaluated as follows:
- Permissions are combined disjunctively (union/OR logic)
- If any permission grants access to the requested database and operation, access is allowed
- Wildcard (
*) matches all databases in the account FULLpermission implies bothREADandWRITE- Users with no permissions have no access to any database