GitLab CI/CD 작업 토큰

Tier: Free, Premium, Ultimate
Offering: GitLab.com, Self-Managed형, GitLab Dedicated

CI/CD 파이프라인 작업이 실행되기 전에 GitLab은 고유한 토큰을 생성하고 작업에서 CI_JOB_TOKEN 미리 정의된 변수로 사용할 수 있도록 합니다.
이 토큰은 작업이 실행되는 동안에만 유효합니다. 작업이 완료되면 토큰 액세스가 취소되어 더 이상 토큰을 사용할 수 없습니다.

CI/CD 작업 토큰을 사용하여 실행 중인 작업에서 특정 GitLab 기능을 인증합니다.
토큰은 파이프라인을 트리거한 사용자와 동일한 액세스 수준을 받지만 개인 액세스 토큰보다는 적은 리소스에 액세스할 수 있습니다.
사용자는 커밋을 푸시하거나 매뉴얼 작업을 트리거하거나 예약된 파이프라인의 소유자인 등 작업을 실행시킬 수 있습니다.
이 사용자는 해당 리소스에 액세스할 수 있는 필수 권한을 가진 역할을 가져야 합니다.

작업 토큰을 사용하여 GitLab에 인증하여 다른 그룹 또는 프로젝트의 리소스(대상 프로젝트)에 액세스할 수 있습니다.
기본적으로 작업 토큰의 그룹 또는 프로젝트는 대상 프로젝트의 허용 디렉터리에 추가되어야 합니다.

프로젝트가 공개 또는 내부이면 허용 디렉터리에 없어도 일부 기능에 액세스할 수 있습니다.
예를 들어, 프로젝트의 공개 파이프라인에서 artifact를 가져올 수 있습니다.
이 액세스는 또한 제한될 수 있습니다.

기능 추가 세부사항
컨테이너 레지스트리 API 토큰은 작업 프로젝트의 컨테이너 레지스트리로 제한됩니다.
컨테이너 레지스트리 $CI_REGISTRY_PASSWORD 미리 정의된 변수는 CI/CD 작업 토큰입니다.
배포 API GET 요청은 기본적으로 공개됩니다.
환경 API GET 요청은 기본적으로 공개됩니다.
작업 artifact API GET 요청은 기본적으로 공개됩니다.
작업 API 작업 토큰의 작업을 얻기 위해.
패키지 레지스트리  
패키지 API GET 요청은 기본적으로 공개됩니다.
파이프라인 트리거 token= 매개변수와 함께 다중 프로젝트 파이프라인을 트리거하는 데 사용됩니다.
파이프라인 API 파이프라인 메타데이터를 업데이트하기 위해.
릴리스 링크 API  
릴리스 API GET 요청은 기본적으로 공개됩니다.
Terraform plan  

작업 토큰은 프로젝트의 리소스에 액세스할 수 있지만 불필요한 추가 권한을 부여할 수 있습니다.
보다 세분화된 액세스 권한을 위해 제안이 있습니다.

GitLab CI/CD 작업 토큰 보안

작업 토큰이 노출되면, 해당 CI/CD 작업을 트리거한 사용자의 액세스 가능한 개인 데이터에 잠재적으로 액세스할 수 있습니다.
토큰이 유출되거나 오용되지 않도록 돕기 위해 GitLab은:

  • 작업 로그에서 작업 토큰을 마스킹합니다.
  • 작업이 실행되는 동안에만 작업 토큰에 대한 권한을 부여합니다.

또한 러너(runner)를 안전하게 구성해야 합니다:

  • 기계를 재사용하는 경우 Docker privileged 모드를 사용하지 않습니다.
  • 작업이 동일한 머신에서 실행되는 경우 shell executor를 사용하지 않습니다.

보안이 취약한 GitLab 러너 구성은 다른 작업에서 토큰을 도난당할 수 있는 위험을 증가시킵니다.

프로젝트의 작업 토큰 액세스 제어

특정 그룹이나 프로젝트가 프로젝트의 리소스에 대해 작업 토큰을 사용하여 인증하고 액세스하는 것을 제어할 수 있습니다.

기본적으로 작업 토큰 액세스는 현재 프로젝트에서 파이프라인을 실행하는 CI/CD 작업에만 제한됩니다.
다른 그룹이나 프로젝트가 다른 프로젝트의 파이프라인에서 작업 토큰으로 인증하도록 허용하려면:

  • 그룹 또는 프로젝트를 작업 토큰 허용 디렉터리에 추가해야 합니다.
  • 작업을 트리거하는 사용자는 현재 프로젝트의 구성원이어야 합니다.
  • 사용자는 해당 작업을 수행할 권한을 가져야 합니다.

프로젝트가 공개 또는 내부이면 특정 공개 액세스 가능한 리소스에는 허용 디렉터리에 없는 임의의 프로젝트에서 작업 토큰을 사용하여 액세스할 수 있습니다.
이러한 리소스는 역시 허용 디렉터리에 있는 프로젝트만 액세스할 수 있습니다.

