Skip to content

Manage the Reader Role Trust Policy

The table reader IAM role has a trust policy that controls which external services may assume it — Databricks, Snowflake, or BigQuery. This page shows you how to read the current policy and add a new integration without removing the ones already configured.

The update endpoint replaces the entire policy rather than merging into it. If you post only the entry you are adding, every other integration is dropped and stops working. Whenever an account already has an integration, add a new one with a read-modify-write flow: get the current policy, add your entry, then post the combined list.

Prerequisites

  • Iceberg catalog resources provisioned and active for your account (see Provision Resources)
  • The trust policy details for the integration you are adding — collected during that integration's setup (Databricks, Snowflake, or BigQuery)

Authentication

For authentication details and API endpoints by site, see Use Iceberg Catalog Management API. All trust policy operations are admin-only, and write-only API keys are rejected. Examples use the US endpoint — replace it with your site's endpoint.

Trust Policy Entries

A trust policy is a list of entries, one per service. Each entry has the same shape across both the get and update endpoints:

FieldDescription
serviceThe service allowed to assume the role: databricks, snowflake, or bigquery
iam_principal_arnsIAM principal ARNs allowed to assume the role. Required for databricks and snowflake; omit for bigquery. Up to 5.
external_idExternal ID for the assume-role condition.

A policy holds at most one entry per service. Posting two entries for the same service is rejected.

Get the Current Trust Policy

Retrieve the entries currently configured for the reader role:

curl "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/resources/reader_role/trust_policy" \
  -H "Authorization: TD1 <admin_api_key>" \
  -H "Accept: application/json"

The response returns 200 with the configured entries. For example, an account that already trusts Databricks returns:

{
  "entries": [
    {
      "service": "databricks",
      "iam_principal_arns": [
        "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
        "<iam_role_arn>"
      ],
      "external_id": "<databricks_external_id>"
    }
  ]
}

An account with no entries configured yet returns 200 with an empty list ({ "entries": [] }). A 404 means resources are not provisioned for the account — provision them first.

Append a New Integration

  1. Get the current policy with the request above and note every existing entry.
  2. Post the combined list: every existing entry, plus the entry for the new integration. This example adds Snowflake to an account that already trusts Databricks:
curl -X POST "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/resources/reader_role/trust_policy" \
  -H "Authorization: TD1 <admin_api_key>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "entries": [
      {
        "service": "databricks",
        "iam_principal_arns": [
          "arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL",
          "<iam_role_arn>"
        ],
        "external_id": "<databricks_external_id>"
      },
      {
        "service": "snowflake",
        "iam_principal_arns": ["<snowflake_iam_user_arn>"],
        "external_id": "<snowflake_external_id>"
      }
    ]
  }'

The endpoint returns 202 Accepted and applies the policy asynchronously by updating the underlying stack.

Important

Omitting an existing entry removes that integration's access. Always start from the output of the get endpoint so no entry is lost.

Remove an Integration

To revoke a service's access, post the policy without its entry. To remove all access, post an empty list:

curl -X POST "https://api-iceberg-mng.us01.treasuredata.com/v1/iceberg/catalog/resources/reader_role/trust_policy" \
  -H "Authorization: TD1 <admin_api_key>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{ "entries": [] }'

Verify the Result

Call the get endpoint again to confirm the policy contains exactly the entries you intend.

The get endpoint returns the intended policy — the value the service persisted — which during an in-flight update may not yet match the live IAM state. To confirm the update has fully applied, poll the Get Resource Status endpoint and wait for status to return to active.

Troubleshooting

SymptomPossible Cause
An existing integration stops working after an updateIts entry was omitted from the posted list — re-post with all entries included
400 Invalid trust policyA duplicate service entry, an unsupported field for the service, or a malformed ARN or external ID
404Resources are not provisioned for the account
409Resources are not in an updatable state — wait for status to return to active

Next Steps