파이프라인 보안
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
시크릿 관리는 개발자가 엄격한 접근 제어가 있는 안전한 환경에 민감한 데이터를 안전하게 저장하기 위해 사용하는 시스템입니다. 가장 민감하고 가장 엄격한 정책 하에 있는 시크릿은 시크릿 관리자에 저장해야 합니다. 특정 외부 시크릿 관리 프로바이더에 대한 GitLab 네이티브 통합을 사용하여 필요할 때 CI/CD 파이프라인에서 해당 시크릿을 검색할 수 있습니다.
시크릿 관리#
시크릿 관리는 개발자가 엄격한 접근 제어가 있는 안전한 환경에 민감한 데이터를 안전하게 저장하기 위해 사용하는 시스템입니다. 시크릿은 기밀로 유지되어야 하는 민감한 자격 증명입니다. 시크릿의 예시:
- 비밀번호
- SSH 키
- 액세스 토큰
- 노출이 조직에 해를 끼칠 수 있는 기타 모든 유형의 자격 증명
시크릿 저장#
시크릿 관리 프로바이더#
가장 민감하고 가장 엄격한 정책 하에 있는 시크릿은 시크릿 관리자에 저장해야 합니다. 시크릿 관리자 솔루션을 사용할 때 시크릿은 GitLab 인스턴스 외부에 저장됩니다. 이 공간에는 HashiCorp의 Vault, Azure Key Vault, Google Cloud Secret Manager를 포함한 여러 프로바이더가 있습니다.
특정 외부 시크릿 관리 프로바이더에 대한 GitLab 네이티브 통합을 사용하여 필요할 때 CI/CD 파이프라인에서 해당 시크릿을 검색할 수 있습니다.
CI/CD 변수#
CI/CD 변수는 CI/CD 파이프라인에서 데이터를 저장하고 재사용하는 편리한 방법이지만, 변수는 시크릿 관리 프로바이더보다 덜 안전합니다. 변수 값:
- GitLab 프로젝트, 그룹 또는 인스턴스 설정에 저장됩니다. 설정에 접근하는 사용자는 숨겨지지 않은 변수 값에 접근할 수 있습니다.
- 재정의될 수 있어 어떤 값이 사용되었는지 파악하기 어렵습니다.
- 실수로 인한 파이프라인 잘못된 구성으로 노출될 수 있습니다.
변수에 저장하기에 적합한 정보는 악용 위험 없이 노출될 수 있는 데이터(비민감)여야 합니다.
민감한 데이터는 시크릿 관리 솔루션에 저장해야 합니다. 시크릿 관리 솔루션이 없고 CI/CD 변수에 민감한 데이터를 저장하려는 경우 항상 다음을 수행하세요:
CI/CD 파이프라인에 매개변수 전달#
CI/CD 파이프라인에 매개변수를 전달하려면 파이프라인 변수 대신 CI/CD inputs을 사용합니다.
Inputs는 다음을 제공합니다:
- 파이프라인 생성 시 타입 안전 유효성 검사
- 명시적 매개변수 계약
- 보안을 강화하는 범위 제한 가용성
inputs를 구현할 때 파이프라인 변수는 다음과 같은 이유로 보안 취약성을 유발할 수 있으므로 파이프라인 변수 비활성화를 고려합니다:
- 타입 유효성 검사 부재
- 사전 정의된 변수를 재정의하여 예기치 않은 동작 유발 가능
- 민감한 시크릿과 동일한 권한 범위 공유
파이프라인 무결성#
파이프라인 무결성 보장의 핵심 보안 원칙:
- 공급망 보안: 자산은 신뢰할 수 있는 소스에서 가져와야 하며 무결성을 검증해야 합니다.
- 재현성: 파이프라인은 동일한 입력을 사용할 때 일관된 결과를 생성해야 합니다.
- 감사 가능성: 모든 파이프라인 종속성은 추적 가능하고 출처를 확인할 수 있어야 합니다.
- 버전 제어: 파이프라인 종속성의 변경은 추적 및 제어되어야 합니다.
Docker 이미지#
Docker 이미지에 대해 항상 SHA 다이제스트를 사용하여 클라이언트 측 무결성 검증을 보장합니다. 예를 들어:
- Node:
- 사용:
image: node@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef - 대신:
image: node:latest
- 사용:
- Python:
- 사용:
image: python@sha256:9876543210abcdef9876543210abcdef9876543210abcdef9876543210abcdef - 대신:
image: python:3.9
- 사용:
특정 태그가 있는 이미지의 SHA 다이제스트는 다음을 사용하여 찾을 수 있습니다:
docker pull node:18.17.1
docker images --digests node:18.17.1
이미지 무결성을 보호하는 컨테이너 레지스트리에서 가져오는 것을 선호합니다:
- 보호된 컨테이너 저장소를 사용하여 컨테이너 저장소의 컨테이너 이미지를 변경할 수 있는 사용자를 제한합니다.
- 보호된 태그를 사용하여 컨테이너 태그를 푸시하고 삭제할 수 있는 사람을 제어합니다.
가능하면 컨테이너 참조에서 변수 사용을 피합니다. 변수는 악의적인 이미지를 가리키도록 수정될 수 있습니다. 예를 들어:
- 선호:
image: my-registry.example.com/node:18.17.1
- 대신:
image: ${CUSTOM_REGISTRY}/node:latestimage: node:${VERSION}
패키지 종속성#
작업에서 패키지 종속성을 잠가야 합니다. 잠금 파일에 정의된 정확한 버전을 사용합니다:
- npm:
- 사용:
npm ci - 대신:
npm install
- 사용:
- yarn:
- 사용:
yarn install --frozen-lockfile - 대신:
yarn install
- 사용:
- Python:
- 사용:
pip install -r requirements.txt --require-hashespip install -r requirements.lock
- 대신:
pip install -r requirements.txt
- 사용:
- Go:
go.sum에서 정확한 버전 사용:go mod verifygo mod download
- 대신:
go get ./...
예를 들어, CI/CD 작업에서:
javascript-job:
script:
- npm ci
셸 명령 및 스크립트#
작업에서 도구를 설치할 때 항상 정확한 버전을 지정하고 검증합니다. 예를 들어, Terraform 작업에서:
terraform_job:
script:
# Download specific version
- |
wget https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip
# IMPORTANT: Always verify checksums
echo "c0ed7bc32ee52ae255af9982c8c88a7a4c610485cf1d55feeb037eab75fa082c terraform_1.5.7_linux_amd64.zip" | sha256sum -c
unzip terraform_1.5.7_linux_amd64.zip
mv terraform /usr/local/bin/
# Use the installed version
- terraform init
- terraform plan
버전 관리 도구#
가능한 경우 버전 관리자를 사용합니다:
node_build:
script:
# Use nvm to install and use a specific Node version
- |
nvm install 16.15.1
nvm use 16.15.1
- node --version # Verify version
- npm ci
- npm run build
포함된 구성#
파이프라인에 구성이나 CI/CD 컴포넌트를 추가하기 위해 include 키워드를 사용할 때 가능하면 특정 ref를 사용합니다. 예를 들어:
include:
- project: 'my-group/my-project'
ref: 8b0c8b318857c8211c15c6643b0894345a238c4e # Pin to a specific commit
file: '/templates/build.yml'
- project: 'my-group/security'
ref: v2.1.0 # Pin to a protected tag
file: '/templates/scan.yml'
- component: 'my-group/security-scans' # Pin to a specific version
version: '1.2.3'
버전이 없는 포함을 피합니다:
include:
- project: 'my-group/my-project' # Unsafe
file: '/templates/build.yml'
- component: 'my-group/security-scans' # Unsafe
- remote: 'https://example.com/security-scan.yml' # Unsafe
원격 파일을 포함하는 대신 파일을 다운로드하여 저장소에 저장합니다. 그런 다음 로컬 복사본을 포함할 수 있습니다:
include:
- local: '/ci/security-scan.yml' # Verified and stored in the repository
관련 주제#
- CIS Docker Benchmarks
- Google Cloud: Design secure deployment pipelines
