InfoGrab Docs

Sigstore를 사용한 키 없는 서명 및 검증

요약

Sigstore 프로젝트는 GitLab CI/CD로 빌드된 컨테이너 이미지에 키 없는 서명을 사용할 수 있는 Cosign이라는 CLI를 제공합니다. GitLab OIDC 클레임과 Fulcio 인증서 확장 간의 매핑에 대한 자세한 내용은 OIDC 토큰 클레임을 Fulcio OID에 매핑하기의 GitLab 열을 참조하세요.

Sigstore 프로젝트는 GitLab CI/CD로 빌드된 컨테이너 이미지에 키 없는 서명을 사용할 수 있는 Cosign이라는 CLI를 제공합니다. 키 없는 서명은 개인 키를 관리, 보호 및 교체할 필요가 없다는 점을 포함하여 많은 이점이 있습니다. Cosign은 서명에 사용할 단기 키 쌍을 요청하고, 인증서 투명성 로그에 기록한 다음 폐기합니다. 키는 파이프라인을 실행한 사용자의 OIDC 신원을 사용하여 GitLab 서버에서 얻은 토큰을 통해 생성됩니다. 이 토큰에는 토큰이 CI/CD 파이프라인에 의해 생성되었음을 인증하는 고유한 클레임이 포함됩니다. 자세한 내용은 키 없는 서명에 대한 Cosign 문서를 참조하세요.

GitLab OIDC 클레임과 Fulcio 인증서 확장 간의 매핑에 대한 자세한 내용은 OIDC 토큰 클레임을 Fulcio OID에 매핑하기의 GitLab 열을 참조하세요.

전제 조건:

  • GitLab.com을 사용해야 합니다.
  • 프로젝트의 CI/CD 구성이 프로젝트에 위치해야 합니다.

Cosign을 사용하여 컨테이너 이미지 및 빌드 아티팩트 서명 또는 검증#

Cosign을 사용하여 컨테이너 이미지와 빌드 아티팩트를 서명하고 검증할 수 있습니다.

전제 조건:

  • >= 2.0.1 버전의 Cosign을 사용해야 합니다.

알려진 문제

  • CI/CD 구성 파일의 id_tokens 부분은 빌드 및 서명 대상 프로젝트에 위치해야 합니다. AutoDevOps, 다른 저장소에서 포함된 CI 파일, 자식 파이프라인은 지원되지 않습니다. 이 제한 사항을 제거하기 위한 작업은 에픽 11637에서 추적 중입니다.

모범 사례:

  • 서명 전에 이미지/아티팩트가 변조되는 것을 방지하기 위해 동일한 job에서 이미지/아티팩트를 빌드하고 서명하세요.
  • 컨테이너 이미지를 서명할 때 태그 대신 다이제스트(변경 불가)에 서명하세요.

GitLab ID 토큰은 Cosign의 키 없는 서명에 사용할 수 있습니다. 토큰에는 aud 클레임으로 sigstore가 설정되어 있어야 합니다. SIGSTORE_ID_TOKEN 환경 변수에 설정하면 Cosign이 토큰을 자동으로 사용할 수 있습니다.

Cosign 설치 방법에 대한 자세한 내용은 Cosign 설치 문서를 참조하세요.

서명#

컨테이너 이미지#

Cosign.gitlab-ci.yml 템플릿을 사용하여 GitLab CI에서 컨테이너 이미지를 빌드하고 서명할 수 있습니다. 서명은 이미지와 동일한 컨테이너 저장소에 자동으로 저장됩니다.

include:
- template: Cosign.gitlab-ci.yml

컨테이너 서명에 대한 자세한 내용은 Cosign 컨테이너 서명 문서를 참조하세요.

빌드 아티팩트#

다음 예시는 GitLab CI에서 빌드 아티팩트를 서명하는 방법을 보여줍니다. 서명 검증에 사용되는 cosign sign-blob으로 생성된 cosign.bundle 파일을 저장해야 합니다.

아티팩트 서명에 대한 자세한 내용은 Cosign 블롭 서명 문서를 참조하세요.

build_and_sign_artifact:
  stage: build
  image: alpine:latest
  variables:
    COSIGN_YES: "true"
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  before_script:
    - apk add --update cosign
  script:
    - echo "This is a build artifact" > artifact.txt
    - cosign sign-blob artifact.txt --bundle cosign.bundle
  artifacts:
    paths:
      - artifact.txt
      - cosign.bundle

