4.4 KiB
Security
Authentication
AegisGitea MCP uses bearer token authentication. Clients must include a valid API key with every tool call.
How It Works
- The client sends
Authorization: Bearer <key>with its request. - The server extracts the token and validates it against the configured
MCP_API_KEYS. - Comparison is done in constant time to prevent timing attacks.
- If validation fails, the failure is counted against the client's IP address.
Generating API Keys
Use the provided script to generate cryptographically secure 64-character hex keys:
make generate-key
# or: python scripts/generate_api_key.py
Keys must be at least 32 characters long. The script also saves metadata (creation date, expiration) to a keys/ directory.
Multiple Keys (Grace Period During Rotation)
You can configure multiple keys separated by commas. This allows you to add a new key and remove the old one without downtime:
MCP_API_KEYS=newkey...,oldkey...
Remove the old key from the list after all clients have been updated.
Key Rotation
Rotate keys regularly (recommended: every 90 days).
make rotate-key
# or: python scripts/rotate_api_key.py
The rotation script:
- Reads the current key from
.env - Generates a new key
- Offers to replace the key immediately or add it alongside the old key (grace period)
- Creates a backup of your
.envbefore modifying it
Checking Key Age
make check-key-age
# or: python scripts/check_key_age.py
Exit codes: 0 = OK, 1 = expiring within 7 days (warning), 2 = already expired (critical).
Rate Limiting
Failed authentication attempts are tracked per client IP address.
| Setting | Default | Description |
|---|---|---|
MAX_AUTH_FAILURES |
5 |
Maximum failures before the IP is blocked |
AUTH_FAILURE_WINDOW |
300 |
Rolling window in seconds |
Once an IP exceeds the threshold, all further requests from that IP return HTTP 429 until the window resets. This is enforced entirely in memory — a server restart resets the counters.
Audit Logging
All security-relevant events are written to a structured JSON log file.
Log Location
Default: /var/log/aegis-mcp/audit.log
Configurable via AUDIT_LOG_PATH.
The directory is created automatically on startup.
What Is Logged
| Event | Description |
|---|---|
| Tool invocation | Every call to a tool: tool name, arguments, result status, correlation ID |
| Access denied | Failed authentication attempts: IP address, reason |
| Security event | Rate limit triggers, invalid key formats, startup authentication status |
Log Format
Each entry is a JSON object on a single line:
{
"timestamp": "2026-02-13T10:00:00Z",
"event": "tool_invocation",
"correlation_id": "a1b2c3d4-...",
"tool": "get_file_contents",
"owner": "myorg",
"repo": "backend",
"path": "src/main.py",
"result": "success",
"client_ip": "10.0.0.1"
}
Using Logs for Monitoring
Because entries are newline-delimited JSON, they are easy to parse:
# Show all failed tool calls
grep '"result": "error"' /var/log/aegis-mcp/audit.log | jq .
# Show all access-denied events
grep '"event": "access_denied"' /var/log/aegis-mcp/audit.log | jq .
Access Control Model
AegisGitea MCP does not implement its own repository access control. Access to repositories is determined entirely by the Gitea bot user's permissions:
- If the bot user has no access to a repository, it will not appear in
list_repositoriesandget_repository_infowill return an error. - Grant the bot user the minimum set of repository permissions needed.
Principle of least privilege: create a dedicated bot user and grant it read-only access only to the repositories that the AI needs to see.
Network Security Recommendations
- Run the MCP server behind a reverse proxy (e.g. Traefik or nginx) with TLS.
- Do not expose the server directly on a public port without TLS.
- Restrict inbound connections to known AI client IP ranges where possible.
- The
/mcp/toolsendpoint is intentionally public (required for ChatGPT plugin discovery). If this is undesirable, restrict it at the network/proxy level.
Container Security
The provided Docker image runs with:
- A non-root user (
aegis, UID 1000) no-new-privilegessecurity option- CPU and memory resource limits (1 CPU, 512 MB)
See Deployment for details.