> For the complete documentation index, see [llms.txt](https://docs.e6data.com/query-engine/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.e6data.com/query-engine/guides/security/access-tokens/create-use-rotate-revoke.md).

# Create, use, rotate, and revoke tokens

Create personal access tokens and service account API keys, use them over REST and JDBC/ODBC, set an expiry, rotate, and revoke them.

This page is for everyone who connects to an e6data workspace over the API - through a BI tool, a notebook, a script, or an automated pipeline. It covers creating a token, using it, setting an expiry, rotating it, and revoking it.

## Choosing a token type

Pick the credential that matches the actor:

* A **person** acting under their own identity (Tableau, a notebook, a local script) → use a **Personal Access Token (PAT)**.
* A **machine or automated process** (CI/CD, Airflow, a service) → use a **Service Account API key**.

A PAT inherits your personal roles and is revoked when your account is deprovisioned, so it is **not** suitable for CI/CD. A service account is an independent identity that keeps working when team members change. For the full credential comparison and prefixes, see the canonical table in [Access tokens](/query-engine/guides/security/access-tokens.md#token-types).

## Personal access tokens

A PAT authenticates the API **as you**. It inherits exactly the roles your user account has in the workspace.

### Create a personal access token

1. Open the **avatar menu** (top-right) and select **User settings**.
2. Go to the **Access tokens** tab.
3. Select **Create**.
4. Enter a **Comment** describing what the token is for (for example, `Tableau Desktop - Marketing`). This is required - 3 to 200 characters.
5. Set **Token Expiry**: enter a number of days (default 90, maximum 3650), or tick **Never expires**.
6. Select **Create**, then copy the token immediately.

{% hint style="warning" %}
The token is shown only once. After you close the dialog, the full value cannot be retrieved again. If you lose it, create a new one and revoke the old one - there is no way to recover a lost token value.
{% endhint %}

### Use a personal access token

e6data's API accepts a token in either of two request headers. For a PAT the common convention is `Authorization: Bearer`, but both headers work:

| Header                          | Example                                                |
| ------------------------------- | ------------------------------------------------------ |
| `Authorization: Bearer <token>` | `Authorization: Bearer e6pat_analytics_a1b2c3d4_xYz9…` |
| `X-API-Key: <token>`            | `X-API-Key: e6pat_analytics_a1b2c3d4_xYz9…`            |

REST (curl):

```bash
curl -H "Authorization: Bearer e6pat_analytics_a1b2c3d4_xYz9…" \
  https://<workspace>.e6.run/api/v1/catalogs
```

For scripts, keep the token out of your shell history and source by reading it from an environment variable:

```bash
export E6DATA_TOKEN="e6pat_analytics_a1b2c3d4_xYz9…"

curl -H "Authorization: Bearer $E6DATA_TOKEN" \
  https://<workspace>.e6.run/api/v1/catalogs
```

For JDBC/ODBC and BI tools (Tableau, Power BI, Looker, Metabase), use the e6data driver and supply your credentials as:

| Field              | Value                |
| ------------------ | -------------------- |
| Host               | `<workspace>.e6.run` |
| Port               | `443`                |
| Username           | your email address   |
| Password           | your PAT             |
| Database / Catalog | your catalog name    |

A typical JDBC connection string looks like:

```
jdbc:e6data://<workspace>.e6.run:443/<catalog>;schema=<schema>
```

The driver formats the auth header for you. If a generic BI tool sends your token as HTTP **Basic** auth instead, it won't be accepted - see [Troubleshooting](#troubleshooting).

### List and revoke your tokens

On **User settings → Access tokens** you can see all your tokens - comment, created date, and expiry (expired ones are flagged). Only metadata is shown; the token value is never displayed again. Select the trash icon next to a token and confirm to revoke it. Revocation takes effect immediately.

## Service accounts

A service account is a **machine identity** for automated and programmatic access. It cannot log into the Console - it authenticates only through its API keys, and it has its own role bindings. Because it isn't tied to a person, it keeps working when team members change.

### Create a service account

1. In the left sidebar, go to **Administration → Service Accounts**.
2. Select **Create**.
3. Enter a **Name** - lowercase letters, numbers, and hyphens, 1–63 characters, not starting or ending with a hyphen (for example, `github-actions`). The name cannot be changed later.
4. Optionally add a **Display Name** and **Description**.
5. Select **Create**.

The new account gets an email-style identity such as `github-actions@serviceaccount.local`, shown on its **Details** tab. Assign it a role binding so its keys can do something - see [Token security best practices](/query-engine/guides/security/access-tokens/token-security-best-practices.md#least-privilege).

{% hint style="info" %}
Create one service account per use case - one for CI, one for Airflow, one for monitoring - so you can revoke or rotate one without disturbing the others.
{% endhint %}

### Add an API key

1. Open the service account and go to the **API Keys** tab.
2. Select **New Key**.
3. Enter a **Key Name** (for example, `prod-deploy-2026`), 1–128 characters.
4. Set **Key Expiry** in days (default 90, maximum 3650), or tick **Never expires**.
5. Select **Create Key**, then copy the key immediately.

Like PATs, an API key is shown only once. Store it in a secrets manager before closing the dialog. If you lose it, create a new key and revoke the old one.

### Use a service account API key

For service accounts the common convention is the `X-API-Key` header (both headers work, just as with PATs).

GitHub Actions - store the key as an Actions secret, never in the workflow file:

```yaml
- name: Run e6data query
  env:
    E6DATA_API_KEY: ${{ secrets.E6DATA_SERVICE_ACCOUNT_KEY }}
  run: |
    curl -s -H "X-API-Key: $E6DATA_API_KEY" \
      https://<workspace>.e6.run/api/v1/catalogs
```

Python (Airflow tasks, services, scripts):

```python
import os
import requests

api_key = os.environ["E6DATA_SERVICE_ACCOUNT_KEY"]
resp = requests.get(
    "https://<workspace>.e6.run/api/v1/catalogs",
    headers={"X-API-Key": api_key},
)
resp.raise_for_status()
print(resp.json())
```

### List and revoke API keys

The **API Keys** tab lists every key on the account (name, prefix, created, expiry). Select **Revoke** next to a key and confirm - it stops working immediately. Deleting the service account revokes all of its keys at once.

## Token expiry

Expiry is optional for both PATs and API keys. In the Console you enter it as a number of days; it is stored as an RFC 3339 timestamp (for example, `2026-12-31T23:59:59Z`) and checked on every request.

An expired token returns `401 Unauthorized` (`invalid or expired API token`). Expired tokens cannot be extended - create a replacement and revoke the old one.

| Use case                               | Suggested expiry                              |
| -------------------------------------- | --------------------------------------------- |
| BI tool connection (Tableau, Power BI) | 90 days - rotate quarterly                    |
| CI/CD pipeline key                     | 365 days - rotate annually or on team changes |
| Short-lived script or investigation    | Hours to days - match the task                |
| No expiry                              | Only with a rotation process already in place |

## Rotating a token

Rotate before expiry, and immediately if a token might have been exposed. Use **create-before-delete** so there is no gap where nothing works:

1. **Create** a new token (or API key).
2. **Update** your application or secrets manager with the new value.
3. **Verify** the new token authenticates correctly.
4. **Revoke** the old token.

## Troubleshooting

| Symptom                                                 | Cause                                                                                     | Fix                                                                                                                       |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `401` - `invalid or expired API token`                  | The token expired, was revoked, or was copied incorrectly                                 | Check the expiry; re-copy the full value; if needed create a new token and revoke the old one                             |
| `401` - `invalid API token format`                      | The value isn't a well-formed e6data token                                                | Re-copy the whole token, including the `e6pat_` / `e6sa_` prefix                                                          |
| `412` - `AccessToken not configured for this workspace` | The token system hasn't been initialized for this workspace yet                           | A workspace Admin needs to configure it once (`POST /api/v1/accesstokens/configure`) before tokens can be created         |
| `403 Forbidden`                                         | The token is valid, but its identity lacks the required permission                        | Ask an Admin to add or adjust the role binding for your user or service account                                           |
| Works in `curl` but not in my BI tool                   | The tool sends credentials as HTTP Basic auth, which the token middleware does not accept | Use the e6data JDBC/ODBC driver (email = username, token = password), or configure the tool to send an `X-API-Key` header |

## Frequently asked questions

**I lost a token before saving it - can I get it back?** No. The full value is shown only once. Create a new token, update your app with it, then revoke the old one by UUID if you still have it.

**Can I use my PAT for a CI/CD pipeline?** You can, but don't. A PAT is tied to your personal identity and will stop working if you change roles or leave - breaking the pipeline. Use a service account instead.

**What happens to my tokens if my workspace access is removed?** They still authenticate (the token is valid), but every call returns `403 Forbidden` because you no longer have a role binding. An Admin re-granting you a role restores access - you don't need new tokens.

**Why does e6data accept two different auth headers?** The middleware checks `X-API-Key` first, then `Authorization: Bearer`. Both work for both token types; the per-type conventions above are just the common choice.

## See also

* [Access tokens](/query-engine/guides/security/access-tokens.md) - the canonical token-types table.
* [Token security best practices](/query-engine/guides/security/access-tokens/token-security-best-practices.md) - storage, least privilege, revocation, and audit.
* [Roles and permissions](/query-engine/guides/security/identity-and-rbac/roles-and-permissions.md) - the role bindings a token inherits.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.e6data.com/query-engine/guides/security/access-tokens/create-use-rotate-revoke.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
