안전한 Jenkins 자격 증명 관리를 위한 모범 사례

자격 증명 플러그인, 폴더 범위, withCredentials, RBAC, 순환 및 외부 볼트를 사용하여 Jenkins 비밀을 안전하게 저장합니다.

안전한 Jenkins 자격 증명 관리를 위한 모범 사례

Jenkins 작업은 종종 프로덕션에 가까운 비밀(클라우드 토큰, 레지스트리 비밀번호, 배포 키, 서명 인증서 및 API 자격 증명)이 필요합니다. 이러한 비밀이 Jenkinsfile, 콘솔 로그 또는 작업 매개변수에 포함되면 CI/CD 시스템이 손상으로 이어지는 직접적인 경로가 됩니다.

자격 증명 플러그인을 사용하고, 자격 증명의 범위를 좁게 유지하며, 필요한 단계에만 주입하세요.

기본: Jenkins 자격 증명 플러그인

자격 증명 플러그인은 Jenkins가 민감한 데이터를 저장하는 데 사용하는 표준 메커니즘입니다. 이 플러그인은 자격 증명을 위한 중앙 집중식 암호화 저장소를 제공하여 비밀이 빌드 로그, 소스 제어 또는 구성 파일에 노출되지 않도록 보장합니다.

Jenkins가 자격 증명을 저장할 때 JENKINS_HOME/secrets 아래의 파일을 포함하여 Jenkins 컨트롤러의 키 자료를 사용하여 암호화합니다. 컨트롤러 파일 시스템 및 Jenkins 구성에 대한 광범위한 액세스 권한이 있는 사람은 비밀을 복구할 수 있으므로 파일 시스템 및 관리자 액세스를 엄격하게 제어해야 합니다.

주요 자격 증명 유형

사용 가능한 자격 증명 유형을 이해하는 것이 안전한 구현을 위한 첫 번째 단계입니다. 저장 중인 비밀에 가장 정확하게 매핑되는 유형을 선택하세요.

  1. 비밀 텍스트: API 토큰, 액세스 키, OAuth 토큰 또는 웹후크 비밀과 같은 일반적인 짧은 텍스트 값에 사용됩니다.
  2. 사용자 이름 및 비밀번호: Maven 저장소, 개인 레지스트리(Docker Hub, Artifactory) 또는 내부 애플리케이션과 같은 서비스에 대한 인증에 사용되는 표준 쌍입니다.
  3. 개인 키가 있는 SSH 사용자 이름: 원격 에이전트에 액세스하거나, 개인 Git 저장소를 복제하거나, 원격 인프라에서 명령을 실행하는 데 필수적입니다. 개인 키는 직접 입력하거나, 경로로 제공하거나, Jenkins 컨트롤러에서 관리할 수 있습니다.
  4. 비밀 파일: 키 저장소, 인증서(.pem, .crt) 또는 비밀이 포함된 구성 파일과 같은 전체 파일을 업로드하는 데 사용됩니다.

팁: 항상 가능한 가장 세분화된 자격 증명 유형을 사용하세요. 예를 들어 API 키만 필요한 경우 사용자 이름 및 비밀번호 필드에 맞추려고 시도하지 말고 비밀 텍스트를 사용하세요.

최소 권한 원칙: 자격 증명 범위 지정

자격 증명 범위는 Jenkins 환경 내에서 액세스할 수 있는 위치를 결정합니다. 작업에 필요한 액세스 권한만 부여하는 최소 권한 원칙을 적용하는 것이 중요합니다.

1. 시스템 범위

시스템 범위 자격 증명(Jenkins 관리 > 자격 증명 관리 > Jenkins에 저장됨)은 Jenkins 인스턴스의 모든 작업, 폴더 및 파이프라인에서 전역적으로 사용할 수 있습니다.

  • 사용: 전체 Jenkins 운영에 필요한 비밀(예: 전역 구성 플러그인에서 사용하는 자격 증명 또는 모든 에이전트 연결에 필요한 비밀)에만 시스템 범위를 사용하세요.
  • 경고: 시스템 범위 사용을 최소화하세요. 손상된 작업은 잠재적으로 모든 전역적으로 사용 가능한 비밀에 액세스할 수 있습니다.

2. 폴더 범위

폴더 범위 자격 증명은 특정 폴더(폴더 플러그인 또는 조직 폴더를 사용하여 생성) 내에 정의됩니다. 이러한 비밀은 해당 폴더 및 하위 폴더 내에 있는 작업만 보고 사용할 수 있습니다.

  • 권장 사항: 항상 폴더 범위를 선호하세요. 이렇게 하면 액세스가 분할되어 하나의 프로젝트가 손상되더라도 피해 범위가 제한됩니다.

선언적 파이프라인에 안전하게 주입

파이프라인 스크립트에 자격 증명을 하드코딩하지 마세요. 환경 변수는 Jenkins가 좁은 블록에 대해 주입하고 알려진 비밀 값을 로그에서 마스킹하는 경우에만 허용됩니다.

선언적 파이프라인에서 자격 증명에 액세스하는 안전한 방법은 내장된 withCredentials 단계를 사용하는 것입니다. 이 단계는 지정된 자격 증명을 블록 실행 중에만 사용할 수 있는 범위가 지정된 환경 변수에 로드합니다.

예제 1: 비밀 텍스트(API 토큰) 주입