그룹 또는 프로젝트를 작업 토큰 허용 디렉터리에 추가

작업 토큰을 사용하여 인증하고 프로젝트의 리소스에 액세스하는 그룹 또는 프로젝트를 작업 토큰 허용 디렉터리에 추가할 수 있습니다.
기본적으로 모든 프로젝트의 허용 디렉터리에는 해당 프로젝트만 포함됩니다.

예를 들어, 프로젝트 A는 프로젝트 A의 허용 디렉터리에 프로젝트 B를 추가할 수 있습니다.
프로젝트 B(허용된 프로젝트)의 CI/CD 작업은 이제 프로젝트 A에 액세스할 수 있습니다.

그룹 또는 프로젝트를 허용 디렉터리에 추가하는 경우에만 프로젝트 간 액세스가 필요합니다.

전제 조건:

  • 현재 프로젝트에서 적어도 관리자 역할이어야 합니다. 허용된 프로젝트가 내부적이거나 비공개인 경우 해당 프로젝트에서 적어도 게스트 역할이어야 합니다.
  • 허용 디렉터리에 추가된 그룹 및 프로젝트가 200개를 초과할 수 없습니다.

그룹 또는 프로젝트를 허용 디렉터리에 추가하려면:

  1. 왼쪽 사이드바에서 검색 또는 찾아가기를 선택하여 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. Token Access를 확장합니다.
  4. 이 프로젝트로의 액세스 제한 토글이 활성화되어 있는지 확인합니다. 새 프로젝트에서는 기본적으로 활성화됩니다.
    이 기능을 비활성화하면 보안 위험성이 발생할 수 있으므로 프로젝트 유지자 또는 소유자는 무조건 이 설정을 활성화 상태로 유지해야 합니다.
  5. 그룹 또는 프로젝트 추가를 선택합니다.
  6. 허용 디렉터리에 추가하려는 그룹 또는 프로젝트의 경로를 입력하고 프로젝트 추가를 선택합니다.

또한 API를 사용하여 그룹 또는 프로젝트를 허용 디렉터리에 추가할 수 있습니다.

공개 또는 내부 프로젝트에 대한 작업 토큰 범위 제한

  • GitLab 16.6에서 도입되었습니다. (소개됨)

허용 디렉터리에 없는 프로젝트는 작업 토큰을 사용하여 공개 또는 내부 프로젝트에 대해 인증하는 데 사용할 수 있습니다:

  • 아티팩트 검색.
  • 컨테이너 레지스트리 접근.
  • 패키지 레지스트리 접근.
  • 릴리스, 배포 및 환경 접근.

허용 디렉터리에 있는 프로젝트의 구성원만 이러한 작업에 대한 액세스를 제한하여 이러한 작업에 대한 액세스를 제한할 수 있습니다.

전제 조건:

  • 프로젝트의 Maintainer 역할이어야 합니다.

기능을 프로젝트 구성원만 표시되도록 설정하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > 일반을 선택합니다.
  3. 가시성, 프로젝트 기능, 권한을 확장합니다.
  4. 원하는 기능에 대해 가시성을 프로젝트 구성원만으로 설정합니다.
    • 아티팩트 검색 기능은 CI/CD 가시성 설정으로 제어됩니다.
  5. 변경 사항 저장을 선택합니다.

모든 프로젝트에 대한 프로젝트 액세스 허용

caution
토큰 액세스 제한 및 허용 디렉터리을 해제하는 것은 보안 위험입니다. 악의적인 사용자는 권한이 없는 프로젝트에서 생성된 파이프라인을 손상시키려고 할 수 있습니다. 만약 파이프라인이 프로젝트의 관리자 중 한 명에 의해 생성된 경우, 작업 토큰은 프로젝트에 액세스하려는 시도에 사용될 수 있습니다.

이 프로젝트로의 액세스 제한 설정을 해제하면 허용 디렉터리이 무시됩니다. 사용자가 파이프라인을 트리거하는 권한이 있는 경우 모든 프로젝트의 작업이 해당 프로젝트에 대한 작업 토큰으로 액세스할 수 있습니다.

이 설정을 테스트하거나 유사한 이유로만 해제해야 하며 가능한 빨리 다시 활성화해야 합니다.

전제 조건:

  • 프로젝트의 적어도 Maintainer 역할이어야 합니다.

작업 토큰 범위 허용 디렉터리을 해제하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 토큰 액세스를 확장합니다.
  4. 이 프로젝트로의 액세스 제한을 비활성화로 토글합니다.
    • 새 프로젝트의 경우 기본적으로 활성화됩니다.

또한 GraphQL (inboundJobTokenScopeEnabled) 및 REST API로 설정을 활성화하거나 비활성화할 수 있습니다.

