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

# Client Authentication

> Secure your Edge Server HTTP APIs with API key authentication

Authentication protects your Edge Server HTTP APIs by requiring clients to provide valid credentials. Edge Server uses API keys for authentication, combined with permission sets for authorization.

## Overview

Edge Server authentication involves three components:

1. **Identity**: Defines who can access the API (with a credential like an API key)
2. **PermissionSet**: Defines what actions are allowed
3. **HttpServer**: Specifies which identities can authenticate

## Generating API Keys

Use the Edge Server CLI to generate secure API keys:

```bash theme={null}
ditto-edge-server api-key generate
```

This command outputs two values:

* **Generated Private Key**: The secret key that clients use to authenticate (keep this secure)
* **Secure Public Hash**: The base64-encoded hash to store in your configuration

Example output:

```
Generated Private Key: dGVzdC1hcGkta2V5LTEyMzQ1Njc4OTA=
Secure Public Hash: c2NyeXB0JGxuPTE2LHI9OCxwPTEkYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=$
```

<Warning>
  The API key is only shown once during generation. Store it securely (e.g., in a secrets manager or environment variable). The hash can be safely stored in your configuration file.
</Warning>

## Validating API Keys

To verify that an API key matches its hash:

```bash theme={null}
ditto-edge-server api-key validate \
  --key "dGVzdC1hcGkta2V5LTEyMzQ1Njc4OTA=" \
  --hash "c2NyeXB0JGxuPTE2LHI9OCxwPTEkYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=$"
```

If valid, you'll see:

```
Key is valid
```

This is useful for:

* Verifying credentials before deployment
* Troubleshooting authentication issues

## Configuring Authentication

### Step 1: Create a Permission Set

Define what actions authenticated clients can perform:

```yaml theme={null}
auth:
  permission_sets:
    full_permissions:
      permissions: full  # Currently the only option
```

See the [PermissionSet reference](/edge-server/configuration/reference/permission-set-resource) for details.

### Step 2: Create an Identity

Add the API key hash and reference the permission set:

```yaml theme={null}
auth:
  identities:
    api_client:
      credential:
        api_key: "BASE64_ENCODED_STRING_GENERATED_BY_CLI"
      permissions: [full_permissions]
      id: "my-api-client"
  permission_sets:
    full_permissions:
      permissions: full
```

<Info>
  The `credential.api_key` field contains the **hash** (not the original key). The original key is what clients send in HTTP requests.
</Info>

See the [Identity reference](/edge-server/configuration/reference/identity-resource) for details.

### Step 3: Protect Your HTTP Server

Complete configuration with authentication:

```yaml theme={null}
database:
  db_id: "12345678-1234-4123-1234-123456789012"
  device_name: "edge-server-1"
  auth:
    server:
      access_token: "YOUR_TOKEN"
      auth_url: "REPLACE_ME_WITH_YOUR_URL"
      provider: "__playgroundProvider"

http_server:
  listen_addr: "127.0.0.1:8080"
  tls_config: dev_mode
  http_api: true

auth:
  identities:
    api_client:
      credential:
        api_key: "BASE64_ENCODED_STRING_GENERATED_BY_CLI"
      permissions: [full_permissions]
      id: "my-api-client"
  permission_sets:
    full_permissions:
      permissions: full
```

See the [HTTP Server reference](/edge-server/configuration/reference/http-server-resource) for details.

## Using API Keys in HTTP Requests

Clients authenticate by including the API key in the `Authorization` header:

```bash theme={null}
curl -X POST http://127.0.0.1:8080/execute \
  -H "Authorization: Bearer dGVzdC1hcGkta2V5LTEyMzQ1Njc4OTA=" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT * FROM users"
  }'
```

The format is: `Authorization: Bearer <your-api-key>`

## Multiple Identities

You can configure multiple identities with different API keys:

```yaml theme={null}
database:
  db_id: "12345678-1234-4123-1234-123456789012"
  device_name: "edge-server-1"
  auth:
    server:
      access_token: "YOUR_TOKEN"
      auth_url: "REPLACE_ME_WITH_YOUR_URL"
      provider: "__playgroundProvider"

http_server:
  listen_addr: "127.0.0.1:8080"
  tls_config: dev_mode
  http_api: true

auth:
  identities:
    admin_client:
      credential:
        api_key: "BASE64_ENCODED_STRING_GENERATED_BY_CLI"
      permissions: [admin_permissions]
      id: "admin"
    readonly_client:
      credential:
        api_key: "BASE64_ENCODED_STRING_GENERATED_BY_CLI"
      permissions: [read_only_permissions]
      id: "readonly"
  permission_sets:
    admin_permissions:
      permissions: full
    read_only_permissions:
      permissions: full  # Currently all permissions are "full"
```

Both API keys can authenticate, allowing different clients to use different credentials.

## Disabling Authentication (Not Recommended)

To disable authentication entirely:

```yaml theme={null}
database:
  db_id: "12345678-1234-4123-1234-123456789012"
  device_name: "edge-server-1"
  auth:
    server:
      access_token: "YOUR_TOKEN"
      auth_url: "REPLACE_ME_WITH_YOUR_URL"
      provider: "__playgroundProvider"

http_server:
  listen_addr: "127.0.0.1:8080"
  tls_config: dev_mode
  http_api: true

# No authentication required (dev mode only)
auth: dev_mode
```

<Warning>
  Disabling authentication exposes your API to unauthorized access. Only do this in trusted development environments, never in production.
</Warning>

## Best Practices

### Key Generation

1. **Use the CLI**: Always generate keys using `ditto-edge-server api-key generate` rather than creating them manually
2. **One key per client**: Generate unique API keys for each client or service
3. **Validate before deploying**: Use `ditto-edge-server api-key validate` to verify keys work before updating production configs

### Key Storage

1. **Store keys securely**: Use environment variables, secrets managers, or secure vaults for API keys
2. **Never commit keys**: Don't commit API keys to version control (add them to `.gitignore`)

### Key Rotation

To rotate an API key:

1. Generate a new key: `ditto-edge-server api-key generate`
2. Create a new Identity with the new hash
3. Add the new Identity to the HTTP server's `auth` list (keeping the old one temporarily)
4. Update clients to use the new key
5. Verify clients are using the new key
6. Remove the old Identity from the `auth` list
7. Restart Edge Server to apply changes

### Access Control

1. **Use descriptive IDs**: Give identities meaningful `id` values for audit logs (e.g., `"production-api"`, `"monitoring-service"`)
2. **Separate permission sets**: Create distinct permission sets for different roles (even if they currently have the same permissions)
3. **Principle of least privilege**: Plan to grant minimum necessary permissions when granular controls become available

## Troubleshooting

### Authentication Fails

If clients receive 401 Unauthorized errors:

1. **Verify the key is correct**: Use `ditto-edge-server api-key validate` to check the key matches the hash
2. **Check the Identity resource ID**: Ensure the HTTP server's `auth` list references the correct Identity resource name
3. **Verify the header format**: Ensure the request uses `Authorization: Bearer <key>` format
4. **Check Edge Server logs**: Look for authentication-related errors in the server logs

### Key Validation Fails

If `ditto-edge-server api-key validate` reports the key is invalid:

1. **Check for whitespace**: Ensure there's no extra whitespace in the key or hash
2. **Verify the hash format**: Hashes should be base64-encoded strings starting with the algorithm identifier
3. **Regenerate if needed**: If unsure, generate a new key-hash pair and update your configuration

## Related Resources

* [Identity Configuration Reference](/edge-server/configuration/reference/identity-resource)
* [PermissionSet Configuration Reference](/edge-server/configuration/reference/permission-set-resource)
* [HTTP Server Configuration](/edge-server/configuration/http-server)
* [HTTP Server Configuration Reference](/edge-server/configuration/reference/http-server-resource)
