InfoGrab Docs

GitLab CI/CD에서 HashiCorp Vault 시크릿 사용

요약

GitLab CI/CD에서 HashiCorp Vault 시크릿을 사용할 수 있습니다. CI/CD 잡에서 Vault 시크릿을 사용하려면 먼저 Vault 서버를 구성해야 합니다. 다음 예에서 vault.example.com을 Vault 서버의 URL로, gitlab.example.com을 GitLab 인스턴스의 URL로 교체합니다.

GitLab CI/CD에서 HashiCorp Vault 시크릿을 사용할 수 있습니다. ID 토큰을 사용하여 HashiCorp Vault로 인증합니다.

CI/CD 잡에서 Vault 시크릿을 사용하려면 먼저 Vault 서버를 구성해야 합니다. HashiCorp Vault로 시크릿 인증 및 읽기 튜토리얼에 Vault 구성 및 ID 토큰을 사용한 인증에 대한 자세한 내용이 있습니다.

다음 예에서 vault.example.com을 Vault 서버의 URL로, gitlab.example.com을 GitLab 인스턴스의 URL로 교체합니다.

Vault 서버 구성#

Vault 서버를 구성하려면:

  1. 다음 명령을 실행하여 인증 방법을 활성화합니다. 이 명령은 Vault 서버에 GitLab 인스턴스의 OIDC 디스커버리 URL을 제공하여 Vault가 공개 서명 키를 가져오고 인증 시 JSON Web Token(JWT)을 검증할 수 있게 합니다:

    $ vault auth enable jwt
    
    $ vault write auth/jwt/config \
      oidc_discovery_url="https://gitlab.example.com" \
      bound_issuer="gitlab.example.com"
    
  2. 특정 경로 및 작업에 대한 액세스를 허용하거나 거부하도록 Vault 서버에 정책을 구성합니다. 이 예에서는 프로덕션 환경에 필요한 시크릿 세트에 대한 읽기 전용 액세스를 부여합니다:

    vault policy write myproject-production - <# Read-only permission on 'ops/data/production/*' path
    
    path "ops/data/production/*" {
      capabilities = [ "read" ]
    }
    EOF
    
  3. Vault 서버에 역할을 구성하여 역할을 프로젝트나 네임스페이스로 제한합니다.

  4. 다음 CI/CD 변수를 만들어 Vault 서버에 대한 세부 정보를 제공합니다:

    • VAULT_SERVER_URL: https://vault.example.com:8200과 같은 Vault 서버의 URL.
    • VAULT_AUTH_ROLE: 선택 사항. 인증 시도 시 사용할 역할. 역할이 지정되지 않으면 Vault는 인증 방법이 구성될 때 지정된 기본 역할을 사용합니다.
    • VAULT_AUTH_PATH: 선택 사항. 인증 방법이 마운트된 경로, 기본값은 jwt.
    • VAULT_NAMESPACE: 선택 사항. 시크릿 읽기 및 인증에 사용할 Vault Enterprise 네임스페이스. 다음 경우:
      • Vault의 경우 네임스페이스가 지정되지 않으면 root("/") 네임스페이스가 사용됩니다.
      • Vault 오픈 소스의 경우 설정이 무시됩니다.
      • HashiCorp Cloud Platform (HCP) Vault의 경우 네임스페이스가 필요합니다. HCP Vault는 기본적으로 admin 네임스페이스를 루트 네임스페이스로 사용합니다. 예를 들어 VAULT_NAMESPACE=admin.

서버 역할 구성#

CI/CD 잡이 인증을 시도할 때 역할을 지정합니다. 역할을 사용하여 다른 정책을 그룹화할 수 있습니다. 인증이 성공하면 이러한 정책이 결과 Vault 토큰에 첨부됩니다.

