> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turrisfi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate with the Turris Public API

# Authentication

The Turris Public API supports two authentication methods. Choose the one that best fits your use case.

## Authentication Methods

| Method                      | Best For                                 | Security Level              |
| --------------------------- | ---------------------------------------- | --------------------------- |
| **OAuth (M2M)**             | Server-to-server integrations            | High - JWT with expiration  |
| **Restricted Access Token** | Simple integrations with IP restrictions | High - Token + IP allowlist |

<Note>
  Both methods provide the same level of access. OAuth is recommended for production integrations due to its token rotation capability.
</Note>

## OAuth Authentication (Recommended)

OAuth uses Machine-to-Machine (M2M) JWT tokens for authentication. This is the preferred method for production integrations.

### Step 1: Create API Client

1. Navigate to [API Settings](https://www.app.live.turrisfi.com/upstream-entity/associated-downstream-entities?settings-modal=open\&path=api) in your Turris dashboard
2. Click **Create API Client**
3. Store your `client_id` and `client_secret` securely

<Warning>
  **Never expose your client secret in frontend code.** Store credentials securely in environment variables or a secrets manager.
</Warning>

### Step 2: Get Access Token

Exchange your credentials for a JWT:

```bash theme={null}
curl -X POST "https://public.api.live.turrisfi.com/v1/auth/jwt" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "your-client-id",
    "clientSecret": "your-client-secret"
  }'
```

**Response:**

```json theme={null}
{
  "statusCode": 201,
  "data": {
    "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
  },
  "timestamp": "2025-01-30T12:34:56.789Z"
}
```

### Step 3: Use the Token

Include the token in the `Authorization` header:

```bash theme={null}
curl -X GET "https://public.api.live.turrisfi.com/v1/downstream-entity-associations" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
```

### Token Lifecycle

| Property               | Value                           |
| ---------------------- | ------------------------------- |
| **Time-to-Live (TTL)** | 60 minutes                      |
| **Refresh**            | Request new token before expiry |

<Tip>
  Implement token caching in your application. Request a new token only when the current one is about to expire (e.g., 5 minutes before expiry).
</Tip>

### Test Your Token

Verify your token is valid:

```bash theme={null}
curl -X GET "https://public.api.live.turrisfi.com/v1/auth/test-oauth" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Success Response:**

```json theme={null}
{
  "message": "If you see this message, your jwt is valid!"
}
```

***

## Restricted Access Token

Restricted Access Tokens provide a simpler authentication method with IP-based security.

### Step 1: Create Token

1. Navigate to [API Settings](https://www.app.live.turrisfi.com/upstream-entity/associated-downstream-entities?settings-modal=open\&path=api) in your Turris dashboard
2. Click **Create Restricted Access Token**
3. Add your server's IP addresses to the allowlist
4. Store your token securely

### Step 2: Use the Token

Include the token in the `x-restricted-access-token` header:

```bash theme={null}
curl -X GET "https://public.api.live.turrisfi.com/v1/downstream-entity-associations" \
  -H "x-restricted-access-token: your-restricted-access-token"
```

### Security Model

The Restricted Access Token guard performs three validations:

1. **Token Presence** - Checks for the `x-restricted-access-token` header
2. **Token Validity** - Validates the token against stored hashes
3. **IP Allowlist** - Verifies the request originates from an allowed IP address

<Warning>
  Requests from IP addresses not in your allowlist will be rejected with a `403 Forbidden` error.
</Warning>

### Test Your Token

Verify your token and IP are configured correctly:

```bash theme={null}
curl -X GET "https://public.api.live.turrisfi.com/v1/auth/test-restricted-access-token" \
  -H "x-restricted-access-token: your-restricted-access-token"
```

**Success Response:**

```json theme={null}
{
  "message": "If you see this message, your accessToken is valid!"
}
```

***

## Fallback Behavior

When both authentication headers are provided, the API uses this priority:

1. **OAuth** is attempted first
2. If OAuth fails and a Restricted Access Token is present, **token authentication** is attempted

This allows for graceful migration between authentication methods.

***

## Error Responses

### 401 Unauthorized

**Missing or invalid credentials:**

```json theme={null}
{
  "statusCode": 401,
  "requestId": "dev-63c50377-1cfa-4d51-bce7-d187507853db",
  "errorType": "unauthorized",
  "errorMessage": ["Authentication token not provided"],
  "timestamp": "2025-01-30T09:58:12.488Z"
}
```

**Expired JWT:**

```json theme={null}
{
  "statusCode": 401,
  "requestId": "dev-1fb0b225-f24e-43ed-b602-8ec6d7d84758",
  "errorType": "unauthorized",
  "errorMessage": ["JWT token has expired"],
  "timestamp": "2025-01-30T19:36:41.467Z"
}
```

### 403 Forbidden

**IP not in allowlist (Restricted Access Token only):**

```json theme={null}
{
  "statusCode": 403,
  "requestId": "dev-e08550ef-5cfb-4a06-8686-5b8399ac5fc9",
  "errorType": "forbidden",
  "errorMessage": ["IP address \"192.168.1.1\" not in allowed list for token \"***-a5ed\""],
  "timestamp": "2025-01-30T03:25:32.327Z"
}
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Store credentials securely">
    * Use environment variables or a secrets manager
    * Never commit credentials to version control
    * Rotate credentials periodically
  </Accordion>

  <Accordion title="Implement token caching">
    * Cache OAuth tokens for their full TTL (60 minutes)
    * Refresh tokens proactively before expiry
    * Handle token refresh failures gracefully
  </Accordion>

  <Accordion title="Handle errors gracefully">
    * Implement retry logic for transient failures
    * Log authentication errors for debugging
    * Alert on repeated authentication failures
  </Accordion>
</AccordionGroup>