검증#

커맨드라인 인수

이름
--certificate-identity Fulcio에서 발급한 서명 인증서의 SAN. 이미지/아티팩트가 서명된 프로젝트의 다음 정보로 구성할 수 있습니다: GitLab 인스턴스 URL + 프로젝트 경로 + // + CI 구성 경로 + @ + ref 경로.
--certificate-oidc-issuer 이미지/아티팩트가 서명된 GitLab 인스턴스 URL. 예: https://gitlab.com.
--bundle cosign sign-blob으로 생성된 bundle 파일. 빌드 아티팩트 검증에만 사용됩니다.

서명된 이미지/아티팩트 검증에 대한 자세한 내용은 Cosign 검증 문서를 참조하세요.

컨테이너 이미지#

다음 예시는 GitLab CI에서 서명된 컨테이너 이미지를 검증하는 방법을 보여줍니다. 앞서 설명한 커맨드라인 인수를 사용하세요.

verify_image:
  image: alpine:3.20
  stage: verify
  before_script:
    - apk add --update cosign docker
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - cosign verify "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" --certificate-identity "https://gitlab.com/my-group/my-project//path/to/.gitlab-ci.yml@refs/heads/main" --certificate-oidc-issuer "https://gitlab.com"

추가 세부 정보:

  • 프로젝트 경로와 .gitlab-ci.yml 경로 사이의 이중 백슬래시는 오류가 아니며 검증 성공에 필요합니다. 단일 슬래시를 사용할 때 일반적인 오류는 Error: none of the expected identities matched what was in the certificate, got subjects이며, 이 오류는 서명된 URL에 프로젝트 경로와 .gitlab-ci.yml 경로 사이에 두 개의 슬래시가 있음을 나타냅니다.
  • 서명과 동일한 파이프라인에서 검증이 이루어지는 경우 다음 경로를 사용할 수 있습니다: "${CI_PROJECT_URL}//.gitlab-ci.yml@refs/heads/${CI_COMMIT_REF_NAME}"

빌드 아티팩트#

다음 예시는 GitLab CI에서 서명된 빌드 아티팩트를 검증하는 방법을 보여줍니다. 아티팩트 검증을 위해서는 아티팩트 자체와 cosign sign-blob으로 생성된 cosign.bundle 파일이 모두 필요합니다. 앞서 설명한 커맨드라인 인수를 사용하세요.

verify_artifact:
  stage: verify
  image: alpine:latest
  before_script:
    - apk add --update cosign
  script:
    - cosign verify-blob artifact.txt --bundle cosign.bundle --certificate-identity "https://gitlab.com/my-group/my-project//path/to/.gitlab-ci.yml@refs/heads/main" --certificate-oidc-issuer "https://gitlab.com"

추가 세부 정보:

  • 프로젝트 경로와 .gitlab-ci.yml 경로 사이의 이중 백슬래시는 오류가 아니며 검증 성공에 필요합니다. 단일 슬래시를 사용할 때 일반적인 오류는 Error: none of the expected identities matched what was in the certificate, got subjects이며, 이 오류는 서명된 URL에 프로젝트 경로와 .gitlab-ci.yml 경로 사이에 두 개의 슬래시가 있음을 나타냅니다.
  • 서명과 동일한 파이프라인에서 검증이 이루어지는 경우 다음 경로를 사용할 수 있습니다: "${CI_PROJECT_URL}//.gitlab-ci.yml@refs/heads/${CI_COMMIT_REF_NAME}"

Sigstore와 npm을 사용하여 키 없는 증명 생성#

Sigstore와 npm을 GitLab CI/CD와 함께 사용하여 키 관리 오버헤드 없이 빌드 아티팩트에 디지털 서명을 할 수 있습니다.

npm 증명 정보#

npm CLI를 사용하면 패키지 관리자가 사용자에게 증명 어테스테이션을 제공할 수 있습니다. npm CLI 증명 생성을 사용하면 사용자가 다운로드하여 사용하는 패키지가 본인과 해당 패키지를 빌드한 빌드 시스템에서 제공된 것임을 신뢰하고 검증할 수 있습니다.