Bound claims는 JWT 클레임과 일치하는 미리 정의된 값입니다. 경계 클레임을 사용하면 특정 GitLab 사용자, 특정 프로젝트 또는 특정 Git 참조에 대해 실행되는 잡에 대한 액세스를 제한할 수 있습니다. 필요한 만큼 경계 클레임을 가질 수 있지만 인증이 성공하려면 모두 일치해야 합니다.

사용자 역할보호된 브랜치와 같은 GitLab 기능과 경계 클레임을 결합하여 특정 사용 사례에 맞게 이러한 규칙을 조정할 수 있습니다. 이 예에서는 프로덕션 릴리스에 사용되는 패턴과 일치하는 이름의 보호된 태그에 대해 실행되는 잡에 대해서만 인증이 허용됩니다:

$ vault write auth/jwt/role/myproject-production - <{
  "role_type": "jwt",
  "policies": ["myproject-production"],
  "token_explicit_max_ttl": 60,
  "user_claim": "user_email",
  "bound_audiences": "https://vault.example.com",
  "bound_claims_type": "glob",
  "bound_claims": {
    "project_id": "42",
    "ref_protected": "true",
    "ref_type": "tag",
    "ref": "auto-deploy-*"
  }
}
EOF
Warning

project_id 또는 namespace_id와 같은 제공된 클레임 중 하나를 사용하여 항상 역할을 프로젝트나 네임스페이스로 제한하세요. 이러한 제한 없이 이 GitLab 인스턴스에서 생성된 모든 JWT가 이 역할을 사용하여 인증할 수 있습니다.

ID 토큰 JWT 클레임의 전체 목록은 GitLab CI/CD에서 HashiCorp Vault 시크릿 사용 튜토리얼을 검토하세요.

시간 제한(TTL), IP 주소 범위, 사용 횟수 등 결과 Vault 토큰의 일부 속성을 지정할 수도 있습니다. 옵션의 전체 목록은 JSON Web Token 방법의 역할 생성에 관한 Vault 문서에서 확인할 수 있습니다.

CI/CD 잡에서 Vault 시크릿 사용#

잡에 하나 이상의 ID 토큰이 정의된 경우 secrets 키워드가 자동으로 해당 토큰을 사용하여 Vault로 인증합니다.

Vault 서버를 구성한 후 secrets:vault 키워드를 사용하여 Vault에 저장된 시크릿을 사용합니다:

job_using_vault:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    DATABASE_PASSWORD:
      vault: production/db/password@ops
      token: $VAULT_ID_TOKEN

이 예에서:

  • production/db는 시크릿의 경로입니다.
  • password는 필드입니다.
  • ops는 시크릿 엔진이 마운트된 경로입니다.
  • production/db/password@opsops/data/production/db 경로로 변환됩니다.
  • $VAULT_ID_TOKEN으로 인증합니다.

GitLab이 Vault에서 시크릿을 가져온 후 값은 임시 파일에 저장됩니다. 이 파일의 경로는 DATABASE_PASSWORD라는 CI/CD 변수에 저장됩니다. 이는 file 유형의 변수와 유사합니다.

기본 동작을 재정의하려면 file 옵션을 명시적으로 설정합니다:

secrets:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  DATABASE_PASSWORD:
    vault: production/db/password@ops
    file: false
    token: $VAULT_ID_TOKEN

이 예에서 시크릿 값은 파일을 가리키는 대신 DATABASE_PASSWORD 변수에 직접 저장됩니다.

시크릿 엔진#

히스토리
  • generic 옵션이 GitLab Runner 16.11에서 도입됨.

GitLab Runner는 secrets:engine:name 키워드로 다양한 시크릿 엔진을 지원합니다:

