- Never hardcode secrets in Jenkinsfiles — use the Credentials store and bind with credentials() or withCredentials([])
- Use credentials('id') in environment blocks — Jenkins automatically masks values in logs
- Keep Jenkins and all plugins updated — unpatched plugins are the #1 attack vector
- Restrict pipeline script approval in Script Security — review each individually
- Enable RBAC via Role Strategy plugin — never leave default authorization
- Never hardcode secrets — use the Credentials store; credentials are encrypted at rest and masked in output
- Bind with withCredentials([string(credentialsId: 'token', variable: 'TOKEN')]) or credentials('id') in environment blocks
- Use set +x before shell commands referencing secrets to prevent log exposure
- Keep Jenkins core and plugins updated — subscribe to Security Advisory mailing list
- Audit plugins quarterly: remove unused ones, check Security Warnings in Plugin Manager
- Enable RBAC using Role Strategy plugin — assign minimal permissions per team
- Use Folder-level permissions to scope team access to their project folders
- Use Groovy Sandbox for untrusted pipeline code — prevents dangerous Java API access
- Never mount Docker socket without understanding implications — effective root on host
- Rotate credentials on schedule — integrate with HashiCorp Vault or AWS Secrets Manager
- Never run Jenkins controller as root — use dedicated jenkins user
- Use HTTPS for Jenkins UI and API — TLS at reverse proxy