DEV Community

Cover image for Running AI Agent Wallets as Non-Root: Docker UID 1001 Security Best Practices
Wallet Guy
Wallet Guy

Posted on

Running AI Agent Wallets as Non-Root: Docker UID 1001 Security Best Practices

Running AI agent wallets as non-root containers isn't just a security recommendation — it's essential for preventing privilege escalation attacks that could compromise your entire host system. When your trading bot or DeFi agent handles real funds, following the principle of least privilege becomes critical infrastructure hygiene.

Container security breaches are among the fastest-growing attack vectors in cloud infrastructure. A compromised root container can escape to the host, access other containers, and potentially drain not just your agent's wallet, but any other services running on the same machine. For self-hosters running AI agent infrastructure, this represents an existential risk to both funds and privacy.

Why Non-Root Containers Matter for AI Agent Wallets

Traditional wallet services run as root by default, creating unnecessary attack surface. When an AI agent makes hundreds of DeFi transactions daily, each API call, each smart contract interaction, and each transaction signing operation becomes a potential entry point. Running as root means a single vulnerability could escalate to full system compromise.

Self-hosted AI agent infrastructure faces unique challenges. Unlike simple web applications, agents need persistent access to private keys, maintain WebSocket connections to blockchain networks, and often integrate with external APIs that could serve malicious responses. The blast radius of a security incident extends beyond uptime to actual financial loss.

WAIaaS Non-Root Security Architecture

WAIaaS containers run as UID 1001 by default, implementing defense-in-depth security for self-hosted deployments. This design choice reflects a broader security philosophy: assume breach, limit impact.

Dockerfile Security Configuration

The WAIaaS Docker image implements several non-root security patterns:

# Create non-root user
RUN addgroup --system --gid 1001 waiaas && \
    adduser --system --uid 1001 --ingroup waiaas waiaas

# Switch to non-root user
USER waiaas:waiaas

# Ensure data directory permissions
WORKDIR /data
Enter fullscreen mode Exit fullscreen mode

This configuration ensures the containerized daemon never runs with root privileges, even if the host Docker daemon itself runs as root.

Docker Compose Security Best Practices

For production self-hosted deployments, WAIaaS supports additional hardening through Docker Compose security features:

services:
  daemon:
    image: ghcr.io/minhoyoo-iotrust/waiaas:latest
    container_name: waiaas-daemon
    user: "1001:1001"  # Explicitly set non-root user
    ports:
      - "127.0.0.1:3100:3100"  # Bind only to localhost
    volumes:
      - waiaas-data:/data
    environment:
      - WAIAAS_DATA_DIR=/data
      - WAIAAS_DAEMON_HOSTNAME=0.0.0.0
    security_opt:
      - no-new-privileges:true  # Prevent privilege escalation
    cap_drop:
      - ALL  # Drop all capabilities
    cap_add:
      - NET_BIND_SERVICE  # Only add required capabilities
    read_only: true  # Read-only root filesystem
    tmpfs:
      - /tmp
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3100/health"]
      interval: 30s
      timeout: 5s
      start_period: 10s
      retries: 3

volumes:
  waiaas-data:
    driver: local
Enter fullscreen mode Exit fullscreen mode

This configuration implements multiple security layers: non-root execution, capability dropping, read-only filesystems, and localhost-only network binding.

File System Permissions and Data Directory Security

Running as UID 1001 requires careful attention to volume mount permissions. WAIaaS handles this through intelligent entrypoint scripting that manages data directory ownership without requiring root privileges.

Auto-Provision Security Model

The auto-provision feature generates secure master passwords while maintaining non-root execution:

# Deploy with auto-provision (generates secure random password)
docker run -d \
  --name waiaas \
  --user 1001:1001 \
  -p 127.0.0.1:3100:3100 \
  -v waiaas-data:/data \
  -e WAIAAS_AUTO_PROVISION=true \
  ghcr.io/minhoyoo-iotrust/waiaas:latest

# Retrieve generated password securely
docker exec waiaas cat /data/recovery.key
Enter fullscreen mode Exit fullscreen mode

The auto-provisioned password uses cryptographically secure random generation, providing high entropy without requiring interactive setup that might compromise security in automated deployments.

Docker Secrets Integration

For production deployments, WAIaaS integrates with Docker Secrets to avoid environment variable exposure:

# Create secret files with proper permissions
mkdir -p secrets
echo "your-secure-password" > secrets/master_password.txt
chmod 600 secrets/master_password.txt
chown 1001:1001 secrets/master_password.txt

# Deploy with secrets overlay
docker compose -f docker-compose.yml -f docker-compose.secrets.yml up -d
Enter fullscreen mode Exit fullscreen mode

The secrets overlay ensures sensitive configuration never appears in process lists, environment variable dumps, or container inspection output.

Network Security and Localhost Binding

Self-hosted AI agent infrastructure should minimize network exposure. WAIaaS defaults to localhost-only binding (127.0.0.1:3100:3100) rather than exposing services on all interfaces.

This design choice reflects the security principle that AI agents should be co-located with their applications, not exposed as network services. External access, when required, should flow through reverse proxies with proper authentication rather than direct container exposure.

Session Authentication Security

WAIaaS implements 3-layer authentication that works seamlessly with non-root execution:

# masterAuth — system administration (requires strong password)
curl -X POST http://127.0.0.1:3100/v1/wallets \
  -H "Content-Type: application/json" \
  -H "X-Master-Password: your-secure-password" \
  -d '{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'

# sessionAuth — AI agent operations (time-limited JWT)
curl http://127.0.0.1:3100/v1/wallet/balance \
  -H "Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."
Enter fullscreen mode Exit fullscreen mode

Session tokens provide time-limited access with configurable TTL, maxRenewals, and absoluteLifetime parameters, ensuring compromised tokens have limited blast radius.

Monitoring and Intrusion Detection

Non-root containers enable better security monitoring because privilege escalation attempts become immediately visible. WAIaaS provides health check endpoints and structured logging that integrate with monitoring systems:

# Container health monitoring
docker compose logs -f daemon

# Check daemon status
curl -f http://127.0.0.1:3100/health
Enter fullscreen mode Exit fullscreen mode

The health check endpoint returns detailed status information that can trigger alerts if wallet operations become unavailable or if the daemon detects security policy violations.

Quick Start: Secure Self-Hosted Deployment

  1. Clone and configure: git clone https://github.com/minhoyoo-iotrust/WAIaaS.git && cd WAIaaS

  2. Deploy with auto-provision: docker compose up -d (automatically runs as UID 1001)

  3. Retrieve secure credentials: docker exec waiaas-daemon cat /data/recovery.key

  4. Create wallet and session: Use the CLI to set up AI agent access with proper permissions

  5. Verify security: Check that containers run as non-root with docker exec waiaas-daemon id

What's Next

Self-hosted AI agent infrastructure requires ongoing security maintenance and monitoring. Consider implementing log aggregation, automated backup strategies, and network monitoring to maintain security posture over time.

Ready to deploy secure AI agent wallets with proper privilege separation? Check out the WAIaaS GitHub repository for complete deployment guides and security configurations, or visit waiaas.ai to explore the full security architecture.

Top comments (0)