시크릿 엔진 secrets:engine:name Runner 버전 세부 정보
KV 시크릿 엔진 - 버전 2 kv-v2 13.4 엔진 유형이 명시적으로 지정되지 않은 경우 GitLab Runner가 사용하는 기본 엔진입니다.
KV 시크릿 엔진 - 버전 1 kv-v1 또는 generic 13.4 generic 키워드 지원이 GitLab 15.11에서 도입됨.
AWS 시크릿 엔진 generic 16.11
HashiCorp Vault Artifactory 시크릿 플러그인 generic 16.11 이 시크릿 백엔드는 JFrog Artifactory 서버(5.0.0 이상)와 통신하고 지정된 범위의 액세스 토큰을 동적으로 프로비저닝합니다.

다른 시크릿 엔진 사용#

kv-v2 시크릿 엔진이 기본적으로 사용됩니다. 다른 엔진을 사용하려면 구성의 vault 아래에 engine 섹션을 추가합니다.

예를 들어 Artifactory의 시크릿 엔진 및 경로를 설정하려면:

job_using_vault:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    JFROG_TOKEN:
      vault:
        engine:
          name: generic
          path: artifactory
        path: production/jfrog
        field: access_token
      file: false

이 예에서 시크릿 값은 access_token 필드로 artifactory/production/jfrog에서 가져옵니다.

문제 해결#

자체 서명 인증서 오류: certificate signed by unknown authority#

Vault 서버가 자체 서명 인증서를 사용하는 경우 잡 로그에 다음 오류가 표시됩니다:

ERROR: Job failed (system failure): resolving secrets: initializing Vault service: preparing authenticated client: checking Vault server health: Get https://vault.example.com:8000/v1/sys/health?drsecondarycode=299&performancestandbycode=299&sealedcode=299&standbycode=299&uninitcode=299: x509: certificate signed by unknown authority

이 오류를 해결하는 두 가지 옵션이 있습니다:

  • 자체 서명 인증서를 GitLab Runner 서버의 CA 저장소에 추가합니다. Helm 차트를 사용하여 GitLab Runner를 배포한 경우 자체 GitLab Runner 이미지를 만들어야 합니다.
  • VAULT_CACERT 환경 변수를 사용하여 인증서를 신뢰하도록 GitLab Runner를 구성합니다:
    • systemd를 사용하여 GitLab Runner를 관리하는 경우 GitLab Runner에 환경 변수를 추가하는 방법을 참조하세요.
    • Helm 차트를 사용하여 GitLab Runner를 배포한 경우:
      1. GitLab 액세스에 커스텀 인증서를 제공하고, GitLab 인증서 대신 Vault 서버의 인증서를 추가해야 합니다. GitLab 인스턴스도 자체 서명 인증서를 사용하는 경우 동일한 Secret에 두 인증서를 추가할 수 있습니다.

      2. values.yaml 파일에 다음 줄을 추가합니다:

        ## Replace both the  and the 
        ## with the actual values you used to create the secret
        
        certsSecretName: 
        
        envVars:
          - name: VAULT_CACERT
            value: "/home/gitlab-runner/.gitlab-runner/certs/"
        

GitLab 개발 키트(GDK)를 사용하여 로컬에서 개발 모드로 vault 서버를 실행하는 경우에도 이 오류가 발생할 수 있습니다. Vault 서버의 자체 서명 인증서를 신뢰하도록 시스템에 수동으로 요청할 수 있습니다. 이 샘플 튜토리얼은 macOS에서 이를 수행하는 방법을 설명합니다.

resolving secrets: secret not found: MY_SECRET 오류#

GitLab이 vault에서 시크릿을 찾을 수 없는 경우 다음 오류가 발생할 수 있습니다:

ERROR: Job failed (system failure): resolving secrets: secret not found: MY_SECRET

CI/CD 잡에서 vault 값이 올바르게 구성되어 있는지 확인합니다.

Vault CLI의 kv 명령을 사용하여 시크릿을 검색할 수 있는지 확인하여 CI/CD 구성의 vault 값 구문을 확인할 수 있습니다. 예를 들어 시크릿을 검색하려면:

$ vault kv get -field=password -namespace=admin -mount=ops "production/db"
this-is-a-password