npm 패키지를 게시하는 방법에 대한 자세한 내용은 GitLab npm 패키지 레지스트리를 참조하세요.

Sigstore#

Sigstore는 패키지 관리자와 보안 전문가가 소프트웨어 공급망을 공격으로부터 보호하는 데 사용할 수 있는 도구 모음입니다. Fulcio, Cosign, Rekor와 같은 무료 오픈 소스 기술을 결합하여 오픈 소스 소프트웨어를 더 안전하게 배포하고 사용하는 데 필요한 디지털 서명, 검증 및 증명 확인을 처리합니다.

관련 주제:

GitLab CI/CD에서 증명 생성#

Sigstore가 앞서 설명한 GitLab OIDC를 지원하므로, npm 증명을 GitLab CI/CD 및 Sigstore와 함께 사용하여 GitLab CI/CD 파이프라인에서 npm 패키지의 증명을 생성하고 서명할 수 있습니다.

전제 조건#

  1. GitLab ID 토큰audsigstore로 설정합니다.
  2. npm publish에 --provenance 플래그를 추가합니다.

.gitlab-ci.yml 파일에 추가할 예시 내용:

build:
  image: node:latest
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  script:
    - npm publish --provenance --access public

npm GitLab 템플릿도 이 기능을 제공하며, 예시는 템플릿 문서에서 확인할 수 있습니다.

npm 증명 검증#

npm CLI도 최종 사용자가 패키지의 증명을 검증하는 기능을 제공합니다.

npm audit signatures
audited 1 package in 0s
1 package has a verified registry signature

증명 메타데이터 검사#

Rekor 투명성 로그는 증명과 함께 게시된 모든 패키지에 대한 인증서와 어테스테이션을 저장합니다. 예를 들어, 다음은 예시 항목입니다.

npm에서 생성된 증명 문서 예시:

_type: https://in-toto.io/Statement/v0.1
subject:
  - name: pkg:npm/%40strongjz/strongcoin@0.0.13
    digest:
      sha512: >-
        924a134a0fd4fe6a7c87b4687bf0ac898b9153218ce9ad75798cc27ab2cddbeff77541f3847049bd5e3dfd74cea0a83754e7686852f34b185c3621d3932bc3c8
