External security audit of KNEL-AIMiddleware before release: - FINAL-REPORT.md: Executive summary, risk assessment, remediation roadmap - 01-dockerfile-security.md: 38/40 containers run as root (HIGH) - 02-shell-script-security.md: 83 missing set -e/u directives (HIGH) - 03-docker-compose-security.md: 3 privileged services documented (MEDIUM) - 04-secrets-audit.md: PASS - no hardcoded secrets found - 05-vulnerability-scan.md: 14+ CVEs, 1 CRITICAL OpenSSL (golang:1.23-alpine) Assessment: CONDITIONAL PASS for release 💘 Generated with Crush Assisted-by: GLM-5 via Crush <crush@charm.land>
5.8 KiB
Docker Compose Security Audit
Date: 2026-02-20
Auditor: External Security Review
Scope: docker-compose.yml and container orchestration
Executive Summary
| Metric | Value |
|---|---|
| Total Services | 40+ |
| High Severity Issues | 3 |
| Medium Severity Issues | 1 |
| Low Severity Issues | 1 |
Detailed Findings
1. Docker Socket Mount (HIGH)
Severity: HIGH
Affected Services: docker-mcp, mcp-ansible
CWE: CWE-250 (Execution with Unnecessary Privileges)
Description
Two services mount the Docker socket, granting full Docker daemon access:
# docker-mcp
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# mcp-ansible
volumes:
- /var/run/docker.sock:/var/run/docker.sock
This provides equivalent access to root on the host system.
Impact
- Full control over all containers on host
- Ability to mount host filesystem
- Potential for container escape
- Access to secrets in other containers
Risk Assessment
- Necessary for Function: Yes - these services manage Docker/containers
- Mitigation Required: Yes
Recommendation
- Run these services with explicit user constraints where possible
- Document the privilege requirement clearly
- Consider socket proxy (docker-socket-proxy) for least privilege
- Isolate on dedicated management nodes in production
# Alternative with socket proxy
services:
docker-mcp:
environment:
- DOCKER_HOST=tcp://docker-proxy:2375
depends_on:
- docker-proxy
docker-proxy:
image: tecnativa/docker-socket-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- CONTAINERS=1
- IMAGES=1
# Only allow specific operations
2. Kubernetes Config Mount (HIGH)
Severity: HIGH
Affected Service: kubernetes-mcp
CWE: CWE-250 (Execution with Unnecessary Privileges)
Description
The kubernetes-mcp service mounts kubeconfig:
volumes:
- ~/.kube/config:/home/appuser/.kube/config:ro
This grants Kubernetes cluster admin access to the container.
Impact
- Full control over Kubernetes cluster
- Access to all secrets in cluster
- Ability to deploy privileged workloads
- Cluster admin equivalent access
Risk Assessment
- Necessary for Function: Yes - required for Kubernetes management
- Mitigation Required: Yes
Recommendation
- Use read-only mount (
:roflag) - already implemented - Consider ServiceAccount tokens instead of kubeconfig
- Implement RBAC with minimal required permissions
- Document required permissions clearly
3. Privileged Access Pattern (MEDIUM)
Severity: MEDIUM Affected: Multiple services requiring system access CWE: CWE-269 (Improper Privilege Management)
Description
Several services require elevated privileges for their function:
| Service | Privilege Type | Justification |
|---|---|---|
| docker-mcp | Docker socket | Container management |
| mcp-ansible | Docker socket | Container orchestration |
| kubernetes-mcp | kubeconfig | Cluster management |
| ssh-mcp | SSH keys | Remote server access |
Recommendation
Document each privileged service with:
- Required access level
- Business justification
- Mitigating controls
- Audit logging requirements
4. Default Credential Pattern (LOW)
Severity: LOW
Affected Service: ghost-mcp
CWE: CWE-1188 (Initialization with Hard-Coded Network Resource Configuration)
Description
Ghost MCP service shows a placeholder credential pattern:
# Line 224
environment:
- GHOST_API_KEY=${GHOST_API_KEY:-your-api-key-here}
While this is a placeholder (not a real credential), it establishes a pattern that could lead to:
- Developers committing real credentials
- Default credentials being used in development
Recommendation
- Remove default values entirely
- Fail fast if required variables not set
- Use
${VAR:?VAR must be set}pattern
environment:
- GHOST_API_KEY=${GHOST_API_KEY:?GHOST_API_KEY must be set}
Network Security Analysis
Network Configuration
All services use default Docker networking (bridge). No custom networks defined.
Recommendations
- Create isolated networks for service groups:
networks:
mcp-servers:
driver: bridge
lsp-servers:
driver: bridge
- Limit inter-service communication where not required
Resource Limits
Current State
No resource limits defined for any service.
Risk
- Resource exhaustion (memory/CPU)
- Noisy neighbor problems
- Potential denial of service
Recommendation
Add resource constraints:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
memory: 256M
Health Checks
Current State
No health checks defined.
Recommendation
Add health checks for monitoring:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Positive Findings
- No host network mode - Services use bridge networking
- No privileged mode - No containers run with
privileged: true - Environment variables externalized - Using
.envfile pattern - Read-only mounts where appropriate - kubeconfig mounted read-only
- Consistent container naming -
kneldevstack-aimiddleware-prefix
Remediation Priority
| Priority | Finding | Effort | Impact |
|---|---|---|---|
| 1 | Document privileged services | Low | High |
| 2 | Add resource limits | Low | Medium |
| 3 | Implement socket proxy for Docker access | Medium | High |
| 4 | Remove default credential patterns | Low | Low |
| 5 | Add health checks | Medium | Medium |
| 6 | Create network segmentation | Medium | Medium |