Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/auth/access-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Manage Access Tokens from [Settings > Access Tokens](https://portal.epilot.cloud

By default, a new Access Token inherits the roles and permissions of the creating user.

When creating a token, you can optionally set an **expiry**. A token with an expiry is automatically invalidated once it passes; a token created without one remains valid until revoked. Setting an expiry is recommended to limit the impact of a leaked token.

![Access Token create view](/img/create-access-token.png)

:::note
Expand Down Expand Up @@ -70,6 +72,28 @@ POST /v1/access-tokens
}
```

Set an optional expiry with the `expires_in` parameter — a number of seconds (e.g. `3600`) or a duration string with time units (e.g. `'10h'`, `'7d'`, `'2 days'`), bounded between 30 seconds and 365 days. Without `expires_in`, the token does not expire.

```json title="Request body with expiry"
{
"name": "Postman Access Token",
"assume_roles": ["123:owner"],
"expires_in": "30d"
}
```

Tokens created with `expires_in` are stored, listed, and revocable exactly like non-expiring tokens. The response includes an `expires_at` timestamp, and the token stops working — and drops out of the token list — once it expires:

```json title="201 response for a token with expiry"
{
"id": "api_5ZugdRXasLfWBypHi93Fk",
"created_at": "2019-08-24T14:15:22Z",
"expires_at": "2019-09-23T14:15:22.000Z",
"name": "Postman Access Token",
"assignments": ["123:owner"]
}
```

Each Access Token generated via the API receives a unique ID.

```json title="201 response"
Expand Down
8 changes: 4 additions & 4 deletions docs/auth/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Authorization: Bearer <your-token>

## Getting Started

The recommended way to authenticate with epilot APIs is using **Access Tokens** — long-lived, scoped tokens designed for integrations.
The recommended way to authenticate with epilot APIs is using **Access Tokens** — scoped tokens designed for integrations.