predicateType: https://slsa.dev/provenance/v0.2
predicate:
  buildType: https://github.com/npm/CLI/gitlab/v0alpha1
  builder:
    id: https://gitlab.com/strongjz/npm-provenance-example/-/runners/12270835
  invocation:
    configSource:
      uri: git+https://gitlab.com/strongjz/npm-provenance-example
      digest:
        sha1: 6e02e901e936bfac3d4691984dff8c505410cbc3
      entryPoint: deploy
    parameters:
      CI: 'true'
      CI_API_GRAPHQL_URL: https://gitlab.com/api/graphql
      CI_API_V4_URL: https://gitlab.com/api/v4
      CI_COMMIT_BEFORE_SHA: 7d3e913e5375f68700e0c34aa90b0be7843edf6c
      CI_COMMIT_BRANCH: main
      CI_COMMIT_REF_NAME: main
      CI_COMMIT_REF_PROTECTED: 'true'
      CI_COMMIT_REF_SLUG: main
      CI_COMMIT_SHA: 6e02e901e936bfac3d4691984dff8c505410cbc3
      CI_COMMIT_SHORT_SHA: 6e02e901
      CI_COMMIT_TIMESTAMP: '2023-05-19T10:17:12-04:00'
      CI_COMMIT_TITLE: trying to publish to gitlab reg
      CI_CONFIG_PATH: .gitlab-ci.yml
      CI_DEFAULT_BRANCH: main
      CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: gitlab.com:443/strongjz/dependency_proxy/containers
      CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: gitlab.com:443/strongjz/dependency_proxy/containers
      CI_DEPENDENCY_PROXY_SERVER: gitlab.com:443
      CI_DEPENDENCY_PROXY_USER: gitlab-ci-token
      CI_JOB_ID: '4316132595'
      CI_JOB_NAME: deploy
      CI_JOB_NAME_SLUG: deploy
      CI_JOB_STAGE: deploy
      CI_JOB_STARTED_AT: '2023-05-19T14:17:23Z'
      CI_JOB_URL: https://gitlab.com/strongjz/npm-provenance-example/-/jobs/4316132595
      CI_NODE_TOTAL: '1'
      CI_PAGES_DOMAIN: gitlab.io
      CI_PAGES_URL: https://strongjz.gitlab.io/npm-provenance-example
      CI_PIPELINE_CREATED_AT: '2023-05-19T14:17:21Z'
      CI_PIPELINE_ID: '872773336'
      CI_PIPELINE_IID: '40'
      CI_PIPELINE_SOURCE: push
      CI_PIPELINE_URL: https://gitlab.com/strongjz/npm-provenance-example/-/pipelines/872773336
      CI_PROJECT_CLASSIFICATION_LABEL: ''
      CI_PROJECT_DESCRIPTION: ''
      CI_PROJECT_ID: '45821955'
      CI_PROJECT_NAME: npm-provenance-example
      CI_PROJECT_NAMESPACE: strongjz
      CI_PROJECT_NAMESPACE_SLUG: strongjz
      CI_PROJECT_NAMESPACE_ID: '36018'
      CI_PROJECT_PATH: strongjz/npm-provenance-example
      CI_PROJECT_PATH_SLUG: strongjz-npm-provenance-example
      CI_PROJECT_REPOSITORY_LANGUAGES: javascript,dockerfile
      CI_PROJECT_ROOT_NAMESPACE: strongjz
      CI_PROJECT_TITLE: npm-provenance-example
      CI_PROJECT_URL: https://gitlab.com/strongjz/npm-provenance-example
      CI_PROJECT_VISIBILITY: public
      CI_REGISTRY: registry.gitlab.com
      CI_REGISTRY_IMAGE: registry.gitlab.com/strongjz/npm-provenance-example
      CI_REGISTRY_USER: gitlab-ci-token
      CI_RUNNER_DESCRIPTION: 3-blue.shared.runners-manager.gitlab.com/default
      CI_RUNNER_ID: '12270835'
      CI_RUNNER_TAGS: >-
        ["gce", "east-c", "linux", "ruby", "mysql", "postgres", "mongo",
        "git-annex", "shared", "docker", "saas-linux-small-amd64"]
      CI_SERVER_HOST: gitlab.com
      CI_SERVER_NAME: GitLab
      CI_SERVER_PORT: '443'
      CI_SERVER_PROTOCOL: https
      CI_SERVER_REVISION: 9d4873fd3c5
      CI_SERVER_SHELL_SSH_HOST: gitlab.com
      CI_SERVER_SHELL_SSH_PORT: '22'
      CI_SERVER_URL: https://gitlab.com
      CI_SERVER_VERSION: 16.1.0-pre
      CI_SERVER_VERSION_MAJOR: '16'
      CI_SERVER_VERSION_MINOR: '1'
      CI_SERVER_VERSION_PATCH: '0'
      CI_TEMPLATE_REGISTRY_HOST: registry.gitlab.com
      GITLAB_CI: 'true'
      GITLAB_FEATURES: >-
        elastic_search,ldap_group_sync,multiple_ldap_servers,seat_link,usage_quotas,zoekt_code_search,repository_size_limit,admin_audit_log,auditor_user,custom_file_templates,custom_project_templates,db_load_balancing,default_branch_protection_restriction_in_groups,extended_audit_events,external_authorization_service_api_management,geo,instance_level_scim,ldap_group_sync_filter,object_storage,pages_size_limit,project_aliases,password_complexity,enterprise_templates,git_abuse_rate_limit,required_ci_templates,runner_maintenance_note,runner_performance_insights,runner_upgrade_management,runner_jobs_statistics
      GITLAB_USER_ID: '31705'
      GITLAB_USER_LOGIN: strongjz
    environment:
      name: 3-blue.shared.runners-manager.gitlab.com/default
      architecture: linux/amd64
      server: https://gitlab.com
      project: strongjz/npm-provenance-example
      job:
        id: '4316132595'
      pipeline:
        id: '872773336'
        ref: .gitlab-ci.yml
  metadata:
    buildInvocationId: https://gitlab.com/strongjz/npm-provenance-example/-/jobs/4316132595
    completeness:
      parameters: true
      environment: true
      materials: false
    reproducible: false
  materials:
    - uri: git+https://gitlab.com/strongjz/npm-provenance-example
      digest:
        sha1: 6e02e901e936bfac3d4691984dff8c505410cbc3