GitLab CI/CD에서 HashiCorp Vault 시크릿 사용

Tier: Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

GitLab CI/CD에서 HashiCorp Vault 시크릿을 사용할 수 있습니다. CI/CD 잡에서 Vault 시크릿을 사용하려면 먼저 Vault 서버를 구성해야 합니다. 다음 예에서 vault.example.com을 Vault 서버의 URL로, gitlab.example.com을 GitLab 인스턴스의 URL로 교체합니다.

GitLab CI/CD에서 HashiCorp Vault 시크릿을 사용할 수 있습니다. ID 토큰을 사용하여 HashiCorp Vault로 인증합니다.

CI/CD 잡에서 Vault 시크릿을 사용하려면 먼저 Vault 서버를 구성해야 합니다. HashiCorp Vault로 시크릿 인증 및 읽기 튜토리얼에 Vault 구성 및 ID 토큰을 사용한 인증에 대한 자세한 내용이 있습니다.

다음 예에서 vault.example.com을 Vault 서버의 URL로, gitlab.example.com을 GitLab 인스턴스의 URL로 교체합니다.

Vault 서버 구성#

Vault 서버를 구성하려면:

  1. 다음 명령을 실행하여 인증 방법을 활성화합니다. 이 명령은 Vault 서버에 GitLab 인스턴스의 OIDC 디스커버리 URL을 제공하여 Vault가 공개 서명 키를 가져오고 인증 시 JSON Web Token(JWT)을 검증할 수 있게 합니다:

    $ vault auth enable jwt
    
    $ vault write auth/jwt/config \
      oidc_discovery_url="https://gitlab.example.com" \
      bound_issuer="gitlab.example.com"
    
  2. 특정 경로 및 작업에 대한 액세스를 허용하거나 거부하도록 Vault 서버에 정책을 구성합니다. 이 예에서는 프로덕션 환경에 필요한 시크릿 세트에 대한 읽기 전용 액세스를 부여합니다:

    vault policy write myproject-production - <# Read-only permission on 'ops/data/production/*' path
    
    path "ops/data/production/*" {
      capabilities = [ "read" ]
    }
    EOF
    
  3. Vault 서버에 역할을 구성하여 역할을 프로젝트나 네임스페이스로 제한합니다.

  4. 다음 CI/CD 변수를 만들어 Vault 서버에 대한 세부 정보를 제공합니다:

    • VAULT_SERVER_URL: https://vault.example.com:8200과 같은 Vault 서버의 URL.
    • VAULT_AUTH_ROLE: 선택 사항. 인증 시도 시 사용할 역할. 역할이 지정되지 않으면 Vault는 인증 방법이 구성될 때 지정된 기본 역할을 사용합니다.
    • VAULT_AUTH_PATH: 선택 사항. 인증 방법이 마운트된 경로, 기본값은 jwt.
    • VAULT_NAMESPACE: 선택 사항. 시크릿 읽기 및 인증에 사용할 Vault Enterprise 네임스페이스. 다음 경우:
      • Vault의 경우 네임스페이스가 지정되지 않으면 root("/") 네임스페이스가 사용됩니다.
      • Vault 오픈 소스의 경우 설정이 무시됩니다.
      • HashiCorp Cloud Platform (HCP) Vault의 경우 네임스페이스가 필요합니다. HCP Vault는 기본적으로 admin 네임스페이스를 루트 네임스페이스로 사용합니다. 예를 들어 VAULT_NAMESPACE=admin.

서버 역할 구성#

CI/CD 잡이 인증을 시도할 때 역할을 지정합니다. 역할을 사용하여 다른 정책을 그룹화할 수 있습니다. 인증이 성공하면 이러한 정책이 결과 Vault 토큰에 첨부됩니다.

