feat(kernos): implement optional API key authentication for MCP
Added kernos_api_keys configuration variable to enable optional request authentication via Bearer or X-Api-Key headers. Updated Kernos documentation with setup instructions and usage examples. Also corrected FastAPI project port assignments in Ouranos docs.
This commit is contained in:
@@ -19,4 +19,9 @@ ENVIRONMENT={{ kernos_environment | default('production') }}
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Comma-separated whitelist of allowed commands
|
# Comma-separated whitelist of allowed commands
|
||||||
# Commands after shell operators (;, &&, ||, |) are also validated
|
# Commands after shell operators (;, &&, ||, |) are also validated
|
||||||
ALLOW_COMMANDS={{ kernos_allow_commands }}
|
ALLOW_COMMANDS={{ kernos_allow_commands }}
|
||||||
|
|
||||||
|
# Optional API keys for authentication (comma-separated)
|
||||||
|
# When set, all MCP requests require authentication
|
||||||
|
# Leave empty to disable authentication
|
||||||
|
API_KEYS={{ kernos_api_keys | default('') }}
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ HTTP-enabled MCP shell server using FastMCP. Wraps the existing `mcp-shell-serve
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **HTTP Transport**: Accessible via URL instead of stdio
|
- **HTTP Transport**: Accessible via URL instead of stdio
|
||||||
|
- **API Key Authentication**: Optional per-request authentication for MCP endpoints
|
||||||
- **Health Endpoints**: `/live`, `/ready`, `/health` for Kubernetes-style probes
|
- **Health Endpoints**: `/live`, `/ready`, `/health` for Kubernetes-style probes
|
||||||
- **Prometheus Metrics**: `/metrics` endpoint for monitoring
|
- **Prometheus Metrics**: `/metrics` endpoint for monitoring
|
||||||
- **JSON Structured Logging**: Production-ready log format with correlation IDs
|
- **JSON Structured Logging**: Production-ready log format with correlation IDs
|
||||||
- **Full Security**: Command whitelisting inherited from `mcp-shell-server`
|
- **Full Security**: Command whitelisting and API key authentication
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
@@ -61,7 +62,8 @@ Deploys Kernos to caliban.incus:
|
|||||||
| `kernos_log_level` | Python log level |
|
| `kernos_log_level` | Python log level |
|
||||||
| `kernos_log_format` | Log format (`json` or `text`) |
|
| `kernos_log_format` | Log format (`json` or `text`) |
|
||||||
| `kernos_environment` | Environment name for logging |
|
| `kernos_environment` | Environment name for logging |
|
||||||
| `kernos_allow_commands` |Comma-separated command whitelist |
|
| `kernos_allow_commands` | Comma-separated command whitelist |
|
||||||
|
| `kernos_api_keys` | Comma-separated API keys for authentication (optional) |
|
||||||
|
|
||||||
### Global Variables (`ansible/inventory/group_vars/all/vars.yml`)
|
### Global Variables (`ansible/inventory/group_vars/all/vars.yml`)
|
||||||
|
|
||||||
@@ -97,6 +99,82 @@ The systemd service includes additional hardening:
|
|||||||
- `ProtectHome=true`
|
- `ProtectHome=true`
|
||||||
- `ReadWritePaths=/tmp`
|
- `ReadWritePaths=/tmp`
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Kernos supports optional API key authentication. When enabled, all MCP requests (tools, resources, prompts) must include a valid key. Health and metrics endpoints (`/live`, `/ready`, `/health`, `/metrics`) remain open for probes and monitoring.
|
||||||
|
|
||||||
|
### Generating API Keys
|
||||||
|
|
||||||
|
Generate a cryptographically secure key with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Using openssl (recommended)
|
||||||
|
openssl rand -hex 32
|
||||||
|
|
||||||
|
# Or using Python
|
||||||
|
python3 -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enabling Authentication
|
||||||
|
|
||||||
|
Add API keys to your host variables in `ansible/inventory/host_vars/caliban.incus.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Single key
|
||||||
|
kernos_api_keys: "a1b2c3d4e5f6..."
|
||||||
|
|
||||||
|
# Multiple keys (comma-separated)
|
||||||
|
kernos_api_keys: "key-for-alice,key-for-bob,key-for-ci-pipeline"
|
||||||
|
```
|
||||||
|
|
||||||
|
When `kernos_api_keys` is empty or unset, authentication is disabled (open access).
|
||||||
|
|
||||||
|
### Sending the Key
|
||||||
|
|
||||||
|
Clients authenticate via either header:
|
||||||
|
|
||||||
|
| Header | Format |
|
||||||
|
|--------|--------|
|
||||||
|
| `Authorization` | `Bearer <key>` |
|
||||||
|
| `X-Api-Key` | `<key>` |
|
||||||
|
|
||||||
|
#### FastMCP Client
|
||||||
|
|
||||||
|
```python
|
||||||
|
from fastmcp import Client
|
||||||
|
|
||||||
|
async with Client(
|
||||||
|
"http://caliban.incus:22021/mcp",
|
||||||
|
auth="your-api-key-here",
|
||||||
|
) as client:
|
||||||
|
result = await client.call_tool("shell_execute", {"command": ["ls", "-la"]})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### curl
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Using Authorization header
|
||||||
|
curl -H "Authorization: Bearer your-api-key-here" http://caliban.incus:22021/mcp/
|
||||||
|
|
||||||
|
# Using X-Api-Key header
|
||||||
|
curl -H "X-Api-Key: your-api-key-here" http://caliban.incus:22021/mcp/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### MCP client config (e.g. Claude Desktop, OpenAI)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"kernos": {
|
||||||
|
"url": "http://caliban.incus:22021/mcp/",
|
||||||
|
"headers": {
|
||||||
|
"Authorization": "Bearer your-api-key-here"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Testing Health Endpoints
|
### Testing Health Endpoints
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Each project has a number that is used to determine port numbers.
|
|||||||
- Gitea Runner (CI/CD agent)
|
- Gitea Runner (CI/CD agent)
|
||||||
- Django Projects: Zelus (221), Angelia (222), Athena (224), Kairos (225), Icarlos (226), MCP Switchboard (227), Spelunker (228), Peitho (229), Mnemosyne (230)
|
- Django Projects: Zelus (221), Angelia (222), Athena (224), Kairos (225), Icarlos (226), MCP Switchboard (227), Spelunker (228), Peitho (229), Mnemosyne (230)
|
||||||
- FastAgent Projects: Pallas (240)
|
- FastAgent Projects: Pallas (240)
|
||||||
- FastAPI Projects: Daedalus (200), Arke (201) Kernos (202), Stentor (203), Orpheus (204), Periplus (205), Nike (206)
|
- FastAPI Projects: Daedalus (200), Arke (201) Kernos (202), Rommie (203), Orpheus (204), Periplus (205), Nike (206), Stentor (207)
|
||||||
|
|
||||||
### caliban — Agent Automation
|
### caliban — Agent Automation
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user