Sigstore를 사용한 키 없는 서명 및 검증

Tier: Free, Premium, Ultimate
Offering: GitLab.com
원문 보기
요약

Sigstore 프로젝트는 GitLab CI/CD로 빌드된 컨테이너 이미지에 키 없는 서명을 사용할 수 있는 Cosign이라는 CLI를 제공합니다. GitLab OIDC 클레임과 Fulcio 인증서 확장 간의 매핑에 대한 자세한 내용은 OIDC 토큰 클레임을 Fulcio OID에 매핑하기의 GitLab 열을 참조하세요.

Sigstore 프로젝트는 GitLab CI/CD로 빌드된 컨테이너 이미지에 키 없는 서명을 사용할 수 있는 Cosign이라는 CLI를 제공합니다. 키 없는 서명은 개인 키를 관리, 보호 및 교체할 필요가 없다는 점을 포함하여 많은 이점이 있습니다. Cosign은 서명에 사용할 단기 키 쌍을 요청하고, 인증서 투명성 로그에 기록한 다음 폐기합니다. 키는 파이프라인을 실행한 사용자의 OIDC 신원을 사용하여 GitLab 서버에서 얻은 토큰을 통해 생성됩니다. 이 토큰에는 토큰이 CI/CD 파이프라인에 의해 생성되었음을 인증하는 고유한 클레임이 포함됩니다. 자세한 내용은 키 없는 서명에 대한 Cosign 문서를 참조하세요.

GitLab OIDC 클레임과 Fulcio 인증서 확장 간의 매핑에 대한 자세한 내용은 OIDC 토큰 클레임을 Fulcio OID에 매핑하기의 GitLab 열을 참조하세요.

전제 조건:

  • GitLab.com을 사용해야 합니다.
  • 프로젝트의 CI/CD 구성이 프로젝트에 위치해야 합니다.

Cosign을 사용하여 컨테이너 이미지 및 빌드 아티팩트 서명 또는 검증#

Cosign을 사용하여 컨테이너 이미지와 빌드 아티팩트를 서명하고 검증할 수 있습니다.

전제 조건:

  • >= 2.0.1 버전의 Cosign을 사용해야 합니다.

알려진 문제

  • CI/CD 구성 파일의 id_tokens 부분은 빌드 및 서명 대상 프로젝트에 위치해야 합니다. AutoDevOps, 다른 저장소에서 포함된 CI 파일, 자식 파이프라인은 지원되지 않습니다. 이 제한 사항을 제거하기 위한 작업은 에픽 11637에서 추적 중입니다.

모범 사례:

  • 서명 전에 이미지/아티팩트가 변조되는 것을 방지하기 위해 동일한 job에서 이미지/아티팩트를 빌드하고 서명하세요.
  • 컨테이너 이미지를 서명할 때 태그 대신 다이제스트(변경 불가)에 서명하세요.

GitLab ID 토큰은 Cosign의 키 없는 서명에 사용할 수 있습니다. 토큰에는 aud 클레임으로 sigstore가 설정되어 있어야 합니다. SIGSTORE_ID_TOKEN 환경 변수에 설정하면 Cosign이 토큰을 자동으로 사용할 수 있습니다.

Cosign 설치 방법에 대한 자세한 내용은 Cosign 설치 문서를 참조하세요.

서명#

컨테이너 이미지#

Cosign.gitlab-ci.yml 템플릿을 사용하여 GitLab CI에서 컨테이너 이미지를 빌드하고 서명할 수 있습니다. 서명은 이미지와 동일한 컨테이너 저장소에 자동으로 저장됩니다.

include:
- template: Cosign.gitlab-ci.yml

컨테이너 서명에 대한 자세한 내용은 Cosign 컨테이너 서명 문서를 참조하세요.

빌드 아티팩트#

다음 예시는 GitLab CI에서 빌드 아티팩트를 서명하는 방법을 보여줍니다. 서명 검증에 사용되는 cosign sign-blob으로 생성된 cosign.bundle 파일을 저장해야 합니다.

아티팩트 서명에 대한 자세한 내용은 Cosign 블롭 서명 문서를 참조하세요.

build_and_sign_artifact:
  stage: build
  image: alpine:latest
  variables:
    COSIGN_YES: "true"
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  before_script:
    - apk add --update cosign
  script:
    - echo "This is a build artifact" > artifact.txt
    - cosign sign-blob artifact.txt --bundle cosign.bundle
  artifacts:
    paths:
      - artifact.txt
      - cosign.bundle