1. Go to [Settings > Access Tokens](https://portal.epilot.cloud/app/tokens) in the epilot portal
2. Create a new token, optionally scoping it to specific roles
2. Create a new token, optionally scoping it to specific roles and setting an expiry
3. Pass the token as a bearer token in your API requests

```typescript
Expand Down Expand Up @@ -95,7 +95,7 @@ See the [SDK documentation](/docs/sdk/overview) for the full SDK reference.

epilot authentication is built on [OAuth 2.0](https://oauth.net/2/) with [Amazon Cognito User Pools](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html) as the identity provider. Each epilot tenant has its own Cognito User Pool.

When a user logs in to the epilot portal, Cognito issues short-lived OAuth tokens (60 min). For API integrations, the [Access Token service](/api/access-token) issues long-lived JWTs with claims compatible with Cognito tokens, so all epilot APIs accept them seamlessly.
When a user logs in to the epilot portal, Cognito issues short-lived OAuth tokens (60 min). For API integrations, the [Access Token service](/api/access-token) issues JWTs with claims compatible with Cognito tokens, so all epilot APIs accept them seamlessly. These tokens support an optional expiry set at creation and stay valid until revoked if none is set.

All tokens are verified by the API Gateway authorizer using JWKS endpoints before reaching backend services.

Expand All @@ -118,7 +118,7 @@ sequenceDiagram

| Token | Lifetime | Use case |
|---|---|---|
| **Access Token** | Long-lived | Server-side API integrations, scripts, third-party apps |
| **Access Token** | Configurable expiry, up to 365 days (valid until revoked if unset) | Server-side API integrations, scripts, third-party apps |
| **OAuth 2.0 Token** | 60 minutes | Interactive user sessions in the epilot portal |
| **Publishable Token** | Long-lived | Client-side public apps (journeys, portals) |

Expand Down
8 changes: 4 additions & 4 deletions docs/auth/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ epilot supports multiple token types for different use cases:
| Token Type | Lifetime | Use Case |
|---|---|---|
| **OAuth Access Token** | 60 minutes | Interactive user sessions |
| **Access Token (Long-lived)** | No expiration | Third-party integrations, automation |
| **Access Token** | Configurable expiry, up to 365 days (set at creation) | Third-party integrations, automation |
| **Publishable Token** | No expiration | Client-side embedding (journeys, portals) |

Long-lived Access Tokens inherit the creating user's roles and permissions, and can be revoked at any time. Publishable Tokens are restricted to a narrow set of public-facing operations. See [Access Tokens](/docs/auth/access-tokens) and [Token Types](/docs/auth/token-types) for details.
Access Tokens support an optional expiry, set when the token is created — either in the management UI or via the `expires_in` parameter of the [Access Token API](/api/access-token). Tokens created without an expiry remain valid until revoked; tokens created with one can live up to 365 days and stay listed and revocable until they expire. Access Tokens inherit the creating user's roles and permissions, and can be revoked at any time. Publishable Tokens are restricted to a narrow set of public-facing operations. See [Access Tokens](/docs/auth/access-tokens) and [Token Types](/docs/auth/token-types) for details.

### Authentication Methods

Expand Down Expand Up @@ -197,7 +197,7 @@ WAF rules are continuously tuned based on traffic patterns and threat intelligen

epilot distinguishes between two categories of API credentials:

- **Access Tokens** — Secret, long-lived tokens that carry the creating user's full permissions. Keep confidential; use for server-to-server integrations. See [Access Tokens](/docs/auth/access-tokens).
- **Access Tokens** — Secret tokens that carry the creating user's permissions. Keep confidential; use for server-to-server integrations, and set an expiry at creation to limit exposure. See [Access Tokens](/docs/auth/access-tokens).
- **Publishable Tokens** — Safe to embed in client-side code (journey embed scripts, portal widgets). Restricted to public operations and cannot access sensitive data. See [Token Types](/docs/auth/token-types).

:::warning
Expand Down Expand Up @@ -282,6 +282,6 @@ epilot maintains the following certifications and compliance measures:
- [Passkeys](/docs/auth/passkeys) -- Phishing-resistant biometric and hardware key authentication
- [SSO](/docs/sso/single-sign-on) — Single sign-on with OIDC and SAML identity providers
- [Authorization](/docs/auth/authorization) — JWT validation, API Gateway authorizer, Permissions API
- [Access Tokens](/docs/auth/access-tokens) — Creating and managing long-lived API tokens
- [Access Tokens](/docs/auth/access-tokens) — Creating and managing API tokens
- [Token Types](/docs/auth/token-types) — Comparison of access tokens vs. publishable tokens
- [Permissions](/docs/auth/permissions) — RBAC model, grant evaluation, role management
19 changes: 16 additions & 3 deletions docs/auth/token-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ epilot uses three token types for authentication. Choose the right one for your

| | OAuth 2.0 Token | Access Token | Publishable Token |
|---|---|---|---|
| **Lifetime** | 60 minutes | Long-lived (no expiry) | Long-lived (no expiry) |
| **Lifetime** | 60 minutes | Configurable expiry, up to 365 days (valid until revoked if unset) | Long-lived (no expiry) |
| **Use case** | Interactive user sessions | Server-side API integrations | Client-side public apps (journeys, portals) |
| **Format** | JWT (Cognito-issued) | JWT (epilot-issued) | JWT (epilot-issued, public key) |
| **Refresh** | Via refresh token | Not needed | Not needed |
Expand All @@ -35,12 +35,12 @@ On successful authentication, Cognito issues three tokens:
OAuth tokens expire after **60 minutes**. Use the refresh token to obtain new tokens transparently.

:::tip
OAuth tokens suit interactive user sessions. For API integrations, use long-lived [Access Tokens](/docs/auth/access-tokens) instead.
OAuth tokens suit interactive user sessions. For API integrations, use [Access Tokens](/docs/auth/access-tokens) instead.
:::

## Access Tokens

Access Tokens are long-lived JWTs for server-side integrations — the recommended authentication method for backend systems, scripts, and third-party applications. See [Access Tokens](/docs/auth/access-tokens) for full management details.
Access Tokens are JWTs for server-side integrations — the recommended authentication method for backend systems, scripts, and third-party applications. You can set an expiry when creating a token; tokens created without one stay valid until revoked. See [Access Tokens](/docs/auth/access-tokens) for full management details.

### How They Work

Expand All @@ -63,6 +63,7 @@ authorize(accessTokenClient, cognitoIdToken);
const { data } = await accessTokenClient.createAccessToken(null, {
name: 'SAP Integration',
assume_roles: ['123:sap_integration_role'],
expires_in: '30d', // optional expiry — seconds or a duration string
});

// data.access_token contains the token — save it securely
Expand All @@ -78,6 +79,17 @@ Scope each Access Token to specific roles via `assume_roles`. If omitted, the to
}
```

### Token Expiry

Set an optional expiry when creating a token via the `expires_in` parameter — either a number of seconds (e.g. `3600`) or a duration string with time units (e.g. `'10h'`, `'7d'`, `'2 days'`). Expired tokens are rejected by the API Gateway authorizer like any other expired JWT.

- **Standard Access Tokens** (`token_type: api`, the default) accept an expiry between 30 seconds and **365 days**.
- Other token types created with an explicit `expires_in` (e.g. `app` tokens) are capped at **7 days**, since they're ephemeral and not manageable from the token list.

If `expires_in` is omitted, the token does not expire and remains valid until revoked.

Access Tokens created with an expiry are still persisted, listed, and revocable like any other token — the create response includes an `expires_at` timestamp, and the token disappears from the list once it expires.

:::warning
Creating access tokens requires the `token:create` permission. The generated token is shown **only once** and cannot be recovered.
:::
Expand Down Expand Up @@ -139,6 +151,7 @@ All token types use JWT (JSON Web Token) format, signed with RS256.
| `assume_roles` | List of role IDs (e.g., `["123:owner"]`) |
| `iss` | Access Token service issuer URL |
| `iat` | Issued-at timestamp |
| `exp` | Expiration timestamp (present when the token was created with an expiry) |

### Token Verification

Expand Down
Loading