Skip to content

Database-Level Access Control for Iceberg Catalog

info

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.

Overview

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.

Prerequisites

  • Your account must have Iceberg catalog resources provisioned (status: active)

Authentication

For authentication details and API endpoints by site, see Use Iceberg Catalog Management API.

Permission Model

Each permission entry has three components:

FieldDescriptionValues
resource_typeThe type of resourceDATABASE
resource_namesList of database namestd{account_id}_{site}_... or * (wildcard)
operationAccess level grantedFULL, READ, WRITE

Operations

OperationSQL Commands Allowed
FULLAll operations (SELECT, CREATE TABLE, DML, SHOW, etc.)
READSELECT, SHOW, information_schema access
WRITECREATE TABLE, CREATE TABLE AS, INSERT, UPDATE, DELETE, SHOW

Database Naming

  • 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.

API Endpoints

Update Permissions (Admin Only)

PUT /v1/iceberg/catalog/permissions
Authorization: TD1 <admin_api_key>
Accept: application/json
Content-Type: application/json

This 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 Example

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"
      }
    ]
  }'

Request Body

{
  "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.
    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.

Response

{
  "permissions": [
    {
      "resource_type": "DATABASE",
      "resource_names": ["td10000_us01_export"],
      "operation": "READ"
    }
  ]
}

The response shows permissions after automatic compaction (duplicate/redundant entries are merged).

Get Permissions

GET /v1/iceberg/catalog/permissions
Authorization: TD1 <your_api_key>
Accept: application/json

curl Example

# 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"

Query Parameters

ParameterRequiredDescription
user_idNoTarget user ID. Omit to view your own permissions. Admins can view any user.

Response

{
  "permissions": [
    {
      "resource_type": "DATABASE",
      "resource_names": ["td10000_us01_export"],
      "operation": "READ"
    }
  ]
}

Returns an empty list if the user has no permissions configured.

Common Tasks

Grant full access to the export database

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"
      }
    ]
  }'

Grant full access using wildcard

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"
      }
    ]
  }'

Grant read-only access

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"
      }
    ]
  }'

Grant write-only access

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"
      }
    ]
  }'

Revoke all permissions

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": []
  }'

Add a permission without removing existing ones

  1. First, GET the user's current permissions.
  2. Add the new permission entry to the list.
  3. PUT the combined list back.

Automatic Permission Compaction

The API automatically merges redundant permissions on write:

InputResult
FULL(*) + READ(td10000_us01_export)FULL(*)
READ(*) + READ(td10000_us01_export)READ(*)

Error Responses

StatusMeaning
400Invalid database name format
403Non-admin attempting to manage permissions, or write-only API key
404Target user not found or does not belong to your account
422Validation error (e.g., empty resource_names array)

Permission Evaluation

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
  • FULL permission implies both READ and WRITE
  • Users with no permissions have no access to any database