검증#

커맨드라인 인수

이름
--certificate-identity Fulcio에서 발급한 서명 인증서의 SAN. 이미지/아티팩트가 서명된 프로젝트의 다음 정보로 구성할 수 있습니다: GitLab 인스턴스 URL + 프로젝트 경로 + // + CI 구성 경로 + @ + ref 경로.
--certificate-oidc-issuer 이미지/아티팩트가 서명된 GitLab 인스턴스 URL. 예: https://gitlab.com.
--bundle cosign sign-blob으로 생성된 bundle 파일. 빌드 아티팩트 검증에만 사용됩니다.

서명된 이미지/아티팩트 검증에 대한 자세한 내용은 Cosign 검증 문서를 참조하세요.

컨테이너 이미지#

다음 예시는 GitLab CI에서 서명된 컨테이너 이미지를 검증하는 방법을 보여줍니다. 앞서 설명한 커맨드라인 인수를 사용하세요.

verify_image:
  image: alpine:3.20
  stage: verify
  before_script:
    - apk add --update cosign docker
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - cosign verify "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" --certificate-identity "https://gitlab.com/my-group/my-project//path/to/.gitlab-ci.yml@refs/heads/main" --certificate-oidc-issuer "https://gitlab.com"

추가 세부 정보:

  • 프로젝트 경로와 .gitlab-ci.yml 경로 사이의 이중 백슬래시는 오류가 아니며 검증 성공에 필요합니다. 단일 슬래시를 사용할 때 일반적인 오류는 Error: none of the expected identities matched what was in the certificate, got subjects이며, 이 오류는 서명된 URL에 프로젝트 경로와 .gitlab-ci.yml 경로 사이에 두 개의 슬래시가 있음을 나타냅니다.
  • 서명과 동일한 파이프라인에서 검증이 이루어지는 경우 다음 경로를 사용할 수 있습니다: "${CI_PROJECT_URL}//.gitlab-ci.yml@refs/heads/${CI_COMMIT_REF_NAME}"

빌드 아티팩트#

다음 예시는 GitLab CI에서 서명된 빌드 아티팩트를 검증하는 방법을 보여줍니다. 아티팩트 검증을 위해서는 아티팩트 자체와 cosign sign-blob으로 생성된 cosign.bundle 파일이 모두 필요합니다. 앞서 설명한 커맨드라인 인수를 사용하세요.

verify_artifact:
  stage: verify
  image: alpine:latest
  before_script:
    - apk add --update cosign
  script:
    - cosign verify-blob artifact.txt --bundle cosign.bundle --certificate-identity "https://gitlab.com/my-group/my-project//path/to/.gitlab-ci.yml@refs/heads/main" --certificate-oidc-issuer "https://gitlab.com"

추가 세부 정보:

  • 프로젝트 경로와 .gitlab-ci.yml 경로 사이의 이중 백슬래시는 오류가 아니며 검증 성공에 필요합니다. 단일 슬래시를 사용할 때 일반적인 오류는 Error: none of the expected identities matched what was in the certificate, got subjects이며, 이 오류는 서명된 URL에 프로젝트 경로와 .gitlab-ci.yml 경로 사이에 두 개의 슬래시가 있음을 나타냅니다.
  • 서명과 동일한 파이프라인에서 검증이 이루어지는 경우 다음 경로를 사용할 수 있습니다: "${CI_PROJECT_URL}//.gitlab-ci.yml@refs/heads/${CI_COMMIT_REF_NAME}"

Sigstore와 npm을 사용하여 키 없는 증명 생성#

Sigstore와 npm을 GitLab CI/CD와 함께 사용하여 키 관리 오버헤드 없이 빌드 아티팩트에 디지털 서명을 할 수 있습니다.

npm 증명 정보#

npm CLI를 사용하면 패키지 관리자가 사용자에게 증명 어테스테이션을 제공할 수 있습니다. npm CLI 증명 생성을 사용하면 사용자가 다운로드하여 사용하는 패키지가 본인과 해당 패키지를 빌드한 빌드 시스템에서 제공된 것임을 신뢰하고 검증할 수 있습니다.