작업 토큰을 사용하여 비공개 프로젝트의 리포지터리 클론

작업 토큰을 사용하여 CI/CD 작업에서 비공개 프로젝트의 리포지터리를 인증하고 복제할 수 있습니다. 예를 들어:

git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/<namespace>/<project>

프로젝트의 HTTPS 프로토콜이 그룹, 프로젝트 또는 인스턴스 설정에서 비활성화된 경우에도 작업 토큰을 사용하여 리포지터리를 복제할 수 있습니다. 그러나 작업 토큰으로 리포지터리에 푸시할 수는 없지만 이슈 389060에서 이 동작을 변경하도록 제안되었습니다.

프로젝트의 작업 토큰 액세스 제한 (비권장됨)

caution
새 프로젝트의 경우 이 프로젝트로의 액세스 제한 설정은 기본적으로 비활성화되어 있으며 GitLab 17.0에서 삭제 예정되었습니다. 프로젝트 관리자 또는 소유자는 대신 이 프로젝트에 대한 액세스 제한 설정을 구성해야 합니다.

프로젝트의 작업 토큰 범위를 제어하여 프로젝트의 작업 토큰으로 액세스할 수 있는 프로젝트의 허용 디렉터리을 만들어 정의할 수 있습니다.

기본적으로 허용 디렉터리에는 현재 프로젝트가 포함됩니다. 다른 프로젝트는 둘 다 액세스 권한이 있는 관리자에 의해 추가 및 삭제할 수 있습니다.

해당 설정이 비활성화된 경우 모든 프로젝트가 허용 디렉터리으로 간주되며 작업 토큰은 사용자의 액세스 권한에만 제한됩니다.

예를 들어 설정이 활성화되면 프로젝트 A의 파이프라인에서 CI_JOB_TOKEN 범위가 프로젝트 A로 제한됩니다. 만약 작업이 프로젝트 B에 대한 API 요청에 토큰을 사용해야 하는 경우 BA의 허용 디렉터리에 추가해야 합니다.

작업 토큰 범위 구성 (비권장됨)

전제 조건:

  • 토큰의 범위에 추가된 프로젝트 수가 200개를 넘어서는 안 됩니다.

작업 토큰 범위를 구성하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 토큰 액세스를 확장합니다.
  4. 이 프로젝트로의 액세스 제한을 활성화로 토글합니다.
  5. 선택 사항. 토큰의 액세스 범위에 기존 프로젝트를 추가합니다. 프로젝트를 추가하는 사용자는 두 프로젝트 모두에서 Maintainer 역할이어야 합니다.

문제 해결

CI 작업 토큰 실패는 일반적으로 404 Not Found 등의 응답으로 표시됩니다.

  • 인증되지 않은 Git 복제:

    $ git clone https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/fabiopitino/test2.git
      
    Cloning into 'test2'...
    remote: The project you were looking for could not be found or you don't have permission to view it.
    fatal: repository 'https://gitlab-ci-token:[MASKED]@gitlab.com/<namespace>/<project>.git/' not found
    
  • 인증되지 않은 패키지 다운로드:

    $ wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/1234/packages/generic/my_package/0.0.1/file.txt
      
    --2021-09-23 11:00:13--  https://gitlab.com/api/v4/projects/1234/packages/generic/my_package/0.0.1/file.txt
    Resolving gitlab.com (gitlab.com)... 172.65.251.78, 2606:4700:90:0:f22e:fbec:5bed:a9b9
    Connecting to gitlab.com (gitlab.com)|172.65.251.78|:443... connected.
    HTTP request sent, awaiting response... 404 Not Found
    2021-09-23 11:00:13 ERROR 404: Not Found.
    
  • 인증되지 않은 API 요청:

    $ curl --verbose --request POST --form "token=$CI_JOB_TOKEN" --form ref=master "https://gitlab.com/api/v4/projects/1234/trigger/pipeline"
      
    < HTTP/2 404
    < date: Thu, 23 Sep 2021 11:00:12 GMT
    {"message":"404 Not Found"}
    < content-type: application/json
    

CI/CD 작업 토큰 인증 문제를 해결할 때 주의할 사항:

  • GraphQL 예제 뮤테이션을 사용하여 프로젝트당 범위 설정을 토글할 수 있습니다.
  • 이 코멘트는 Bash 및 cURL에서 GraphQL을 사용하여 다음을 수행하는 방법을 보여줍니다:
    • 수신 토큰 액세스 범위를 활성화합니다.
    • 프로젝트 A에서 프로젝트 B에 액세스 권한을 부여하거나 B를 A의 허용 디렉터리에 추가합니다.
    • 프로젝트 액세스를 제거합니다.
  • 작업이 더 이상 실행 중이 아니거나 삭제되었거나 프로젝트가 삭제되는 중일 경우 CI 작업 토큰이 무효화됩니다.