Files
KNEL-AIMiddleware/docs/audit/2026-02-20/03-docker-compose-security.md
Charles N Wyble 787fe1f702 docs(audit): add comprehensive security audit report
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>
2026-02-20 11:59:09 -05:00

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

  1. Run these services with explicit user constraints where possible
  2. Document the privilege requirement clearly
  3. Consider socket proxy (docker-socket-proxy) for least privilege
  4. 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

  1. Use read-only mount (:ro flag) - already implemented
  2. Consider ServiceAccount tokens instead of kubeconfig
  3. Implement RBAC with minimal required permissions
  4. 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

  1. Create isolated networks for service groups:
networks:
  mcp-servers:
    driver: bridge
  lsp-servers:
    driver: bridge
  1. 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

  1. No host network mode - Services use bridge networking
  2. No privileged mode - No containers run with privileged: true
  3. Environment variables externalized - Using .env file pattern
  4. Read-only mounts where appropriate - kubeconfig mounted read-only
  5. 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