> ## Documentation Index
> Fetch the complete documentation index at: https://firebolt-aggregate-helm-docs-pr-38.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Reference and syntax for creating Iceberg locations.

# CREATE LOCATION (Iceberg)

For an overview of querying, tuning, and exporting Iceberg tables, see the [Iceberg guide](/guides/iceberg-and-data-lake/iceberg).

Creates a new location object in your Firebolt account, which is a secure, reusable object that stores the connection details and credentials for Iceberg data sources. Instead of entering these details each time you run a query or create a table, you can use a location object.

This document captures the syntax and examples for location objects for Iceberg. For a comprehensive guide to LOCATION objects, see [LOCATION objects](/security/guides/location). For more on location objects syntax in general, see [CREATE LOCATION](/reference-sql/commands/data-definition/create-location).

Iceberg locations currently support six catalog types: `REST`, `FILE_BASED`, `DATABRICKS_UNITY` (as syntactic sugar on top of `REST`), `SNOWFLAKE_OPEN_CATALOG` (a `REST`-shaped catalog), `AWS_GLUE`, and `S3_TABLES`. Each catalog accepts a different set of parameters and credentials. Some vendor catalogs are served by these types rather than by a dedicated keyword: use `REST` for [Snowflake Horizon Catalog](#snowflake-horizon-catalog). Amazon S3 Tables can be reached either through the dedicated [`S3_TABLES`](#s3-tables-catalog) catalog or through [`AWS_GLUE`](#aws-glue-catalog).

## Syntax

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION [ IF NOT EXISTS ] <location_name> WITH
  SOURCE = ICEBERG
  CATALOG = { FILE_BASED | REST | DATABRICKS_UNITY | SNOWFLAKE_OPEN_CATALOG | AWS_GLUE | S3_TABLES }
  CATALOG_OPTIONS = {
    -- FILE_BASED
    ( URL = '<file_based_catalog_url>' )
    |
    -- REST or SNOWFLAKE_OPEN_CATALOG
    ( URL = '<rest_catalog_url>'
      WAREHOUSE = '<warehouse>'
      [ NAMESPACE = '<namespace>' ]
      [ TABLE = '<table_name>' ] )
    |
    -- DATABRICKS_UNITY
    ( WORKSPACE_INSTANCE = '<workspace_instance>'
      CATALOG = '<uc_catalog_name>'
      SCHEMA = '<uc_schema_name>'
      TABLE = '<uc_table_name>' )
    |
    -- AWS_GLUE
    ( URL = '<aws_glue_endpoint_url>'
      CATALOG_ID = '<catalog_id>'
      [ DATABASE = '<database_name>' ]
      [ TABLE = '<table_name>' ] )
    |
    -- S3_TABLES
    ( WAREHOUSE = '<table_bucket_arn>'
      [ URL = '<s3_tables_endpoint_url>' ]
      [ NAMESPACE = '<namespace>' ]
      [ TABLE = '<table_name>' ] )
  }
  CREDENTIALS = {
    -- AWS Authentication
    ( AWS_ACCESS_KEY_ID = '<aws_access_key_id>'
      AWS_SECRET_ACCESS_KEY = '<aws_secret_access_key>'
      [ AWS_SESSION_TOKEN = '<aws_session_token>' ] )
    |
    ( AWS_ROLE_ARN = '<aws_role_arn>'
      [ AWS_ROLE_EXTERNAL_ID = '<aws_role_external_id>' ] )
    |
    -- OAuth Authentication
    ( OAUTH_CLIENT_ID = '<oauth_client_id>'
      OAUTH_CLIENT_SECRET = '<oauth_client_secret>'
      [ OAUTH_SCOPE = '<oauth_scope>' ]
      [ OAUTH_SERVER_URL = '<oauth_server_url>' ] )
    |
    ( BEARER_TOKEN = '<bearer_token>' )
  }
  -- STORAGE_CREDENTIALS: REST, DATABRICKS_UNITY, SNOWFLAKE_OPEN_CATALOG only
  [ STORAGE_CREDENTIALS = {
      ( AWS_ACCESS_KEY_ID = '<aws_access_key_id>'
        AWS_SECRET_ACCESS_KEY = '<aws_secret_access_key>'
        [ AWS_SESSION_TOKEN = '<aws_session_token>' ] )
      |
      ( AWS_ROLE_ARN = '<aws_role_arn>'
        [ AWS_ROLE_EXTERNAL_ID = '<aws_role_external_id>' ] )
    } ]
  [ DESCRIPTION = '<description>' ]
```

## Parameters

### Common Parameters

| Parameter         | Description                                                                                                                                                                                                                   |
| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<location_name>` | A unique identifier for the location within your account.                                                                                                                                                                     |
| `SOURCE`          | The external data source type. Currently, `CLOUD_STORAGE` and `ICEBERG` are supported. Additionally, `AMAZON_S3` is supported as an alias for `CLOUD_STORAGE` with an S3 URL. This should be `ICEBERG` for Iceberg locations. |
| `DESCRIPTION`     | Optional metadata describing the location's purpose.                                                                                                                                                                          |

### Iceberg Parameters

| Parameter             | Description                                                                                                                                                                                                                                                 |
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CATALOG`             | The type of Iceberg catalog. Supported values: `FILE_BASED`, `REST`, `DATABRICKS_UNITY`, `SNOWFLAKE_OPEN_CATALOG`, `AWS_GLUE`, or `S3_TABLES`.                                                                                                              |
| `CATALOG_OPTIONS`     | Configuration options specific to the chosen catalog type.                                                                                                                                                                                                  |
| `CREDENTIALS`         | Authentication credentials for accessing the Iceberg catalog. Depending on the type of catalog, either AWS or OAuth credentials are used.                                                                                                                   |
| `STORAGE_CREDENTIALS` | Optional AWS object-storage credentials for `REST`, `DATABRICKS_UNITY`, and `SNOWFLAKE_OPEN_CATALOG` catalogs, used as a fallback if the catalog does not have credential vending enabled. Accepts the same AWS authentication parameters as `CREDENTIALS`. |

#### AWS Authentication Parameters

Use AWS authentication parameters for `FILE_BASED`, `AWS_GLUE`, and `S3_TABLES` catalogs.

| Parameter               | Description                                                      |
| :---------------------- | :--------------------------------------------------------------- |
| `AWS_ACCESS_KEY_ID`     | Your AWS access key ID for key-based authentication.             |
| `AWS_SECRET_ACCESS_KEY` | Your AWS secret access key for key-based authentication.         |
| `AWS_SESSION_TOKEN`     | Optional temporary session token for temporary credentials.      |
| `AWS_ROLE_ARN`          | The ARN of the IAM role to assume for role-based authentication. |
| `AWS_ROLE_EXTERNAL_ID`  | Optional external ID for role assumption.                        |

#### OAuth Authentication Parameters

Use OAuth authentication parameters for `REST`, `DATABRICKS_UNITY`, or `SNOWFLAKE_OPEN_CATALOG` catalogs.

| Parameter             | Description                                                                                                                                                                                                                                                                                              |
| :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OAUTH_CLIENT_ID`     | The OAuth client ID for authentication. Optional: omit it to authenticate with `OAUTH_CLIENT_SECRET` alone (a secret-only flow), as required by Snowflake Horizon Catalog and other REST catalogs that use a token as the secret. Providing `OAUTH_CLIENT_ID` without `OAUTH_CLIENT_SECRET` is rejected. |
| `OAUTH_CLIENT_SECRET` | The OAuth client secret for authentication.                                                                                                                                                                                                                                                              |
| `OAUTH_SCOPE`         | Optional OAuth scope for authentication.                                                                                                                                                                                                                                                                 |
| `OAUTH_SERVER_URL`    | Optional OAuth server URL for authentication.                                                                                                                                                                                                                                                            |
| `BEARER_TOKEN`        | OAuth bearer token for authentication. Only supported for `DATABRICKS_UNITY` catalog.                                                                                                                                                                                                                    |

#### Iceberg Catalog-Specific Parameters

##### FILE\_BASED Catalog

| Parameter | Description                                                      |
| :-------- | :--------------------------------------------------------------- |
| `URL`     | The URL for the file-based catalog. This must be a valid S3 URL. |

##### REST Catalog

| Parameter   | Description               |
| :---------- | :------------------------ |
| `URL`       | The REST catalog URL.     |
| `WAREHOUSE` | The warehouse identifier. |
| `NAMESPACE` | The namespace identifier. |
| `TABLE`     | The table name.           |

##### SNOWFLAKE\_OPEN\_CATALOG Catalog

Snowflake Open Catalog is a `REST`-shaped catalog and takes the same parameters as `REST`.

| Parameter   | Description                          |
| :---------- | :----------------------------------- |
| `URL`       | The Snowflake Open Catalog REST URL. |
| `WAREHOUSE` | The warehouse identifier.            |
| `NAMESPACE` | The namespace identifier.            |
| `TABLE`     | The table name.                      |

##### DATABRICKS\_UNITY Catalog

| Parameter            | Description                        |
| :------------------- | :--------------------------------- |
| `WORKSPACE_INSTANCE` | The Databricks workspace instance. |
| `CATALOG`            | The Unity Catalog name.            |
| `SCHEMA`             | The Unity Catalog schema name.     |
| `TABLE`              | The Unity Catalog table name.      |

##### AWS\_GLUE Catalog

The `AWS_GLUE` catalog serves both the AWS Glue Data Catalog and Amazon S3 Tables, which are read through the same Glue Iceberg REST endpoint. The two differ only in `CATALOG_ID`.

| Parameter    | Description                                                                                                                                                                                                                                                                                              |
| :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `URL`        | The AWS Glue endpoint URL. Format: `https://glue.<region>.amazonaws.com/iceberg`                                                                                                                                                                                                                         |
| `CATALOG_ID` | The AWS Glue catalog ID. For the Glue Data Catalog, this is your AWS account ID and must be the default catalog for your account; nested and named catalogs are not currently supported. For an S3 Tables table bucket, use the S3 Tables catalog ID `<account_id>:s3tablescatalog/<table_bucket_name>`. |
| `DATABASE`   | The database (namespace) name.                                                                                                                                                                                                                                                                           |
| `TABLE`      | The table name.                                                                                                                                                                                                                                                                                          |

##### S3\_TABLES Catalog

<span className="feature-tag">Nightly Feature</span>

| Parameter   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| :---------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WAREHOUSE` | The Amazon S3 Tables table-bucket ARN. Format: `arn:aws:s3tables:<region>:<account_id>:bucket/<bucket_name>`. Required. Firebolt derives the signing region from the ARN.                                                                                                                                                                                                                                                                                 |
| `URL`       | Optional. The S3 Tables Iceberg REST endpoint. Format: `https://s3tables.<region>.amazonaws.com/iceberg`. When omitted, it is derived from the ARN for standard AWS Regions (the `aws` partition). Provide it explicitly for other partitions (for example AWS GovCloud `aws-us-gov`), for FIPS endpoints, and for PrivateLink or other custom hosts; a table-bucket ARN in a non-standard partition without `URL` is rejected at `CREATE LOCATION` time. |
| `NAMESPACE` | Optional. Restricts the location to a single namespace. Omit it to attach the whole catalog with [`CREATE ICEBERG DATABASE`](/reference-sql/commands/data-definition/create-iceberg-database).                                                                                                                                                                                                                                                            |
| `TABLE`     | Optional. Pins the location to a single table. Requires `NAMESPACE`.                                                                                                                                                                                                                                                                                                                                                                                      |

## Examples

<Tip>
  **Register Iceberg tables for easy querying.** You can use [`CREATE ICEBERG TABLE`](/reference-sql/commands/data-definition/create-iceberg-table) to register an Iceberg table in Firebolt's catalog, allowing you to query it with regular `SELECT` statements. To query every table in a catalog without registering each one, mount the catalog with [`CREATE ICEBERG DATABASE`](/reference-sql/commands/data-definition/create-iceberg-database); this requires a catalog-scoped LOCATION (no `NAMESPACE`, `DATABASE`, `SCHEMA`, or `TABLE` in `CATALOG_OPTIONS`). Alternatively, wrap `READ_ICEBERG` calls in a [view](/reference-sql/commands/data-definition/create-view). See [Simplifying queries with views](/reference-sql/functions-reference/iceberg/read_iceberg#simplifying-queries-with-views) for examples.
</Tip>

### File-based catalog

Used to access Iceberg tables directly from S3.

For file-based Iceberg catalogs, use AWS key-based or role-based authentication in `CREDENTIALS`.

**With access key and secret:**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = FILE_BASED
  CATALOG_OPTIONS = (
    URL = 's3://my-bucket/path/to/iceberg/table'
  )
  CREDENTIALS = ( AWS_ACCESS_KEY_ID = '1231' AWS_SECRET_ACCESS_KEY = '567' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

**With access key, secret, and session token:**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = FILE_BASED
  CATALOG_OPTIONS = (
    URL = 's3://my-bucket/path/to/iceberg/table'
  )
  CREDENTIALS = ( AWS_ACCESS_KEY_ID = '1231' AWS_SECRET_ACCESS_KEY = '567' AWS_SESSION_TOKEN = 'session-token' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

**With role and external id (recommended):**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = FILE_BASED
  CATALOG_OPTIONS = (
    URL = 's3://my-bucket/path/to/iceberg/table'
  )
  CREDENTIALS = ( AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/S3Access' AWS_ROLE_EXTERNAL_ID = 'my-external-id' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

<Note>
  For role-based AWS access you can additionally set an external ID. An external ID is a value you choose and control that AWS checks when Firebolt assumes your role, adding a second condition on top of your account's unique IAM principal. Configuring one is a recommended best practice. See [IAM roles](/security#iam-roles).
</Note>

**With role only:**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = FILE_BASED
  CATALOG_OPTIONS = (
    URL = 's3://my-bucket/path/to/iceberg/table'
  )
  CREDENTIALS = ( AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/S3Access' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

### REST catalog

Used to access Iceberg in REST catalogs, that implement the [Iceberg REST API spec](https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml).

For generic REST Iceberg catalogs, use OAuth parameters for `CREDENTIALS`.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = REST
  CATALOG_OPTIONS = (
    URL = 'https://my-iceberg-rest-catalog/api'
    WAREHOUSE  = 'my_warehouse'
    NAMESPACE = 'my_namespace'
    TABLE = 'my_table_name'
  )
  CREDENTIALS = (
    OAUTH_CLIENT_ID = '00000000-0000-0000-0000-000000000000'
    OAUTH_CLIENT_SECRET = '1234'
    OAUTH_SCOPE = 'example_permission:all'
    -- OAUTH_SERVER_URL is only needed for REST catalogs that don't support the /v1/oauth/tokens endpoint. If /v1/oauth/tokens is supported, it can be omitted.
    OAUTH_SERVER_URL = 'https://my-iceberg-rest-catalog/example/token'
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

**With a storage credential fallback:**

Add `STORAGE_CREDENTIALS` with AWS object-storage credentials, used as a fallback if the catalog does not have credential vending enabled.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = REST
  CATALOG_OPTIONS = (
    URL = 'https://my-iceberg-rest-catalog/api'
    WAREHOUSE  = 'my_warehouse'
    NAMESPACE = 'my_namespace'
    TABLE = 'my_table_name'
  )
  CREDENTIALS = (
    OAUTH_CLIENT_ID = '00000000-0000-0000-0000-000000000000'
    OAUTH_CLIENT_SECRET = '1234'
  )
  STORAGE_CREDENTIALS = (
    AWS_ACCESS_KEY_ID = '1231'
    AWS_SECRET_ACCESS_KEY = '567'
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

`STORAGE_CREDENTIALS` also accepts role-based AWS authentication (`AWS_ROLE_ARN`, optional `AWS_ROLE_EXTERNAL_ID`) and works the same way on `DATABRICKS_UNITY` and `SNOWFLAKE_OPEN_CATALOG` locations.

### Databricks Unity Catalog

Used to access Iceberg tables in a Databricks Unity Catalog. Offered as syntactic sugar on top of `CATALOG = REST`, for users who may be more familiar with Databricks Unity Catalog terminology.

For configuring Unity Catalog in your Databricks workspace, see [Databricks - Set up and manage Unity Catalog](https://docs.databricks.com/aws/en/data-governance/unity-catalog/get-started). Note that you will need to enable credential vending in your Unity Catalog, see [Databricks - Unity Catalog credential vending for external system access](https://docs.databricks.com/aws/en/external-access/credential-vending).
For general information about reading Databricks tables from Iceberg clients, see [Databricks - Read Databricks tables from Iceberg clients](https://docs.databricks.com/gcp/en/external-access/iceberg).

For Databricks Unity Catalogs, use OAuth parameters for `CREDENTIALS`.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = DATABRICKS_UNITY
  CATALOG_OPTIONS = (
    WORKSPACE_INSTANCE = '000-0000000000000.cloud.databricks.com'
    CATALOG  = 'my_uc_catalog_name'
    SCHEMA = 'my_uc_schema_name'
    TABLE = 'my_uc_table_name'
  )
  CREDENTIALS = (
    OAUTH_CLIENT_ID = '00000000-0000-0000-0000-000000000000'
    OAUTH_CLIENT_SECRET = '1234'
    -- OAUTH_SCOPE and OAUTH_SERVER_URL are not needed
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

If you're using a PAT [Databricks - Authenticate with Databricks personal access tokens (legacy)](https://docs.databricks.com/aws/en/dev-tools/auth/pat), you can pass it via the `BEARER_TOKEN` parameter.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = DATABRICKS_UNITY
  CATALOG_OPTIONS = (
    WORKSPACE_INSTANCE = '000-0000000000000.cloud.databricks.com'
    CATALOG  = 'my_uc_catalog_name'
    SCHEMA = 'my_uc_schema_name'
    TABLE = 'my_uc_table_name'
  )
  CREDENTIALS = (
    BEARER_TOKEN = '1234abcd'
    -- No OAUTH_ parameters are needed
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

### Snowflake Open catalog

Iceberg tables in Snowflake Open Catalog can be read by using a `LOCATION` with `CATALOG = SNOWFLAKE_OPEN_CATALOG`, a `REST`-shaped catalog.

For setting up a Snowflake Open Catalog in your account, see [Snowflake - Snowflake Open Catalog overview](https://other-docs.snowflake.com/en/opencatalog/overview). Note that you will need to enable credential vending for your Iceberg tables, see [Snowflake - Use catalog-vended credentials for Apache Iceberg™ tables](https://docs.snowflake.com/en/user-guide/tables-iceberg-configure-catalog-integration-vended-credentials).
For general information about reading Snowflake Open Catalog tables from Iceberg clients, see [Snowflake - Checking your REST catalog configuration](https://docs.snowflake.com/en/user-guide/tables-iceberg-configure-catalog-integration-rest-check-config).

For Snowflake Open catalogs, use OAuth parameters for `CREDENTIALS`.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = SNOWFLAKE_OPEN_CATALOG
  CATALOG_OPTIONS = (
    URL = 'https://abc123.us-west-2.aws.myapi.com/polaris/api/catalog'
    WAREHOUSE  = 'my_warehouse'
    NAMESPACE = 'my_catalog_name'
    TABLE = 'my_table_name'
  )
  CREDENTIALS = (
    OAUTH_CLIENT_ID = '00000000-0000-0000-0000-000000000000'
    OAUTH_CLIENT_SECRET = '1234'
    OAUTH_SCOPE = 'PRINCIPAL_ROLE:ALL'
    -- OAUTH_SERVER_URL is not needed
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

### Snowflake Horizon Catalog

Iceberg tables managed by Snowflake Horizon Catalog are read through Snowflake's Iceberg REST endpoint, so use `CATALOG = REST`.

Snowflake Horizon Catalog authenticates with a Snowflake [Programmatic Access Token (PAT)](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens), which is a single token rather than a client ID and secret pair. Pass the PAT as `OAUTH_CLIENT_SECRET` and omit `OAUTH_CLIENT_ID`.

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = REST
  CATALOG_OPTIONS = (
    URL = 'https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog'
    WAREHOUSE  = 'my_catalog'
    NAMESPACE = 'my_database.my_schema'
    TABLE = 'my_table_name'
  )
  CREDENTIALS = (
    -- Snowflake PAT passed as the client secret; OAUTH_CLIENT_ID is omitted
    OAUTH_CLIENT_SECRET = 'my_snowflake_pat'
  );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

### AWS Glue catalog

Used to access Iceberg tables in AWS Glue Data Catalog.

**With access key and secret:**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = AWS_GLUE
  CATALOG_OPTIONS = (
    URL = 'https://glue.us-east-1.amazonaws.com/iceberg'
    CATALOG_ID = '123456789123'
    DATABASE = 'my_database'
    TABLE = 'my_table'
  )
  CREDENTIALS = ( AWS_ACCESS_KEY_ID = '1231' AWS_SECRET_ACCESS_KEY = '567' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

**With role and external id (recommended):**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = AWS_GLUE
  CATALOG_OPTIONS = (
    URL = 'https://glue.us-east-1.amazonaws.com/iceberg'
    CATALOG_ID = '123456789123'
    DATABASE = 'my_database'
    TABLE = 'my_table'
  )
  CREDENTIALS = ( AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/GlueAccess' AWS_ROLE_EXTERNAL_ID = 'my-external-id' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

**Amazon S3 Tables:**

Amazon S3 Tables can also be reached through AWS Glue's Iceberg REST endpoint: use `CATALOG = AWS_GLUE` with the S3 Tables catalog ID `<account_id>:s3tablescatalog/<table_bucket_name>` as `CATALOG_ID`. For a direct connection that doesn't go through Glue, see [S3 Tables catalog](#s3-tables-catalog).

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH 
  SOURCE = ICEBERG
  CATALOG = AWS_GLUE
  CATALOG_OPTIONS = (
    URL = 'https://glue.us-east-1.amazonaws.com/iceberg'
    CATALOG_ID = '123456789123:s3tablescatalog/my-table-bucket'
    DATABASE = 'my_database'
    TABLE = 'my_table'
  )
  CREDENTIALS = ( AWS_ROLE_ARN = 'arn:aws:iam::123456789123:role/S3TablesAccess' AWS_ROLE_EXTERNAL_ID = 'my-external-id' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

Reading S3 Tables requires `s3tables` and `glue` read permissions plus `lakeformation:GetDataAccess`. See [Amazon S3 Tables](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables.html) for setup.

<Note>
  For role-based AWS access you can additionally set an external ID. An external ID is a value you choose and control that AWS checks when Firebolt assumes your role, adding a second condition on top of your account's unique IAM principal. Configuring one is a recommended best practice. See [IAM roles](/security#iam-roles).
</Note>

Your IAM credentials must have the following permissions:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGlueCatalogTableAccess",
            "Effect": "Allow",
            "Action": [
                "glue:GetCatalog",
                "glue:GetDatabase",
                "glue:GetDatabases",
                "glue:GetTable",
                "glue:GetTables"
            ],
            "Resource": [
                "arn:aws:glue:*:{catalog_id}:table/*/*",
                "arn:aws:glue:*:{catalog_id}:catalog",
                "arn:aws:glue:*:{catalog_id}:database/{database_name}"
            ]
        }
    ]
}
```

Your IAM credentials must also have permissions to access the underlying S3 storage. See [Use AWS roles to access S3](/guides/loading-data/configuring-aws-role-to-access-amazon-s3) for details. (Note that this may not be needed if you are using Lake Formation to manage access.)

**(Optional) Lake Formation**

If you use Lake Formation for access control, you'll need to grant your IAM credentials permissions to Lake Formation, and register the underlying S3 location with Lake Formation:

Your IAM credentials will need the `GetDataAccess` permission - see [AWS Lake Formation: Underlying data access control](https://docs.aws.amazon.com/lake-formation/latest/dg/access-control-underlying-data.html).

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lakeformation:GetDataAccess",
            "Resource": "*"
        }
    ]
}
```

You'll need to register your underlying S3 storage location with Lake Formation - see [AWS Lake Formation: Adding an Amazon S3 location to your data lake](https://docs.aws.amazon.com/lake-formation/latest/dg/register-data-lake.html).

If you want Lake Formation to vend temporary credentials to access your underlying storage, you will need to configure Lake Formation to allow Firebolt's external engine to access data in your S3 - see [AWS Lake Formation: Application integration for full table access](https://docs.aws.amazon.com/lake-formation/latest/dg/full-table-credential-vending.html).

If credential vending is enabled, it is recommended to *not* grant your IAM credentials access to your underlying S3 storage. This helps ensure that any storage access is using the vended credentials only.

### S3 Tables catalog

<span className="feature-tag">Nightly Feature</span>

Used to access [Amazon S3 Tables](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables.html) directly through the S3 Tables Iceberg REST endpoint, without configuring AWS Glue. The endpoint speaks the standard [Iceberg REST API spec](https://github.com/apache/iceberg/blob/main/open-api/rest-catalog-open-api.yaml) but authenticates with AWS SigV4, so `CREDENTIALS` takes AWS key-based or role-based authentication. OAuth credentials and `STORAGE_CREDENTIALS` are not accepted.

`WAREHOUSE` is the table-bucket ARN. Firebolt derives the signing region and, for standard AWS Regions, the endpoint URL from it, so `URL` is optional. See the [`S3_TABLES` parameters](#s3_tables-catalog) for when `URL` is required.

**With role only (URL derived from the ARN):**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH
  SOURCE = ICEBERG
  CATALOG = S3_TABLES
  CATALOG_OPTIONS = (
    WAREHOUSE = 'arn:aws:s3tables:us-east-1:123456789012:bucket/my-bucket'
  )
  CREDENTIALS = ( AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/S3TablesAccess' AWS_ROLE_EXTERNAL_ID = 'my-external-id' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

<Note>
  For role-based AWS access you can additionally set an external ID. An external ID is a value you choose and control that AWS checks when Firebolt assumes your role, adding a second condition on top of your account's unique IAM principal. Configuring one is a recommended best practice. See [IAM roles](/security#iam-roles).
</Note>

**With access key and secret, and an explicit endpoint URL:**

```sql theme={"theme":{"light":"css-variables","dark":"css-variables"}}
CREATE LOCATION my_location
WITH
  SOURCE = ICEBERG
  CATALOG = S3_TABLES
  CATALOG_OPTIONS = (
    WAREHOUSE = 'arn:aws:s3tables:us-east-1:123456789012:bucket/my-bucket'
    URL = 'https://s3tables.us-east-1.amazonaws.com/iceberg'
  )
  CREDENTIALS = ( AWS_ACCESS_KEY_ID = '1231' AWS_SECRET_ACCESS_KEY = '567' );

SELECT * FROM READ_ICEBERG(LOCATION => 'my_location') LIMIT 5;
```

Your IAM credentials must have `s3tables` permissions to read the table bucket, list its namespaces and tables, and read table metadata and data:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowS3TablesRead",
            "Effect": "Allow",
            "Action": [
                "s3tables:GetTableBucket",
                "s3tables:ListNamespaces",
                "s3tables:ListTables",
                "s3tables:GetTableMetadataLocation",
                "s3tables:GetTableData"
            ],
            "Resource": [
                "arn:aws:s3tables:us-east-1:123456789012:bucket/my-bucket",
                "arn:aws:s3tables:us-east-1:123456789012:bucket/my-bucket/*"
            ]
        }
    ]
}
```

For the full set of actions and how the S3 Tables Iceberg REST endpoint authorizes requests, see [AWS: Accessing tables using the Amazon S3 Tables Iceberg REST endpoint](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-integrating-open-source.html).
