# Webhook Credential Configuration

Configure how Gensail authenticates when sending webhooks to your server. This allows you to secure your webhook endpoint by requiring authentication on incoming requests from the pipeline.

## Overview

When you configure webhook credentials, the pipeline will include authentication headers when delivering webhooks to your endpoint. This is the **outbound** authentication (pipeline → your server), complementing the [webhook signature verification](/gensail-analytics/guides/webhook-authentication) which verifies the payload integrity.

## Authentication Types

### None (Default)

No authentication headers are added to webhook requests. Use this only for development or if your endpoint is secured by other means (e.g., IP allowlisting).

### Bearer Token

Sends an API key or token in the Authorization header:

```
Authorization: Bearer <your-token>
```

**Use cases:**

- API key authentication
- JWT tokens
- OAuth2 access tokens


### HMAC Signature

Sends an HMAC-SHA256 signature of the request body:

```
X-Signature: t=1734789600,v1=<hmac-signature>,key=<key-id>
```

**Use cases:**

- Stripe-style webhook verification
- Custom signature validation
- High-security requirements


### Basic Auth

Sends Base64-encoded username:password credentials:

```
Authorization: Basic <base64(username:password)>
```

**Use cases:**

- Legacy systems
- Simple authentication requirements
- Basic HTTP authentication


## API Endpoints

### Get Current Credential

```http
GET /api/v1/config/{entity_type}/{entity_id}/webhook-credential
Authorization: Bearer <platform-token>
```

**Path Parameters:**

| Parameter | Type | Description |
|  --- | --- | --- |
| `entity_type` | string | One of: `partner`, `organization`, `workspace` |
| `entity_id` | uuid | The entity's unique identifier |


**Response (200 OK):**

```json
{
  "credential_id": "550e8400-e29b-41d4-a716-446655440000",
  "credential_hint": "...x7f9",
  "auth_type": "bearer",
  "header_name": "Authorization"
}
```

**Response (404 Not Found):**

```json
{
  "detail": "No webhook credential configured"
}
```

### Create or Update Credential

```http
POST /api/v1/config/{entity_type}/{entity_id}/webhook-credential
Authorization: Bearer <platform-token>
Content-Type: application/json
```

**Request Body:**

```json
{
  "auth_type": "bearer",
  "credential": "your-api-key-or-token",
  "secret": null,
  "header_name": "Authorization"
}
```

**Request Fields:**

| Field | Type | Required | Description |
|  --- | --- | --- | --- |
| `auth_type` | string | Yes | One of: `bearer`, `hmac`, `basic` |
| `credential` | string | Yes | API key (bearer), key ID (hmac), or username (basic) |
| `secret` | string | Conditional | HMAC secret or password (required for `hmac` and `basic`) |
| `header_name` | string | No | Custom header name (defaults: `Authorization` for bearer/basic, `X-Signature` for hmac) |


**Response (200 OK):**

```json
{
  "credential_id": "550e8400-e29b-41d4-a716-446655440000",
  "credential_hint": "...x7f9",
  "auth_type": "bearer",
  "header_name": "Authorization"
}
```

### Delete Credential

```http
DELETE /api/v1/config/{entity_type}/{entity_id}/webhook-credential
Authorization: Bearer <platform-token>
```

**Response (200 OK):**

```json
{
  "message": "Webhook credential deleted",
  "auth_type": "none"
}
```

## Configuration Examples

### Bearer Token Authentication

```bash
curl -X POST \
  "https://analytics-api.gensail.com/api/v1/config/partner/YOUR_PARTNER_ID/webhook-credential" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auth_type": "bearer",
    "credential": "sk_live_abc123xyz789"
  }'
```

Your webhook endpoint will receive:

```http
POST /your-webhook-endpoint HTTP/1.1
Authorization: Bearer sk_live_abc123xyz789
Content-Type: application/json
X-Signature: t=1734789600,v1=...

{"job_id": "...", "status": "completed", ...}
```

### HMAC Signature Authentication

```bash
curl -X POST \
  "https://analytics-api.gensail.com/api/v1/config/partner/YOUR_PARTNER_ID/webhook-credential" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auth_type": "hmac",
    "credential": "key_production_001",
    "secret": "whsec_supersecretkey123"
  }'
```

Your webhook endpoint will receive:

```http
POST /your-webhook-endpoint HTTP/1.1
X-Signature: t=1734789600,v1=a3b2c1d4e5f6...,key=key_production_001
Content-Type: application/json

{"job_id": "...", "status": "completed", ...}
```

### Basic Auth

```bash
curl -X POST \
  "https://analytics-api.gensail.com/api/v1/config/partner/YOUR_PARTNER_ID/webhook-credential" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auth_type": "basic",
    "credential": "webhook_user",
    "secret": "secure_password_123"
  }'
```

Your webhook endpoint will receive:

```http
POST /your-webhook-endpoint HTTP/1.1
Authorization: Basic d2ViaG9va191c2VyOnNlY3VyZV9wYXNzd29yZF8xMjM=
Content-Type: application/json

{"job_id": "...", "status": "completed", ...}
```

### Custom Header Name

For endpoints that expect authentication in a non-standard header:

```bash
curl -X POST \
  "https://analytics-api.gensail.com/api/v1/config/partner/YOUR_PARTNER_ID/webhook-credential" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auth_type": "bearer",
    "credential": "api_key_12345",
    "header_name": "X-API-Key"
  }'
```

Your webhook endpoint will receive:

```http
POST /your-webhook-endpoint HTTP/1.1
X-API-Key: api_key_12345
Content-Type: application/json

{"job_id": "...", "status": "completed", ...}
```

## Configuration Hierarchy

Webhook credentials follow the standard configuration hierarchy:

```
Platform → Partner → Organization → Workspace
```

Credentials configured at a lower level override those at higher levels. For example:

- A partner-level credential applies to all organizations and workspaces
- An organization can override with its own credential
- A workspace can have its own specific credential


## Security Considerations

### Credential Storage

All credentials are encrypted at rest using Fernet symmetric encryption. Only the last 4 characters are stored as a hint for identification purposes.

### Credential Rotation

To rotate credentials:

1. Generate a new credential on your server
2. Update the credential via the API
3. Verify webhooks are being received with the new credential
4. Revoke the old credential on your server


### Best Practices

1. **Use HTTPS**: Always configure webhook URLs with HTTPS
2. **Rotate regularly**: Rotate credentials periodically (e.g., every 90 days)
3. **Use strong secrets**: Generate cryptographically random secrets
4. **Monitor failures**: Watch for webhook delivery failures after credential changes
5. **Test first**: Configure in test environment before production


## Troubleshooting

### "401 Unauthorized" on Webhook Delivery

1. **Verify credential is set**: Use GET to check current configuration
2. **Check credential value**: Ensure the credential matches what your server expects
3. **Verify header name**: Confirm your server checks the correct header
4. **Check encoding**: For basic auth, ensure proper Base64 handling


### "No webhook credential configured"

The entity doesn't have a credential set. Either:

- Configure one using POST
- Or the entity inherits from a parent (check parent entity)


### Credential Not Taking Effect

1. Wait a few seconds for cache invalidation
2. Trigger a new webhook (e.g., reprocess a job)
3. Check webhook delivery logs for the auth header


## Related Documentation

- [Webhook Authentication (Signature Verification)](/gensail-analytics/guides/webhook-authentication) - Verify incoming webhook payloads


## Support

For questions about webhook credential configuration, contact [support@gensail.com](mailto:support@gensail.com).