Bound claims는 JWT 클레임과 일치하는 미리 정의된 값입니다. 경계 클레임을 사용하면 특정 GitLab 사용자, 특정 프로젝트 또는 특정 Git 참조에 대해 실행되는 잡에 대한 액세스를 제한할 수 있습니다. 필요한 만큼 경계 클레임을 가질 수 있지만 인증이 성공하려면 모두 일치해야 합니다.

사용자 역할보호된 브랜치와 같은 GitLab 기능과 경계 클레임을 결합하여 특정 사용 사례에 맞게 이러한 규칙을 조정할 수 있습니다. 이 예에서는 프로덕션 릴리스에 사용되는 패턴과 일치하는 이름의 보호된 태그에 대해 실행되는 잡에 대해서만 인증이 허용됩니다:

$ vault write auth/jwt/role/myproject-production - <{
  "role_type": "jwt",
  "policies": ["myproject-production"],
  "token_explicit_max_ttl": 60,
  "user_claim": "user_email",
  "bound_audiences": "https://vault.example.com",
  "bound_claims_type": "glob",
  "bound_claims": {
    "project_id": "42",
    "ref_protected": "true",
    "ref_type": "tag",
    "ref": "auto-deploy-*"
  }
}
EOF
Warning

project_id 또는 namespace_id와 같은 제공된 클레임 중 하나를 사용하여 항상 역할을 프로젝트나 네임스페이스로 제한하세요. 이러한 제한 없이 이 GitLab 인스턴스에서 생성된 모든 JWT가 이 역할을 사용하여 인증할 수 있습니다.

ID 토큰 JWT 클레임의 전체 목록은 GitLab CI/CD에서 HashiCorp Vault 시크릿 사용 튜토리얼을 검토하세요.

시간 제한(TTL), IP 주소 범위, 사용 횟수 등 결과 Vault 토큰의 일부 속성을 지정할 수도 있습니다. 옵션의 전체 목록은 JSON Web Token 방법의 역할 생성에 관한 Vault 문서에서 확인할 수 있습니다.

CI/CD 잡에서 Vault 시크릿 사용#

잡에 하나 이상의 ID 토큰이 정의된 경우 secrets 키워드가 자동으로 해당 토큰을 사용하여 Vault로 인증합니다.

Vault 서버를 구성한 후 secrets:vault 키워드를 사용하여 Vault에 저장된 시크릿을 사용합니다:

job_using_vault:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    DATABASE_PASSWORD:
      vault: production/db/password@ops
      token: $VAULT_ID_TOKEN

이 예에서:

  • production/db는 시크릿의 경로입니다.
  • password는 필드입니다.
  • ops는 시크릿 엔진이 마운트된 경로입니다.
  • production/db/password@opsops/data/production/db 경로로 변환됩니다.
  • $VAULT_ID_TOKEN으로 인증합니다.

GitLab이 Vault에서 시크릿을 가져온 후 값은 임시 파일에 저장됩니다. 이 파일의 경로는 DATABASE_PASSWORD라는 CI/CD 변수에 저장됩니다. 이는 file 유형의 변수와 유사합니다.

기본 동작을 재정의하려면 file 옵션을 명시적으로 설정합니다:

secrets:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  DATABASE_PASSWORD:
    vault: production/db/password@ops
    file: false
    token: $VAULT_ID_TOKEN

이 예에서 시크릿 값은 파일을 가리키는 대신 DATABASE_PASSWORD 변수에 직접 저장됩니다.

시크릿 엔진#

히스토리
  • generic 옵션이 GitLab Runner 16.11에서 도입됨.

GitLab Runner는 secrets:engine:name 키워드로 다양한 시크릿 엔진을 지원합니다:

시크릿 엔진 secrets:engine:name Runner 버전 세부 정보
KV 시크릿 엔진 - 버전 2 kv-v2 13.4 엔진 유형이 명시적으로 지정되지 않은 경우 GitLab Runner가 사용하는 기본 엔진입니다.
KV 시크릿 엔진 - 버전 1 kv-v1 또는 generic 13.4 generic 키워드 지원이 GitLab 15.11에서 도입됨.
AWS 시크릿 엔진 generic 16.11
HashiCorp Vault Artifactory 시크릿 플러그인 generic 16.11 이 시크릿 백엔드는 JFrog Artifactory 서버(5.0.0 이상)와 통신하고 지정된 범위의 액세스 토큰을 동적으로 프로비저닝합니다.

다른 시크릿 엔진 사용#

kv-v2 시크릿 엔진이 기본적으로 사용됩니다. 다른 엔진을 사용하려면 구성의 vault 아래에 engine 섹션을 추가합니다.

예를 들어 Artifactory의 시크릿 엔진 및 경로를 설정하려면:

job_using_vault:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    JFROG_TOKEN:
      vault:
        engine:
          name: generic
          path: artifactory
        path: production/jfrog
        field: access_token
      file: false

이 예에서 시크릿 값은 access_token 필드로 artifactory/production/jfrog에서 가져옵니다.

문제 해결#

자체 서명 인증서 오류: certificate signed by unknown authority#

Vault 서버가 자체 서명 인증서를 사용하는 경우 잡 로그에 다음 오류가 표시됩니다:

ERROR: Job failed (system failure): resolving secrets: initializing Vault service: preparing authenticated client: checking Vault server health: Get https://vault.example.com:8000/v1/sys/health?drsecondarycode=299&performancestandbycode=299&sealedcode=299&standbycode=299&uninitcode=299: x509: certificate signed by unknown authority

이 오류를 해결하는 두 가지 옵션이 있습니다:

  • 자체 서명 인증서를 GitLab Runner 서버의 CA 저장소에 추가합니다. Helm 차트를 사용하여 GitLab Runner를 배포한 경우 자체 GitLab Runner 이미지를 만들어야 합니다.
  • VAULT_CACERT 환경 변수를 사용하여 인증서를 신뢰하도록 GitLab Runner를 구성합니다:
    • systemd를 사용하여 GitLab Runner를 관리하는 경우 GitLab Runner에 환경 변수를 추가하는 방법을 참조하세요.
    • Helm 차트를 사용하여 GitLab Runner를 배포한 경우:
      1. GitLab 액세스에 커스텀 인증서를 제공하고, GitLab 인증서 대신 Vault 서버의 인증서를 추가해야 합니다. GitLab 인스턴스도 자체 서명 인증서를 사용하는 경우 동일한 Secret에 두 인증서를 추가할 수 있습니다.

      2. values.yaml 파일에 다음 줄을 추가합니다:

        ## Replace both the  and the 
        ## with the actual values you used to create the secret
        
        certsSecretName: 
        
        envVars:
          - name: VAULT_CACERT
            value: "/home/gitlab-runner/.gitlab-runner/certs/"
        

GitLab 개발 키트(GDK)를 사용하여 로컬에서 개발 모드로 vault 서버를 실행하는 경우에도 이 오류가 발생할 수 있습니다. Vault 서버의 자체 서명 인증서를 신뢰하도록 시스템에 수동으로 요청할 수 있습니다. 이 샘플 튜토리얼은 macOS에서 이를 수행하는 방법을 설명합니다.

resolving secrets: secret not found: MY_SECRET 오류#

GitLab이 vault에서 시크릿을 찾을 수 없는 경우 다음 오류가 발생할 수 있습니다:

ERROR: Job failed (system failure): resolving secrets: secret not found: MY_SECRET

CI/CD 잡에서 vault 값이 올바르게 구성되어 있는지 확인합니다.

Vault CLI의 kv 명령을 사용하여 시크릿을 검색할 수 있는지 확인하여 CI/CD 구성의 vault 값 구문을 확인할 수 있습니다. 예를 들어 시크릿을 검색하려면:

$ vault kv get -field=password -namespace=admin -mount=ops "production/db"
this-is-a-password