v0.1.0-draft AI Drafted

Buildkite Hardening Guide

DevOps Last updated: 2025-02-05

CI/CD platform hardening for Buildkite including SAML SSO, team permissions, agent security, and pipeline controls

Code Packs: Terraform

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

  1. Authentication & SSO
  2. Access Controls
  3. Agent Security
  4. Monitoring & Compliance
  5. 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

  1. Navigate to: Organization SettingsSSO
  2. Select SAML provider type

Step 2: Configure SAML

  1. Configure IdP settings:
    • SSO URL
    • Entity ID
    • Certificate
  2. Configure attribute mapping
  3. Map groups to teams

Step 3: Test and Enforce

  1. Test SSO authentication
  2. Enable SSO enforcement
  3. Document admin fallback

Time to Complete: ~1-2 hours

Code Implementation

Code Pack: Terraform
hth-buildkite-1.01-configure-saml-sso.tf View source on GitHub ↗
# 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

  1. Navigate to: Organization SettingsSecurity
  2. Enable Require two-factor authentication
  3. All users must configure 2FA

Step 2: Configure via IdP

  1. Enable MFA in identity provider
  2. Use phishing-resistant methods for admins
  3. All SSO users subject to IdP MFA

Code Implementation

Code Pack: Terraform
hth-buildkite-1.02-enforce-two-factor-authentication.tf View source on GitHub ↗
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

  1. Navigate to: Organization SettingsTeams
  2. Create teams by function
  3. Define team permissions

Step 2: Assign Pipeline Access

  1. Assign pipelines to teams
  2. Configure permission levels:
    • Read & Build Access
    • Full Access
  3. Apply least privilege

Step 3: Regular Access Reviews

  1. Review team membership quarterly
  2. Update access as needed
  3. Remove inactive members

Code Implementation

Code Pack: Terraform
hth-buildkite-2.01-configure-team-permissions.tf View source on GitHub ↗
# 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

  1. Set pipeline visibility per pipeline
  2. Restrict sensitive pipelines
  3. Use team-based access

Step 2: Configure Build Permissions

  1. Control who can trigger builds
  2. Restrict manual builds on production
  3. Audit build triggers

Code Implementation

Code Pack: Terraform
hth-buildkite-2.02-configure-pipeline-permissions.tf View source on GitHub ↗
# 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

  1. Review organization owners/admins
  2. Document admin access
  3. Identify unnecessary privileges

Step 2: Apply Restrictions

  1. Limit admin to 2-3 users
  2. Require 2FA/SSO for admins
  3. Monitor admin activity

Code Implementation

Code Pack: Terraform
hth-buildkite-2.03-limit-admin-access.tf View source on GitHub ↗
# 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

  1. Navigate to: AgentsAgent Tokens
  2. Create tokens per environment
  3. Limit token scope

Step 2: Secure Tokens

  1. Store tokens securely
  2. Rotate tokens regularly
  3. Revoke unused tokens

Code Implementation

Code Pack: Terraform
hth-buildkite-3.01-configure-agent-tokens.tf View source on GitHub ↗
# 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

  1. Create separate clusters for:
    • Production deployments
    • Development builds
    • Security-sensitive builds
  2. Tag agents appropriately

Step 2: Configure Pipeline Targets

  1. Target pipelines to specific clusters
  2. Restrict production access
  3. Audit cluster assignments

Code Implementation

Code Pack: Terraform
hth-buildkite-3.02-configure-agent-clusters.tf View source on GitHub ↗
# 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

  1. Use ephemeral agents where possible
  2. Minimize installed software
  3. Apply OS hardening

Step 2: Network Security

  1. Restrict agent network access
  2. Use private networks
  3. Monitor agent traffic

Code Implementation

Code Pack: Terraform
hth-buildkite-3.03-secure-agent-infrastructure.tf View source on GitHub ↗
# 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

  1. Navigate to: Organization SettingsAudit Log
  2. Review logged events
  3. Configure retention

Step 2: Monitor Events

  1. User authentication
  2. Pipeline changes
  3. Permission modifications
  4. Agent token usage

Code Implementation

Code Pack: Terraform
hth-buildkite-4.01-configure-audit-logging.tf View source on GitHub ↗
# 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:

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?