Drone security is driven by runner isolation, repository trust policy, secure secret injection, and protecting the server/runner communication channel. As a container-native CI/CD platform, special attention must be paid to container escape prevention and pipeline supply chain security.
¶ 1) Harden Server and Repository Trust Policy
# Example Drone server configuration
DRONE_SERVER_HOST=drone.example.com
DRONE_SERVER_PROTO=https
DRONE_RPC_SECRET=<generate-with-openssl-rand-base64-32>
DRONE_GITHUB_CLIENT_ID=<oauth-client-id>
DRONE_GITHUB_CLIENT_SECRET=<oauth-client-secret>
DRONE_USER_CREATE=false # Disable open user registration
DRONE_CRON_DISABLED=false # Enable scheduled pipelines
- Generate strong RPC secret: Use
openssl rand -base64 32 for RPC_SECRET
- Disable open registration: Set
DRONE_USER_CREATE=false
- OAuth integration: Use GitHub/GitLab/Gitea OAuth for authentication
- Admin whitelist: Restrict admin access to specific users
- Restrict repository activation: Limit who can enable repositories in Drone
- Disable auto-trust: Never auto-trust forks or untrusted repositories
- Org-level policies: Enforce organization-level security policies
- Protected branches: Require status checks for protected branches
# Example .drone.yml with trusted settings
kind: pipeline
type: docker
name: default
platform:
os: linux
arch: amd64
# Restrict privileged mode
privileged: false
steps:
- name: build
image: node:20
commands:
- npm ci
- npm test
- Block privileged mode: Default to
privileged: false
- Require approvals: Gate production deployments with manual approvals
- Branch restrictions: Limit pipeline execution on protected branches
- Fork handling: Disable PR builds from forks or run in restricted mode
¶ 2) Isolate Runners and Execution Environments
# Docker runner configuration
DRONE_RUNNER_NAME=runner-1
DRONE_RUNNER_CAPACITY=2
DRONE_RUNNER_ENV_FILE=/etc/drone/enabled-plugins.json
DRONE_DOCKER_NETWORK_DISABLED=false # Disable default network access
DRONE_DOCKER_PRIVILEGED=false # Disable privileged containers
- Dedicated runners: Use separate runners for trusted/untrusted builds
- Capacity limits: Limit concurrent builds per runner
- Network isolation: Disable default Docker network access
- No privileged mode: Block privileged container execution
- Ephemeral containers: Run builds in disposable containers
- Resource limits: Apply CPU/memory limits via Docker/Kubernetes
- Read-only filesystems: Use read-only root where possible
- Drop capabilities: Remove unnecessary Linux capabilities
# Kubernetes runner with security context
kind: pipeline
type: kubernetes
name: default
platform:
os: linux
arch: amd64
workspace:
path: /drone/src
steps:
- name: build
image: node:20
commands:
- npm ci
environment:
NODE_ENV: production
- No host mounts: Avoid mounting host filesystems into containers
- Protect Docker socket: Never expose Docker socket to builds
- Runner hardening: Apply security baselines to runner hosts
- Network segmentation: Isolate runner networks from production
¶ 3) Secure Secrets and Plugin Usage
# Store secrets securely in Drone
drone secret add --repository my-org/my-repo \
--name api-key \
--value <secret-value> \
--type global
# Scope secrets to specific branches
drone secret add --repository my-org/my-repo \
--name deploy-key \
--value <secret-value> \
--event promote
- Use Drone secrets backend: Store secrets in Drone, not in YAML
- Scope secrets tightly: Limit secrets to specific branches/events
- Mask secrets: Enable secret masking in build logs
- Rotate regularly: Implement secret rotation schedules
# Pin plugin images by digest for supply chain control
steps:
- name: deploy
image: plugins/kubernetes@sha256:<digest>
settings:
namespace: production
deploy:
- deployment.yaml
- Pin plugin versions: Use specific versions or digests
- Trusted plugins only: Block untrusted community plugins
- Internal registry: Mirror plugins to internal registry
- Audit plugins: Review plugin code before use
- OAuth tokens: Use OAuth tokens instead of passwords
- Scoped tokens: Limit token permissions to minimum required
- Token rotation: Rotate SCM tokens regularly
- Webhook secrets: Validate webhook signatures
# Secure .drone.yml practices
kind: pipeline
type: docker
name: default
# Use trusted base images
platform:
os: linux
arch: amd664
steps:
- name: security-scan
image: aquasec/trivy:latest
commands:
- trivy fs .
- trivy image my-app:latest
- Trusted base images: Use official or verified images
- Image scanning: Scan images for vulnerabilities
- Dependency scanning: Scan dependencies for CVEs
- Signed commits: Require signed commits for pipeline changes
- Reproducible builds: Enable reproducible build processes
- Artifact signing: Sign build artifacts
- SBOM generation: Generate Software Bill of Materials
- Audit trail: Log all pipeline executions
¶ 5) Monitoring and Incident Response
- Centralized logging: Forward logs to SIEM or log management
- Structured logs: Use JSON format for analysis
- Log retention: Define retention policies
- Audit logging: Log all administrative actions
# Check Drone server status
docker ps --format '{{.Names}}' | grep -E 'drone|runner'
# Review recent builds
drone build ls my-org/my-repo --limit 20
# Check for failed authentications
docker logs drone-server 2>&1 | grep -i "auth\|denied\|failed" | tail -20
# Review active runners
docker logs drone-runner-docker 2>&1 | grep -i "running\|complete" | tail -10
- Alert on auth failures: Detect brute force attempts
- Monitor build anomalies: Watch for unusual build patterns
- Track secret access: Audit when secrets are used
- Runner health: Monitor runner connectivity
- Document procedures: Create runbooks for security incidents
- Isolation procedures: Know how to isolate compromised runners
- Token revocation: Have procedures for emergency token revocation
- Backup and recovery: Maintain secure backups of server configuration
¶ Verification Commands
# Check Drone CLI version
drone --version 2>/dev/null
# Review running containers
docker ps --format '{{.Names}}\t{{.Status}}' | grep -E 'drone|runner'
# Check server configuration
grep -R "DRONE_\|SECRET\|RPC\|AUTH" /etc/drone /opt/drone 2>/dev/null | head -30
# Verify listening ports
sudo ss -tulpn | grep -E ':80|:443|:9000'
# Review recent builds
drone build ls --limit 20 2>/dev/null || echo "Drone CLI not configured"
# Check runner status
curl -s http://localhost:3000/healthz 2>/dev/null || echo "Runner health check failed"
# Review secrets (admin only)
drone secret ls my-org/my-repo 2>/dev/null | head -20
# Check for privileged containers
docker inspect $(docker ps -q --filter name=drone) 2>/dev/null | grep -i "privileged"
- Drone Documentation: https://docs.drone.io/
- Drone Server Security: https://docs.drone.io/server/security/
- Drone Runner Security: https://docs.drone.io/runner/security/
- Drone Source Repository: https://github.com/harness/drone
- Container Security Best Practices: https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html