이 예제는 비밀 텍스트 자격 증명(MY_API_TOKEN)을 안전하게 검색하고 해당 값을 내부 변수 SECRET_TOKEN에 할당합니다. withCredentials 블록이 완료되면 SECRET_TOKEN이 환경에서 자동으로 제거됩니다.

pipeline {
    agent any
    stages {
        stage('API를 통한 배포') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'MY_API_TOKEN', variable: 'SECRET_TOKEN')]) {
                        sh "echo '외부 API 호출 중...'"
                        sh '''
                            curl -X POST \
                              -H "Authorization: Bearer $SECRET_TOKEN" \
                              https://api.mycorp.com/deploy
                        '''
                    }
                }
            }
        }
    }
}

예제 2: 사용자 이름 및 비밀번호 주입

사용자 이름 및 비밀번호 자격 증명을 사용하는 경우 withCredentials 단계는 비밀을 사용자 이름용 변수와 비밀번호용 변수(일반적으로 _USR_PSW 접미사 또는 사용자 지정 이름)로 분할합니다.

pipeline {
    agent any
    stages {
        stage('레지스트리에 로그인') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                    sh '''
                        printf '%s' "$DOCKER_PASS" | docker login \
                          --username "$DOCKER_USER" \
                          --password-stdin my.registry.com
                    '''
                }
            }
        }
    }
}

보안 경고: 로그 억제

Jenkins는 빌드 로그에서 알려진 자격 증명 값을 마스킹하려고 시도하지만 마스킹은 신중한 스크립트를 대체할 수 없습니다. 비밀을 인쇄하거나, 명령줄에 비밀번호를 전달하거나, 비밀 사용 주변에서 셸 추적(set -x)을 실행하지 마세요.

고급 보안 통합

보안 수준이 높은 환경에서는 로컬 Jenkins 마스터 키에만 의존하는 것으로는 충분하지 않은 경우가 많습니다. 외부 비밀 관리 시스템과 통합하면 관심사 분리, 중앙 집중식 감사 및 향상된 암호화 기능을 제공합니다.

외부 자격 증명 저장소

널리 사용되는 통합은 다음과 같습니다.

  • HashiCorp Vault: Vault 플러그인을 사용하여 Jenkins는 런타임에 Vault에서 동적으로 비밀을 요청할 수 있습니다. 즉, 비밀이 Jenkins 컨트롤러에 영구적으로 저장되지 않고 실행 단계 중에만 메모리에 일시적으로 저장됩니다.
  • AWS Secrets Manager/Azure Key Vault: 클라우드 네이티브 플러그인을 사용하면 파이프라인이 IAM 역할 또는 서비스 주체를 사용하여 이러한 서비스에서 직접 비밀을 검색하여 정적 자격 증명 노출을 최소화할 수 있습니다.

외부 저장소를 사용하면 다음과 같은 보안 모범 사례를 따를 수 있습니다.

  1. 저장소 분리: 비밀 인프라가 CI/CD 서버에서 분리됩니다.
  2. 동적 액세스: 수동 Jenkins 구성 업데이트 없이 비밀을 자주 순환할 수 있습니다.
  3. 향상된 감사: 모든 비밀 액세스 시도가 외부 볼트 시스템 내에 기록됩니다.

역할 기반 액세스 제어(RBAC)

RBAC 플러그인(예: 역할 기반 권한 부여 전략)을 구현하면 관리자가 작업을 실행할 수 있는 사람뿐만 아니라 특정 자격 증명을 구성하고 수 있는 사람도 제어할 수 있습니다.

  • 신뢰할 수 있는 사용자만 파이프라인에서 자격 증명을 바인딩할 수 있도록 작업 구성 권한을 제한하세요.
  • 시스템 수준 자격 증명을 수정하거나 생성하는 기능을 소규모 보안 또는 플랫폼 관리자 그룹으로 제한하세요.

자격 증명 관리 모범 사례

관행 설명 보안 이점
폴더 범위 사용 자격 증명 액세스를 필요한 특정 작업/폴더로 제한합니다. 노출 및 피해 범위를 제한합니다.
하드코딩 방지 Jenkinsfile, 빌드 스크립트 또는 소스 제어에 비밀을 절대 배치하지 마세요. 소스 코드 취약점을 제거합니다.
withCredentials 사용 공식 Jenkins API를 사용하여 파이프라인 단계에 비밀을 안전하게 주입합니다. 자동 로그 편집 및 환경 정리를 보장합니다.
외부 볼트 통합 엔터프라이즈 배포에는 Vault, AWS Secrets Manager 또는 Azure Key Vault를 사용하세요. 저장소를 분리하고 동적 순환을 가능하게 합니다.
RBAC 적용 권한 부여 플러그인을 사용하여 자격 증명을 구성, 보기 및 사용할 수 있는 사람을 제한합니다. 사용자 간 최소 권한 원칙을 적용합니다.
정기적인 순환 API 키와 비밀번호를 정기적으로 순환합니다(이상적으로는 외부 볼트를 통해 자동화). 손상된 비밀이 악용될 수 있는 시간을 최소화합니다.
컨트롤러 보안 master.key를 보호하기 위해 Jenkins 컨트롤러에 엄격한 파일 시스템 권한을 적용합니다. 핵심 암호화 메커니즘을 보호합니다.

Jenkins 자격 증명을 프로덕션 비밀로 취급하세요. 범위를 좁게 지정하고, 짧게 바인딩하고, 정기적으로 순환하며, 컨트롤러 액세스를 해당 비밀을 복구할 수 있는 사람으로 제한하세요.