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

# Authentication

> Learn how to authenticate with the Issuing API

# Authentication

The Issuing API uses **RSA-signed JWT tokens** for authentication. To authenticate requests, you need:

1. An **Access Key** (UUID) - obtained from your implementation manager
2. An **RSA key pair** - you generate this yourself
3. **JWT signing** - sign each request with your private key

<Note>
  **For detailed implementation instructions**, see the [Request Signing guide](/issuing/getting-started/request-signing) which covers the complete authentication flow including JWT token generation and signing.
</Note>

## Overview

Authentication works by:

1. **Registering your public key** - Email your RSA public key to your implementation manager to receive an Access Key
2. **Signing requests** - For each API request, create a JWT token signed with your RSA private key
3. **Including the token** - Add the signed JWT to the `Authorization` header as a Bearer token

## Quick Example

```bash theme={null}
curl https://access.utgl.io/v1/ping \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
```

The Bearer token is a JWT that includes:

* Your Access Key (`sub` claim)
* Request URI (`uri` claim)
* HTTP method (`method` claim)
* Request body hash (`body` claim, if applicable)
* Timestamps (`iat`, `exp` claims)

<Warning>
  **Security Best Practices**:

  * Never share your private key or commit it to version control
  * Store keys securely in encrypted storage
  * Use environment variables for sensitive credentials
  * Rotate keys periodically
  * Keep JWT tokens short-lived (expire within 30 seconds)
</Warning>

## Authentication Errors

If authentication fails, you'll receive a `401 Unauthorized` response:

```json theme={null}
{
  "code": "INVALID_SIGNATURE",
  "message": "JWT signature verification failed"
}
```

Common authentication errors:

| Error Code            | Description                       | Solution                                        |
| --------------------- | --------------------------------- | ----------------------------------------------- |
| `INVALID_SIGNATURE`   | JWT signature verification failed | Verify your private key and signature algorithm |
| Authentication failed | Invalid or missing access key     | Check your access key is correct                |
| Authentication failed | JWT token expired                 | Ensure token is less than 30 seconds old        |

## Sandbox Convenience

In the sandbox environment, you can use HTTP Basic Authentication as a convenience (no signature required):

```bash theme={null}
curl -u YOUR_ACCESS_KEY: https://sandbox.access.utgl.io/v1/ping
```

In production, RSA-signed JWT tokens are required. See [Sandbox Environment](/issuing/getting-started/sandbox-environment) for details.

## Rate Limiting

Authenticated requests are subject to rate limiting. See our [Rate Limits documentation](/issuing/getting-started/rate-limits) for details.

## Next Steps

* [Request Signing Guide](/issuing/getting-started/request-signing) - Complete JWT signing implementation
* [Authentication Recipes](/issuing/recipes/authentication-java) - Language-specific examples
* [Sandbox Environment](/issuing/getting-started/sandbox-environment) - Testing without signatures
