Buildkite Hardening Guide
CI/CD platform hardening for Buildkite including SAML SSO, team permissions, agent security, and pipeline controls
Overview
Buildkite is a CI/CD platform enabling organizations to run fast, secure builds on their own infrastructure. As a platform managing build pipelines and deployment workflows, Buildkite security configurations directly impact software supply chain security.
Intended Audience
- Security engineers managing CI/CD platforms
- Platform engineers configuring Buildkite
- DevOps teams managing pipelines
- GRC professionals assessing build security
How to Use This Guide
- L1 (Baseline): Essential controls for all organizations
- L2 (Hardened): Enhanced controls for security-sensitive environments
- L3 (Maximum Security): Strictest controls for regulated industries
Scope
This guide covers Buildkite security including SAML SSO, team permissions, agent security, and pipeline controls.
Table of Contents
- Authentication & SSO
- Access Controls
- Agent Security
- Monitoring & Compliance
- Compliance Quick Reference
1. Authentication & SSO
1.1 Configure SAML Single Sign-On
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 6.3, 12.5 |
| NIST 800-53 | IA-2, IA-8 |
Description
Configure SAML SSO to centralize authentication for Buildkite users.
Prerequisites
- Buildkite organization admin access
- Enterprise or Business tier
- SAML 2.0 compatible IdP
ClickOps Implementation
Step 1: Access SSO Settings
- Navigate to: Organization Settings → SSO
- Select SAML provider type
Step 2: Configure SAML
- Configure IdP settings:
- SSO URL
- Entity ID
- Certificate
- Configure attribute mapping
- Map groups to teams
Step 3: Test and Enforce
- Test SSO authentication
- Enable SSO enforcement
- Document admin fallback
Time to Complete: ~1-2 hours
Code Implementation
Code Pack: Terraform
# SAML SSO is configured via the Buildkite UI, not Terraform.
# This control requires:
# 1. Enterprise or Business tier Buildkite plan
# 2. SAML 2.0 compatible Identity Provider (Okta, Azure AD, etc.)
# 3. Configuration at: Organization Settings > SSO
#
# After SSO is configured in the UI, enforce it for all members.
# The buildkite_organization resource below ensures 2FA is active
# as a complementary authentication control.
#
# Validation: Verify SSO enforcement via the Buildkite API
# GET https://api.buildkite.com/v2/organizations/{org}/sso
1.2 Enforce Two-Factor Authentication
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 6.5 |
| NIST 800-53 | IA-2(1) |
Description
Require 2FA for all Buildkite users.
ClickOps Implementation
Step 1: Enable 2FA Requirement
- Navigate to: Organization Settings → Security
- Enable Require two-factor authentication
- All users must configure 2FA
Step 2: Configure via IdP
- Enable MFA in identity provider
- Use phishing-resistant methods for admins
- All SSO users subject to IdP MFA
Code Implementation
Code Pack: Terraform
resource "buildkite_organization" "hardened" {
enforce_2fa = var.enforce_2fa
}
2. Access Controls
2.1 Configure Team Permissions
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 5.4 |
| NIST 800-53 | AC-6 |
Description
Implement least privilege using Buildkite teams.
ClickOps Implementation
Step 1: Create Teams
- Navigate to: Organization Settings → Teams
- Create teams by function
- Define team permissions
Step 2: Assign Pipeline Access
- Assign pipelines to teams
- Configure permission levels:
- Read & Build Access
- Full Access
- Apply least privilege
Step 3: Regular Access Reviews
- Review team membership quarterly
- Update access as needed
- Remove inactive members
Code Implementation
Code Pack: Terraform
# Create teams with least-privilege defaults
resource "buildkite_team" "teams" {
for_each = var.teams
name = each.key
description = each.value.description
privacy = each.value.privacy
default_team = each.value.default_team
default_member_role = each.value.default_member_role
members_can_create_pipelines = each.value.members_can_create_pipelines
}
2.2 Configure Pipeline Permissions
Profile Level: L2 (Hardened)
| Framework | Control |
|---|---|
| CIS Controls | 5.4 |
| NIST 800-53 | AC-6 |
Description
Control access to specific pipelines.
ClickOps Implementation
Step 1: Configure Pipeline Visibility
- Set pipeline visibility per pipeline
- Restrict sensitive pipelines
- Use team-based access
Step 2: Configure Build Permissions
- Control who can trigger builds
- Restrict manual builds on production
- Audit build triggers
Code Implementation
Code Pack: Terraform
# Create pipelines with hardened defaults (L2+)
resource "buildkite_pipeline" "pipelines" {
for_each = var.profile_level >= 2 ? var.pipelines : {}
name = each.key
repository = each.value.repository
description = each.value.description
default_branch = each.value.default_branch
branch_configuration = each.value.branch_configuration
skip_intermediate_builds = each.value.skip_intermediate_builds
cancel_intermediate_builds = each.value.cancel_intermediate_builds
cluster_id = each.value.cluster_id
default_timeout_in_minutes = each.value.default_timeout_in_minutes
maximum_timeout_in_minutes = each.value.maximum_timeout_in_minutes
allow_rebuilds = each.value.allow_rebuilds
# Restrict fork builds to prevent untrusted code execution
provider_settings {
build_pull_request_forks = false
publish_commit_status = true
publish_commit_status_per_step = true
skip_builds_for_existing_commits = true
cancel_deleted_branch_builds = true
prefix_pull_request_fork_branch_names = true
}
}
# Assign team access to pipelines with explicit permission levels
resource "buildkite_pipeline_team" "access" {
for_each = var.profile_level >= 2 ? var.pipeline_team_access : {}
pipeline_id = buildkite_pipeline.pipelines[each.value.pipeline_key].id
team_id = buildkite_team.teams[each.value.team_key].id
access_level = each.value.access_level
}
2.3 Limit Admin Access
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 5.4 |
| NIST 800-53 | AC-6(1) |
Description
Minimize and protect administrator accounts.
ClickOps Implementation
Step 1: Inventory Admins
- Review organization owners/admins
- Document admin access
- Identify unnecessary privileges
Step 2: Apply Restrictions
- Limit admin to 2-3 users
- Require 2FA/SSO for admins
- Monitor admin activity
Code Implementation
Code Pack: Terraform
# Admin access is managed via the Buildkite UI, not Terraform.
# This control requires:
# 1. Limit organization owners/admins to 2-3 users
# 2. Require SSO and 2FA for all admin accounts
# 3. Review admin membership quarterly
#
# Validation: Query organization members via Buildkite GraphQL API
#
# query {
# organization(slug: "your-org") {
# members(first: 100, role: ADMIN) {
# edges {
# node {
# user {
# name
# email
# }
# }
# }
# }
# }
# }
#
# Expected: No more than 3 admin users returned
3. Agent Security
3.1 Configure Agent Tokens
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 3.11 |
| NIST 800-53 | SC-12 |
Description
Securely manage agent registration tokens.
ClickOps Implementation
Step 1: Create Scoped Tokens
- Navigate to: Agents → Agent Tokens
- Create tokens per environment
- Limit token scope
Step 2: Secure Tokens
- Store tokens securely
- Rotate tokens regularly
- Revoke unused tokens
Code Implementation
Code Pack: Terraform
# Create scoped agent tokens per environment
resource "buildkite_agent_token" "tokens" {
for_each = var.agent_tokens
description = each.value.description
}
3.2 Configure Agent Clusters
Profile Level: L2 (Hardened)
| Framework | Control |
|---|---|
| CIS Controls | 13.5 |
| NIST 800-53 | AC-17 |
Description
Isolate agents by environment or sensitivity.
ClickOps Implementation
Step 1: Create Agent Clusters
- Create separate clusters for:
- Production deployments
- Development builds
- Security-sensitive builds
- Tag agents appropriately
Step 2: Configure Pipeline Targets
- Target pipelines to specific clusters
- Restrict production access
- Audit cluster assignments
Code Implementation
Code Pack: Terraform
# Create isolated agent clusters per environment (L2+)
resource "buildkite_cluster" "clusters" {
for_each = var.profile_level >= 2 ? var.clusters : {}
name = each.key
description = each.value.description
color = each.value.color
emoji = each.value.emoji
}
# Create cluster queues for workload routing (L2+)
resource "buildkite_cluster_queue" "queues" {
for_each = var.profile_level >= 2 ? var.cluster_queues : {}
cluster_id = buildkite_cluster.clusters[each.value.cluster_key].id
key = each.value.key
description = each.value.description
}
3.3 Secure Agent Infrastructure
Profile Level: L2 (Hardened)
| Framework | Control |
|---|---|
| CIS Controls | 4.1 |
| NIST 800-53 | CM-6 |
Description
Secure agent host infrastructure.
ClickOps Implementation
Step 1: Harden Agent Hosts
- Use ephemeral agents where possible
- Minimize installed software
- Apply OS hardening
Step 2: Network Security
- Restrict agent network access
- Use private networks
- Monitor agent traffic
Code Implementation
Code Pack: Terraform
# Agent infrastructure hardening is managed outside the Buildkite provider.
# This control requires:
# 1. Use ephemeral agents (containers or auto-scaling instances)
# 2. Minimize installed software on agent hosts
# 3. Apply OS hardening (CIS benchmarks for the host OS)
# 4. Restrict agent network access to required endpoints only
# 5. Use private networks for agent-to-service communication
# 6. Monitor agent traffic for anomalies
#
# Recommended infrastructure patterns:
# - AWS: buildkite/elastic-ci-stack-for-aws (CloudFormation/Terraform)
# - GCP: buildkite/elastic-ci-stack-for-gcp
# - Kubernetes: buildkite/agent-stack-k8s
#
# Agent configuration flags for hardening:
# --no-plugins Disable third-party plugins
# --no-local-hooks Disable repository-level hooks
# --no-command-eval Disable arbitrary command evaluation
# --allowed-repositories Restrict which repos agents can checkout
#
# Example agent startup with hardened flags (L3):
# buildkite-agent start \
# --no-plugins \
# --no-local-hooks \
# --no-command-eval \
# --allowed-repositories "git@github.com:your-org/*"
4. Monitoring & Compliance
4.1 Configure Audit Logging
Profile Level: L1 (Baseline)
| Framework | Control |
|---|---|
| CIS Controls | 8.2 |
| NIST 800-53 | AU-2 |
Description
Enable and monitor audit logs.
ClickOps Implementation
Step 1: Access Audit Logs
- Navigate to: Organization Settings → Audit Log
- Review logged events
- Configure retention
Step 2: Monitor Events
- User authentication
- Pipeline changes
- Permission modifications
- Agent token usage
Code Implementation
Code Pack: Terraform
# Restrict API access to known IP addresses (L3)
# This limits which networks can query audit logs and other API endpoints
resource "buildkite_organization" "api_restrictions" {
count = var.profile_level >= 3 && length(var.allowed_api_ip_addresses) > 0 ? 1 : 0
allowed_api_ip_addresses = var.allowed_api_ip_addresses
}
# Audit log monitoring is performed via the Buildkite API.
# Key events to monitor:
# - User authentication (login/logout)
# - Pipeline changes (create/update/delete)
# - Permission modifications (team/member changes)
# - Agent token usage (create/revoke)
# - Organization setting changes
#
# Query audit events via GraphQL:
#
# query {
# organization(slug: "your-org") {
# auditEvents(first: 50) {
# edges {
# node {
# type
# occurredAt
# actor {
# name
# }
# subject {
# name
# type
# }
# }
# }
# }
# }
# }
5. Compliance Quick Reference
SOC 2 Trust Services Criteria Mapping
| Control ID | Buildkite Control | Guide Section |
|---|---|---|
| CC6.1 | SSO/2FA | 1.1 |
| CC6.2 | Team permissions | 2.1 |
| CC6.7 | Agent tokens | 3.1 |
| CC7.2 | Audit logging | 4.1 |
NIST 800-53 Rev 5 Mapping
| Control | Buildkite Control | Guide Section |
|---|---|---|
| IA-2 | SSO | 1.1 |
| IA-2(1) | 2FA | 1.2 |
| AC-6 | Team permissions | 2.1 |
| SC-12 | Agent tokens | 3.1 |
| AU-2 | Audit logging | 4.1 |
Appendix A: References
Official Buildkite Documentation:
- Buildkite Trust Center
- Buildkite Security
- Buildkite Documentation
- Security Controls Best Practices
- SSO Configuration
- Team Permissions
- Securing Your Agent
API Documentation:
Compliance Frameworks:
- SOC 2 Type II (annual audit covering Pipelines, Package Registries, and Test Engine) — via Buildkite Trust Center
Security Incidents:
- No major public security breaches identified. Buildkite maintains annual third-party penetration testing and a private HackerOne bug bounty program.
Changelog
| Date | Version | Maturity | Changes | Author |
|---|---|---|---|---|
| 2025-02-05 | 0.1.0 | draft | Initial guide with SSO, teams, and agent security | Claude Code (Opus 4.5) |
Contributing
Found an issue or want to improve this guide?
- Report outdated information: Open an issue with tag
content-outdated - Propose new controls: Open an issue with tag
new-control - Submit improvements: See Contributing Guide