npm 패키지를 게시하는 방법에 대한 자세한 내용은 GitLab npm 패키지 레지스트리를 참조하세요.

Sigstore#

Sigstore는 패키지 관리자와 보안 전문가가 소프트웨어 공급망을 공격으로부터 보호하는 데 사용할 수 있는 도구 모음입니다. Fulcio, Cosign, Rekor와 같은 무료 오픈 소스 기술을 결합하여 오픈 소스 소프트웨어를 더 안전하게 배포하고 사용하는 데 필요한 디지털 서명, 검증 및 증명 확인을 처리합니다.

관련 주제:

GitLab CI/CD에서 증명 생성#

Sigstore가 앞서 설명한 GitLab OIDC를 지원하므로, npm 증명을 GitLab CI/CD 및 Sigstore와 함께 사용하여 GitLab CI/CD 파이프라인에서 npm 패키지의 증명을 생성하고 서명할 수 있습니다.

전제 조건#

  1. GitLab ID 토큰audsigstore로 설정합니다.
  2. npm publish에 --provenance 플래그를 추가합니다.

.gitlab-ci.yml 파일에 추가할 예시 내용:

build:
  image: node:latest
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  script:
    - npm publish --provenance --access public

npm GitLab 템플릿도 이 기능을 제공하며, 예시는 템플릿 문서에서 확인할 수 있습니다.

npm 증명 검증#

npm CLI도 최종 사용자가 패키지의 증명을 검증하는 기능을 제공합니다.

npm audit signatures
audited 1 package in 0s
1 package has a verified registry signature

증명 메타데이터 검사#

Rekor 투명성 로그는 증명과 함께 게시된 모든 패키지에 대한 인증서와 어테스테이션을 저장합니다. 예를 들어, 다음은 예시 항목입니다.

npm에서 생성된 증명 문서 예시:

_type: https://in-toto.io/Statement/v0.1
subject:
  - name: pkg:npm/%40strongjz/strongcoin@0.0.13
    digest:
      sha512: >-
        924a134a0fd4fe6a7c87b4687bf0ac898b9153218ce9ad75798cc27ab2cddbeff77541f3847049bd5e3dfd74cea0a83754e7686852f34b185c3621d3932bc3c8
