diff --git a/ansible/kernos/.env.j2 b/ansible/kernos/.env.j2 index 74712e0..edd89a2 100644 --- a/ansible/kernos/.env.j2 +++ b/ansible/kernos/.env.j2 @@ -19,4 +19,9 @@ ENVIRONMENT={{ kernos_environment | default('production') }} # ============================================================================ # Comma-separated whitelist of allowed commands # Commands after shell operators (;, &&, ||, |) are also validated -ALLOW_COMMANDS={{ kernos_allow_commands }} \ No newline at end of file +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('') }} diff --git a/docs/kernos.md b/docs/kernos.md index a475d3d..efb8438 100644 --- a/docs/kernos.md +++ b/docs/kernos.md @@ -5,10 +5,11 @@ HTTP-enabled MCP shell server using FastMCP. Wraps the existing `mcp-shell-serve ## Features - **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 - **Prometheus Metrics**: `/metrics` endpoint for monitoring - **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 @@ -61,7 +62,8 @@ Deploys Kernos to caliban.incus: | `kernos_log_level` | Python log level | | `kernos_log_format` | Log format (`json` or `text`) | | `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`) @@ -97,6 +99,82 @@ The systemd service includes additional hardening: - `ProtectHome=true` - `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 ` | +| `X-Api-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 ### Testing Health Endpoints diff --git a/docs/ouranos.md b/docs/ouranos.md index 4e7efc7..99b7cfb 100644 --- a/docs/ouranos.md +++ b/docs/ouranos.md @@ -44,7 +44,7 @@ Each project has a number that is used to determine port numbers. - 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) - 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