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

# Authentication

All requests to the external API gateway require authentication headers. These headers validate the request and ensure secure access to your organization's data.

***

## Authentication Architecture & Signature Flow

The diagram below details how incoming requests are authenticated, timestamp/nonce-verified, signature-checked, and checked against IP whitelists.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant Client as External Application
    participant Gateway as API Gateway Guard
    participant DB as System DB (api_integrations)
    
    Client->>Gateway: Send Request + Headers (x-client-id, x-nonce, x-timestamp)
    Gateway->>DB: Query Integration Details by Client ID
    alt Integration Key Not Found / Inactive
        Gateway-->>Client: 401 Unauthorized (INVALID_OR_INACTIVE_CLIENT_ID)
    end
    
    Gateway->>Gateway: Check Incoming IP vs allowedIps
    alt IP Not Whitelisted
        Gateway-->>Client: 403 Forbidden (IP_NOT_ALLOWED)
    end

    Gateway->>Gateway: Check Timestamp Expiry (< 5 mins) & Nonce Replay
    alt Timestamp Expired or Nonce Reused
        Gateway-->>Client: 401 Unauthorized (TIMESTAMP_EXPIRED / NONCE_ALREADY_USED)
    end
    
    opt For State-Changing Requests (POST / PUT / PATCH)
        Gateway->>Gateway: Recompute HMAC-SHA256(clientSecret, base64(body))
        alt Signature Mismatch
            Gateway-->>Client: 401 Unauthorized (INVALID_SIGNATURE)
        end
    end
    
    Gateway-->>Client: Process Request & Return Data (200 OK / 201 Created)
```

***

### Request Headers

Include the following credentials and metadata in your request headers:

| Header        | Description                                                                         | Example                                     |
| :------------ | :---------------------------------------------------------------------------------- | :------------------------------------------ |
| `x-client-id` | The unique Client ID assigned to your application.                                  | `veda_pub_a935d5f172268cdf122572defcc2631b` |
| `x-nonce`     | A unique random string generated fresh for every request to prevent replay attacks. | `2346301255735`                             |
| `x-timestamp` | The current UTC timestamp in milliseconds when the request is sent.                 | `1696301254321`                             |

***

### Example GET Request

```bash theme={null}
curl -X GET "https://api.yourdomain.com/api/v1/external/products" \
     -H "x-client-id: veda_pub_a935d5f172268cdf122572defcc2631b" \
     -H "x-nonce: 2346301255735" \
     -H "x-timestamp: 1696301254321"
```

***

## Request Signing (POST / PUT / PATCH)

For all state-changing requests (`POST`, `PUT`, `PATCH`), you must include a cryptographic signature of the JSON payload. This signature ensures payload integrity and authenticity.

### How to Generate the Signature

1. **Inject Nonce and Timestamp**: Before signing, add `nonce` (a unique random string) and `timestamp` (current Unix timestamp as an integer in milliseconds) directly into your JSON payload body.
2. **Base64 Encode Payload**: Convert the complete JSON payload into stringified JSON and encode it into a Base64 string.
3. **Compute HMAC-SHA256**: Hash the Base64-encoded string using the HMAC-SHA256 algorithm with your **Client Secret** (e.g., `veda_sec_cceac1bd...`) as the secret key.
4. **Attach Signature**: Include the resulting hexadecimal signature string under the `signature` field inside your JSON payload body.

### Example in Node.js

```javascript theme={null}
const crypto = require('crypto');

function prepareSignedPayload(payload, clientSecret) {
  // 1. Add unique timestamp and nonce to the body
  payload.timestamp = Date.now();
  payload.nonce = crypto.randomUUID();

  // 2. Base64 encode the payload string
  const jsonString = JSON.stringify(payload);
  const base64Payload = Buffer.from(jsonString).toString('base64');

  // 3. Generate the HMAC-SHA256 signature
  const signature = crypto
    .createHmac('sha256', clientSecret)
    .update(base64Payload)
    .digest('hex');

  // 4. Attach signature to payload
  payload.signature = signature;

  return payload;
}
```

***

## Authentication Error Responses

Below are the exact JSON error responses returned by the gateway when authentication checks fail:

### 1. Missing or Invalid Client ID (`401 Unauthorized`)

```json theme={null}
{
  "success": false,
  "status": 401,
  "message": "Invalid or inactive Client ID or API Key."
}
```

### 2. Missing Header (`401 Unauthorized`)

```json theme={null}
{
  "success": false,
  "status": 401,
  "message": "Request timestamp (x-timestamp) is missing."
}
```

### 3. Expired Timestamp (`401 Unauthorized`)

```json theme={null}
{
  "success": false,
  "status": 401,
  "message": "Request timestamp expired or invalid."
}
```

### 4. Nonce Replay Attack Detected (`401 Unauthorized`)

```json theme={null}
{
  "success": false,
  "status": 401,
  "message": "Replay attack detected: Request nonce already used."
}
```

### 5. IP Address Not Whitelisted (`403 Forbidden`)

```json theme={null}
{
  "success": false,
  "status": 403,
  "message": "Access denied from IP address: 203.0.113.99"
}
```
