# NodeHive API Key Management

OpenAI-style API key authentication for Drupal JSON:API, REST, and NodeHive API endpoints.

## Features

- **Secure Authentication**: Bearer token authentication using `Authorization: Bearer <key>` header
- **Hashed Storage**: API keys are hashed (SHA-256) before storage
- **Rate Limiting**: Configurable per-key rate limits using Drupal's Flood API
- **IP Allowlisting**: Optional IP restrictions per key
- **Expiry Dates**: Set expiration dates for keys
- **Scope Support**: JSON-based scope definitions (future expansion)
- **Usage Tracking**: Track last used date and total usage count
- **Audit Logging**: All authentication attempts are logged

## Installation

1. Enable the module:
   ```bash
   ddev drush en nodehive_api_key_management -y
   ```

2. Clear cache:
   ```bash
   ddev drush cr
   ```

3. Grant permissions to the `api_service` user:
   - Go to `/admin/people`
   - Find the `api_service` user
   - Edit and assign appropriate roles/permissions for JSON:API access

## Usage

### Creating API Keys

1. Navigate to `/admin/config/services/api-keys`
2. Click "Add key"
3. Fill in the form:
   - **Key Name**: Human-readable identifier
   - **Rate Limit**: Requests per hour (0 = unlimited)
   - **Expiry Date**: Optional expiration
   - **Scopes**: Optional JSON array of allowed scopes
   - **IP Allowlist**: Optional JSON array of allowed IPs
4. Submit the form
5. **Copy the generated key immediately** - it won't be shown again

### Using API Keys

Include the API key in the `Authorization` header with the `Bearer` scheme:

```bash
curl -H "Authorization: Bearer nhk_<your_key_here>" \
     -H "Accept: application/vnd.api+json" \
     https://your-site.com/jsonapi/node/article
```

### Protected Endpoints

The authentication provider automatically protects:
- `/jsonapi/*` - Drupal JSON:API endpoints
- `/api/*` - Custom API endpoints
- `/cdp/api/*` - NodeHive CDP API endpoints

### Managing Keys

- **Edit**: Update name, status, rate limits, expiry, IP allowlist
- **Revoke**: Disable a key (can be re-enabled via edit)
- **Delete**: Permanently remove a key

## Testing

### Test without authentication (should fail):
```bash
ddev exec "curl -s http://web/cdp/api/stats"
```

### Test with valid API key:
```bash
# First create a key via the UI, then:
ddev exec "curl -s -H 'Authorization: Bearer nhk_YOUR_KEY' http://web/cdp/api/stats"
```

### Test JSON:API endpoint:
```bash
ddev exec "curl -s -H 'Authorization: Bearer nhk_YOUR_KEY' \
  -H 'Accept: application/vnd.api+json' \
  http://web/jsonapi/node/article"
```

## Security Considerations

1. **Key Storage**: Keys are hashed with SHA-256 before database storage
2. **One-time Display**: Full keys are shown only once at creation
3. **Rate Limiting**: Flood API prevents abuse
4. **Audit Logs**: All attempts logged to `nodehive_api_key_management` channel
5. **IP Restrictions**: Optional per-key IP allowlisting
6. **Service User**: All requests act as the `api_service` user

## Database Schema

Table: `nodehive_api_keys`

- `id`: Primary key
- `name`: Human-readable name
- `key_hash`: SHA-256 hash of the key
- `key_prefix`: First 10 characters for identification
- `status`: Active (1) or revoked (0)
- `scopes`: JSON array of allowed scopes
- `expiry`: Unix timestamp for expiration
- `rate_limit`: Max requests per hour
- `ip_allowlist`: JSON array of allowed IPs
- `created`: Creation timestamp
- `changed`: Last modified timestamp
- `last_used`: Last authentication timestamp
- `use_count`: Total authentication count

## Permissions

- `administer api keys`: Full CRUD access to keys
- `view api keys`: View key list (without actual key values)
- `use api keys`: Use API keys for authentication

## Troubleshooting

### API key not working

1. Check the key is active: `/admin/config/services/api-keys`
2. Verify not expired
3. Check rate limit not exceeded
4. Verify IP allowlist (if configured)
5. Check logs: `ddev drush watchdog:show --channel=nodehive_api_key_management`

### Service user permissions

The `api_service` user needs appropriate permissions:
- Access JSON:API resources
- Entity-specific read/write permissions

## Development

### Generate key programmatically:
```php
$api_key_manager = \Drupal::service('nodehive_api_key_management.api_key_manager');
$key = $api_key_manager->generateKey();
$key_id = $api_key_manager->createKey('My API Key', $key, [
  'rate_limit' => 1000,
  'expiry' => strtotime('+1 year'),
]);
```

### Validate key:
```php
$api_key_manager = \Drupal::service('nodehive_api_key_management.api_key_manager');
$key_record = $api_key_manager->validateKey($key);
if ($key_record) {
  // Valid key
}
```
