---
title: "Connect Amazon Athena"
description: "Connect Datarelix to Amazon Athena: IAM auth modes, Glue Data Catalog scope, a read-only policy, query-cost controls, and Lake Formation grants."
canonical: https://docs.datarelix.ai/guides/connections/athena/
---

# Connect Amazon Athena

Datarelix connects to AWS Athena through a read-only query service. Athena speaks Trino/Presto SQL and reads table metadata from the AWS Glue Data Catalog — see [Getting started with Athena](https://docs.aws.amazon.com/athena/latest/ug/getting-started.html).

## Prerequisites

- An AWS account with Athena enabled in your target region.
- An **S3 bucket** for query result staging in the **same region as Athena** (Athena writes intermediate results there before Datarelix downloads them).
- A **Glue Data Catalog** with the databases/tables you want to analyze. Tables must be cataloged — Athena does not auto-discover schema from raw S3 objects.
- IAM permissions on the principal used for auth. At minimum: `athena:StartQueryExecution`, `athena:GetQueryExecution`, `athena:GetQueryResults`, `glue:GetDatabase(s)`, `glue:GetTable(s)`, `s3:GetObject` on the data S3 paths, and `s3:GetObject`/`s3:PutObject` on the staging S3 prefix.

## Connection form

```ini
AWS region:           us-east-1
S3 output location:   s3://your-bucket/athena-staging/
Workgroup:            primary             (default)
Catalog:              AwsDataCatalog      (default)
Auth mode:            one of the two below
```

The **Allowed schema** field (set per-connection) scopes introspection and queries to one Glue database.

## Auth modes

### IAM access keys

Long-lived AWS access key + secret. The credentials are stored encrypted. Simplest path for connecting from outside AWS where no ambient IAM role is available.

**Setup — create a dedicated IAM user**

1. In the AWS Console, [create an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) (**IAM → Users → Create user**). Give it a descriptive name (e.g. `datarelix-athena-reader`).
2. Choose **Attach policies directly** and attach a policy with the following minimum permissions (or create a custom policy — see [Athena IAM policies](https://docs.aws.amazon.com/athena/latest/ug/managed-policies.html)):

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "athena:StartQueryExecution",
           "athena:GetQueryExecution",
           "athena:GetQueryResults",
           "athena:StopQueryExecution",
           "athena:GetWorkGroup"
         ],
         "Resource": "arn:aws:athena:<region>:<account-id>:workgroup/primary"
       },
       {
         "Effect": "Allow",
         "Action": ["glue:GetDatabase", "glue:GetDatabases", "glue:GetTable", "glue:GetTables", "glue:GetPartitions"],
         "Resource": "*"
       },
       {
         "Effect": "Allow",
         "Action": ["s3:GetBucketLocation"],
         "Resource": "arn:aws:s3:::your-data-bucket"
       },
       {
         "Effect": "Allow",
         "Action": ["s3:GetObject"],
         "Resource": "arn:aws:s3:::your-data-bucket/*"
       },
       {
         "Effect": "Allow",
         "Action": ["s3:GetObject", "s3:PutObject"],
         "Resource": "arn:aws:s3:::your-bucket/athena-staging/*"
       },
       {
         "Effect": "Allow",
         "Action": ["s3:ListBucket"],
         "Resource": "arn:aws:s3:::your-bucket"
       }
     ]
   }
   ```

3. After the user is created, [create an access key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) (user → **Security credentials → Access keys → Create access key**). Choose **Application running outside AWS**. Copy the **Access key ID** and **Secret access key** — the secret is only shown once.

**Where to find your credentials**

- **Access key ID** and **Secret access key**: IAM → Users → [your user] → **Security credentials → Access keys** (you must create a new key if you didn't copy the secret at creation time).

**What to enter**

```ini
AWS region:           us-east-1
S3 output location:   s3://your-bucket/athena-staging/
Auth mode:            IAM access keys
Access Key ID:        AKIAIOSFODNN7EXAMPLE
Secret Access Key:    ••••••••
```

---

### Assume Role

The calling identity assumes a target IAM role via AWS STS before querying Athena. Best for **cross-account** access: your credentials live in one account; the Athena data and permissions live in another account's IAM role.

**Setup — create the assumable role in the data account**

1. In the **data-owner AWS account**, go to **IAM → Roles → Create role**.
2. Choose **Another AWS account** as the trusted entity and enter your calling account ID.
3. Attach the same Athena + Glue + S3 policy as in the IAM access keys mode above.
4. If you want to use an [**External ID**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) (recommended to prevent confused-deputy attacks), add a condition to the trust policy:
   ```json
   {
     "Version": "2012-10-17",
     "Statement": [{
       "Effect": "Allow",
       "Principal": { "AWS": "arn:aws:iam::<your-calling-account>:root" },
       "Action": "sts:AssumeRole",
       "Condition": {
         "StringEquals": { "sts:ExternalId": "your-external-id" }
       }
     }]
   }
   ```
5. Copy the **Role ARN** from the role's summary page.

The calling identity (resolved from your **IAM access keys** connection or ambient credentials) must have `sts:AssumeRole` permission on the target role ARN.

**Where to find your credentials**

| Field | Where to get it |
|-------|----------------|
| Role ARN | IAM (data account) → Roles → [your role] → **ARN** in the summary (e.g. `arn:aws:iam::123456789012:role/AthenaReaderRole`) |
| External ID | The value you set in the trust policy condition (if any) |

**What to enter**

```ini
AWS region:           us-east-1
S3 output location:   s3://your-bucket/athena-staging/
Auth mode:            Assume Role
Role ARN:             arn:aws:iam::123456789012:role/AthenaReaderRole
External ID:          your-external-id    (leave blank if not required by the trust policy)
```

---

## Glue Data Catalog

Athena reads schema and table metadata from the Glue Data Catalog. **Tables don't exist in Athena until they're cataloged in Glue.**

- Verify your tables are visible: AWS Console → **Glue → Data Catalog → Databases** → click your database → see **Tables**.
- If your data is in S3 but no Glue tables exist, run an [AWS Glue crawler](https://docs.aws.amazon.com/glue/latest/dg/add-crawler.html) once to populate the catalog.
- The connection's **Allowed schema** field corresponds to a Glue database.
- Custom catalogs (federated Glue catalogs, Hive Metastore via Lake Formation) work via the `Catalog` field — default is `AwsDataCatalog`.

### IAM-only vs Lake Formation

How you grant read access depends on whether the database is governed by AWS Lake Formation:

- **IAM-managed catalog** — the `glue:Get*` + `s3:GetObject` permissions in the IAM policy above are sufficient.
- **Lake Formation-governed catalog** — IAM permissions are **not** enough. You must *also* grant the principal `SELECT` (and `DESCRIBE`) on the database/tables in [Lake Formation](https://docs.aws.amazon.com/athena/latest/ug/lf-athena-limitations.html), and grant `DESCRIBE` on the `default` database. Without these, queries fail with `Insufficient Lake Formation permissions` even when IAM is correct.

If you're unsure, AWS Console → **Lake Formation → Data lake locations**: if your S3 paths are registered there, the catalog is Lake Formation-governed.

## S3 staging directory

Athena writes [query results to S3](https://docs.aws.amazon.com/athena/latest/ug/querying.html) before they can be downloaded. The location can also be set on the [workgroup](https://docs.aws.amazon.com/athena/latest/ug/workgroups.html).

- **Region must match Athena's region.** A `us-west-2` bucket with a `us-east-1` Athena query fails with `Query result location is invalid`.
- Athena does **not** auto-delete result files. Add an S3 lifecycle policy on the staging prefix (e.g. expire after 7 days) to keep costs bounded.

## Scope semantics

The **Allowed schema** field limits introspection and queries to one Glue database. Blank scope is not supported — you must explicitly set a database. To analyze multiple databases, create multiple connections.

## Discovery

The introspector queries `INFORMATION_SCHEMA` via Athena (these are small Athena queries that count toward your workgroup). Glue doesn't track foreign keys — the LLM enrichment pass infers relationships from column-name conventions if you opt in.

## Limitations

- **Read-only** — the validator rejects write and DDL statements.
- **One Glue database per connection.**
- **Query result download latency** — Athena always stages to S3, then Datarelix fetches. Adds ~100–500 ms per query on top of compute time.

## Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| `AccessDenied` on `glue:GetDatabase`/`GetTables` | Missing Glue permissions | Add the IAM actions from the policy snippet above. |
| `Insufficient permissions to execute the query` | Missing `s3:GetObject` on source data | Ensure the IAM principal can read the S3 paths registered in Glue. |
| `Query result location not set` / `is invalid` | Empty staging dir or region mismatch | Set **S3 output location** to an `s3://bucket/prefix/` in the **same region as Athena**. |
| `AccessDenied: ... is not authorized to perform sts:AssumeRole` | Calling identity not allowed by target role trust policy | Update the role's trust policy to allow the calling principal. |
| `AccessDenied` with ExternalId | External ID missing or mismatched | Set the **External ID** field to the value the trust policy expects (case-sensitive). |
| `Insufficient Lake Formation permissions` | Lake Formation enabled on the catalog | Grant the principal `SELECT` via the Lake Formation console in addition to IAM. |
| `Table not found` despite Glue listing it | Wrong catalog | Confirm the **Catalog** field matches the catalog name in Glue (usually `AwsDataCatalog`). |