predicateType: https://slsa.dev/provenance/v0.2
predicate:
  buildType: https://github.com/npm/CLI/gitlab/v0alpha1
  builder:
    id: https://gitlab.com/strongjz/npm-provenance-example/-/runners/12270835
  invocation:
    configSource:
      uri: git+https://gitlab.com/strongjz/npm-provenance-example
      digest:
        sha1: 6e02e901e936bfac3d4691984dff8c505410cbc3
      entryPoint: deploy
    parameters:
      CI: 'true'
      CI_API_GRAPHQL_URL: https://gitlab.com/api/graphql
      CI_API_V4_URL: https://gitlab.com/api/v4
      CI_COMMIT_BEFORE_SHA: 7d3e913e5375f68700e0c34aa90b0be7843edf6c
      CI_COMMIT_BRANCH: main
      CI_COMMIT_REF_NAME: main
      CI_COMMIT_REF_PROTECTED: 'true'
      CI_COMMIT_REF_SLUG: main
      CI_COMMIT_SHA: 6e02e901e936bfac3d4691984dff8c505410cbc3
      CI_COMMIT_SHORT_SHA: 6e02e901
      CI_COMMIT_TIMESTAMP: '2023-05-19T10:17:12-04:00'
      CI_COMMIT_TITLE: trying to publish to gitlab reg
      CI_CONFIG_PATH: .gitlab-ci.yml
      CI_DEFAULT_BRANCH: main
      CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: gitlab.com:443/strongjz/dependency_proxy/containers
      CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: gitlab.com:443/strongjz/dependency_proxy/containers
      CI_DEPENDENCY_PROXY_SERVER: gitlab.com:443
      CI_DEPENDENCY_PROXY_USER: gitlab-ci-token
      CI_JOB_ID: '4316132595'
      CI_JOB_NAME: deploy
      CI_JOB_NAME_SLUG: deploy
      CI_JOB_STAGE: deploy
      CI_JOB_STARTED_AT: '2023-05-19T14:17:23Z'
      CI_JOB_URL: https://gitlab.com/strongjz/npm-provenance-example/-/jobs/4316132595
      CI_NODE_TOTAL: '1'
      CI_PAGES_DOMAIN: gitlab.io
      CI_PAGES_URL: https://strongjz.gitlab.io/npm-provenance-example
      CI_PIPELINE_CREATED_AT: '2023-05-19T14:17:21Z'
      CI_PIPELINE_ID: '872773336'
      CI_PIPELINE_IID: '40'
      CI_PIPELINE_SOURCE: push
      CI_PIPELINE_URL: https://gitlab.com/strongjz/npm-provenance-example/-/pipelines/872773336
      CI_PROJECT_CLASSIFICATION_LABEL: ''
      CI_PROJECT_DESCRIPTION: ''
      CI_PROJECT_ID: '45821955'
      CI_PROJECT_NAME: npm-provenance-example
      CI_PROJECT_NAMESPACE: strongjz
      CI_PROJECT_NAMESPACE_SLUG: strongjz
      CI_PROJECT_NAMESPACE_ID: '36018'
      CI_PROJECT_PATH: strongjz/npm-provenance-example
      CI_PROJECT_PATH_SLUG: strongjz-npm-provenance-example
      CI_PROJECT_REPOSITORY_LANGUAGES: javascript,dockerfile
      CI_PROJECT_ROOT_NAMESPACE: strongjz
      CI_PROJECT_TITLE: npm-provenance-example
      CI_PROJECT_URL: https://gitlab.com/strongjz/npm-provenance-example
      CI_PROJECT_VISIBILITY: public
      CI_REGISTRY: registry.gitlab.com
      CI_REGISTRY_IMAGE: registry.gitlab.com/strongjz/npm-provenance-example
      CI_REGISTRY_USER: gitlab-ci-token
      CI_RUNNER_DESCRIPTION: 3-blue.shared.runners-manager.gitlab.com/default
      CI_RUNNER_ID: '12270835'
      CI_RUNNER_TAGS: >-
        ["gce", "east-c", "linux", "ruby", "mysql", "postgres", "mongo",
        "git-annex", "shared", "docker", "saas-linux-small-amd64"]
      CI_SERVER_HOST: gitlab.com
      CI_SERVER_NAME: GitLab
      CI_SERVER_PORT: '443'
      CI_SERVER_PROTOCOL: https
      CI_SERVER_REVISION: 9d4873fd3c5
      CI_SERVER_SHELL_SSH_HOST: gitlab.com
      CI_SERVER_SHELL_SSH_PORT: '22'
      CI_SERVER_URL: https://gitlab.com
      CI_SERVER_VERSION: 16.1.0-pre
      CI_SERVER_VERSION_MAJOR: '16'
      CI_SERVER_VERSION_MINOR: '1'
      CI_SERVER_VERSION_PATCH: '0'
      CI_TEMPLATE_REGISTRY_HOST: registry.gitlab.com
      GITLAB_CI: 'true'
      GITLAB_FEATURES: >-
        elastic_search,ldap_group_sync,multiple_ldap_servers,seat_link,usage_quotas,zoekt_code_search,repository_size_limit,admin_audit_log,auditor_user,custom_file_templates,custom_project_templates,db_load_balancing,default_branch_protection_restriction_in_groups,extended_audit_events,external_authorization_service_api_management,geo,instance_level_scim,ldap_group_sync_filter,object_storage,pages_size_limit,project_aliases,password_complexity,enterprise_templates,git_abuse_rate_limit,required_ci_templates,runner_maintenance_note,runner_performance_insights,runner_upgrade_management,runner_jobs_statistics
      GITLAB_USER_ID: '31705'
      GITLAB_USER_LOGIN: strongjz
    environment:
      name: 3-blue.shared.runners-manager.gitlab.com/default
      architecture: linux/amd64
      server: https://gitlab.com
      project: strongjz/npm-provenance-example
      job:
        id: '4316132595'
      pipeline:
        id: '872773336'
        ref: .gitlab-ci.yml
  metadata:
    buildInvocationId: https://gitlab.com/strongjz/npm-provenance-example/-/jobs/4316132595
    completeness:
      parameters: true
      environment: true
      materials: false
    reproducible: false
  materials:
    - uri: git+https://gitlab.com/strongjz/npm-provenance-example
      digest:
        sha1: 6e02e901e936bfac3d4691984dff8c505410cbc3