# HMAC Authentication for Quable App

## Overview

All requests sent from Quable PIM to your application can be authenticated using an HMAC (Hash-based Message Authentication Code) mechanism with SHA-256.

## How It Works

Authentication relies on two custom HTTP headers:
- `X-Timestamp` Unix timestamp of the request time
- `X-Signature` HMAC signature encoded in base64

## Generating the HMAC Signature

### 1. Building the String to Sign

The signature is calculated from a string constructed with the following elements, separated by the pipe character `|`:

```
{METHOD}|{ENDPOINT}|{TIMESTAMP}|{PAYLOAD}
```

**Component Details:**

| Component | Description | Example |
|-----------|-------------|---------|
| `METHOD` | HTTP method in UPPERCASE | `POST`, `GET` |
| `ENDPOINT` | Your declared QuableApp Endpoint | `https:myapp.mydomain.tld or https:www.mydomain.tld/myapp ...` |
| `TIMESTAMP` | Unix timestamp (seconds since epoch) | `1727712000` |
| `PAYLOAD` | Request body in JSON (empty for GET) | `{"key":"value"}` or `""` |

**Example string to sign:**
```
POST|https:www.mydomain.tld/myapp|1727712000|{"object":{"type":"product","ids":["PROD1"]},"slot":"document.page.tab"}
```

### 2. Computing the HMAC-SHA256

The signature is calculated using:
- **Algorithm**: HMAC-SHA256
- **Secret key**: The shared secret provided by Quable during app configuration
- **Message**: The string built in step 1
- **Format**: Binary output (raw output)

### 3. Base64 Encoding

The binary HMAC result is then encoded in base64 to be transmitted in the HTTP header.

## Validating Requests in Your Application

Your application must validate each incoming request:

### Validation Steps

1. **Extract headers** `X-Timestamp` and `X-Signature`
2. **Verify timestamp validity** (±5 minutes tolerance recommended to avoid rejections due to clock drift)
3. **Rebuild the string to sign** with the same parameters
4. **Calculate the expected HMAC** with your secret
5. **Compare signatures** securely (use constant-time comparison to prevent timing attacks)

### Validation Example (PHP)

```php
public function validateRequest($method, $endpoint, $payload, $receivedTimestamp, $receivedSignature) {
    // Check timestamp (5 minutes tolerance)
    $currentTime = time();
    $timeDiff = abs($currentTime - (int)$receivedTimestamp);
    if ($timeDiff > 300) {
        throw new Exception('Request timestamp expired');
    }
    
    // Rebuild the string to sign
    $string_to_sign = implode('|', array(
        strtoupper($method),
        $endpoint,
        $receivedTimestamp,
        $payload
    ));
    
    // Calculate expected HMAC
    $expectedSignature = base64_encode(
        hash_hmac('sha256', $string_to_sign, $this->getSecret(), true)
    );
    
    // Secure signature comparison
    if (!hash_equals($expectedSignature, $receivedSignature)) {
        throw new Exception('Invalid signature');
    }
    
    return true;
}
```

## Best Practices

✅ **Do:**
- Store the secret securely (environment variables, vault)
- Use constant-time comparison (`hash_equals` in PHP)
- Implement a timestamp tolerance window (5 minutes recommended)
- Log failed authentication attempts
- Reject requests without authentication headers

❌ **Don't:**
- Hardcode the secret in your code
- Compare signatures with `==` (vulnerable to timing attacks)
- Accept timestamps that are too old or in the future
- Ignore validation errors

## Troubleshooting

### Error: "Invalid signature"

**Possible causes:**
- Incorrect or misconfigured secret
- Wrong order of components in the string to sign
- Different character encoding (watch out for UTF-8)
- Modified or malformed payload
- HTTP method in wrong case

**Solution:** Log the string to sign on both sides for comparison

### Error: "Request timestamp expired"

**Possible causes:**
- Clocks out of sync between servers
- Replayed request (replay attack)
- High network latency

**Solution:** Check NTP synchronization, adjust tolerance window

## Resources

- [RFC 2104 - HMAC Specification](https://tools.ietf.org/html/rfc2104)
- [OWASP - Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)
