InfoGrab DocsInfoGrab Docs

튜토리얼: ID 토큰을 사용하도록 HashiCorp Vault 구성 업데이트

요약

이 튜토리얼은 현재 CI/CD 시크릿 구성을 ID 토큰을 사용하도록 변환하는 방법을 설명합니다. CI_JOB_JWT 변수는 더 이상 사용되지 않습니다. ID 토큰으로 변환하는 방법은 다음과 같습니다. 이 튜토리얼은 GitLab CI/CD와 Vault에 익숙하다고 가정합니다.

이 튜토리얼은 현재 CI/CD 시크릿 구성을 ID 토큰을 사용하도록 변환하는 방법을 설명합니다.

CI_JOB_JWT 변수는 더 이상 사용되지 않습니다. 대신 ID 토큰을 사용하려면 Vault 인증 방법과 역할 구성을 업데이트해야 합니다.

ID 토큰으로 변환하는 방법은 다음과 같습니다.

  1. Vault 구성을 업데이트합니다. 다음 중 하나를 선택합니다.
  2. CI/CD job 업데이트

시작하기 전에#

이 튜토리얼은 GitLab CI/CD와 Vault에 익숙하다고 가정합니다.

따라 하려면 다음이 필요합니다.

  • 이미 사용 중인 Vault 서버.
  • CI_JOB_JWT로 Vault에서 시크릿을 가져오는 CI/CD job.
Note

Vault 1.17 이상에서는 JWT에 aud 클레임이 포함된 경우 JWT 인증 로그인에 역할의 바운드 대상이 필요합니다. aud 클레임은 단일 문자열이거나 문자열 목록일 수 있습니다.

JWT 역할을 새 인증 경로로 마이그레이션#

이 방식은 현재 사용 중인 JWT 인증 방법과 병렬로 두 번째 JWT 인증 방법을 만든 다음, 역할이 이를 사용하도록 재생성합니다. 인증 방법을 중복해서 만들고 싶지 않다면 대신 역할 수준 클레임을 사용합니다.

Vault에서 두 번째 JWT 인증 경로 만들기#

다음 예시에서 gitlab.example.com을 GitLab 인스턴스의 URL로 바꿉니다.

CI_JOB_JWT에서 ID 토큰으로 전환하는 과정의 일부로, Vault의 bound_issuer를 업데이트하여 https://를 포함해야 합니다.

$ vault write auth/jwt/config \
    oidc_discovery_url="https://gitlab.example.com" \
    bound_issuer="https://gitlab.example.com"

이 변경을 하면 CI_JOB_JWT를 사용하는 job이 실패하기 시작합니다.

중단 없이 프로젝트 단위 또는 job 단위로 ID 토큰으로 전환하려면 Vault에서 여러 인증 경로를 만듭니다.

  1. jwt_v2라는 이름으로 새 인증 경로를 구성하려면 다음을 실행합니다.

    vault auth enable -path jwt_v2 jwt
    

    다른 이름을 선택할 수 있지만 나머지 예시에서는 jwt_v2를 사용한다고 가정하므로 필요에 따라 예시를 업데이트합니다.

  2. 인스턴스에 대한 새 인증 경로를 구성합니다.

    $ vault write auth/jwt_v2/config \
        oidc_discovery_url="https://gitlab.example.com" \
        bound_issuer="https://gitlab.example.com"
    

새 인증 경로를 사용하도록 역할 재생성#

다음 예시에서 vault.example.com을 Vault 서버의 URL로 바꿉니다.

역할은 특정 인증 경로에 바인딩되므로 job마다 새 역할을 추가해야 합니다. 역할의 bound_audiences 매개변수는 JWT에 대상(audience)이 포함된 경우 필수이며, JWT의 관련 aud 클레임 중 하나 이상과 일치해야 합니다.

  1. myproject-staging이라는 이름의 스테이징 역할을 재생성합니다.

    $ vault write auth/jwt_v2/role/myproject-staging - <<EOF
    {
      "role_type": "jwt",
      "policies": ["myproject-staging"],
      "token_explicit_max_ttl": 60,
      "user_claim": "user_email",
      "bound_audiences": ["https://vault.example.com"],
      "bound_claims": {
        "project_id": "22",
        "ref": "master",
        "ref_type": "branch"
      }
    }
    EOF
    
  2. myproject-production이라는 이름의 프로덕션 역할을 재생성합니다.

    $ vault write auth/jwt_v2/role/myproject-production - <<EOF
    {
      "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": "22",
        "ref_protected": "true",
        "ref_type": "branch",
        "ref": "auto-deploy-*"
      }
    }
    EOF
    

vault 명령에서 jwt를 jwt_v2로만 업데이트하면 됩니다. 역할 안의 role_type은 변경하지 않습니다.

iss 클레임을 역할 수준 클레임으로 이동#

이 방식은 두 번째 JWT 인증 방법을 만들거나 역할을 재생성할 필요가 없습니다. 대신 새 iss 클레임 값을 현재 역할에 직접 추가합니다. 역할마다 하나의 클레임 값만 유지하고 싶다면 대신 새 인증 경로를 사용합니다.

각 역할에 bound_issuers 클레임 맵 추가#

다음 예시에서 gitlab.example.com을 GitLab 인스턴스의 URL로, vault.example.com을 Vault 서버의 URL로, jwt를 현재 인증 방법 이름으로 바꿉니다.

Vault는 JWT 인증 방법 수준에서 여러 iss 클레임을 허용하지 않습니다. 이 수준의 bound_issuer 지시문은 단일 값만 허용하기 때문입니다. 그러나 bound_claims 맵 구성 지시문을 사용하면 역할 수준에서 여러 클레임을 구성할 수 있습니다.

이 방식에서는 Vault에 iss 클레임 검증에 사용할 여러 옵션, 즉 ID 토큰과 함께 제공되는 https:// 접두사가 붙은 GitLab 인스턴스 호스트 이름 클레임과 접두사가 없는 이전 클레임을 제공합니다.

필요한 역할에 bound_claims 구성을 추가하려면 다음을 실행합니다.

$ vault write auth/jwt/role/myproject-staging - <<EOF
{
  "role_type": "jwt",
  "policies": ["myproject-staging"],
  "token_explicit_max_ttl": 60,
  "user_claim": "user_email",
  "bound_audiences": ["https://vault.example.com"],
  "bound_claims": {
    "iss": [
      "https://gitlab.example.com",
      "gitlab.example.com"
    ],
    "project_id": "22",
    "ref": "master",
    "ref_type": "branch"
  }
}
EOF

bound_claims 섹션을 제외하고 현재 역할 구성은 변경하지 않아도 됩니다. Vault가 이 역할에서 접두사가 있는 iss 클레임과 접두사가 없는 iss 클레임을 모두 수락하도록 앞에서 보인 것처럼 iss 구성을 반드시 추가합니다.

다음 단계로 넘어가기 전에 GitLab 통합에 사용하는 모든 JWT 역할에 이 변경을 적용해야 합니다.

인증 방법에서 bound_issuers 클레임 제거#

모든 역할을 bound_claims.iss 클레임으로 업데이트한 뒤에는 이 검증에 대한 인증 방법 수준 구성을 제거할 수 있습니다.

$ vault write auth/jwt/config \
    oidc_discovery_url="https://gitlab.example.com" \
    bound_issuer=""

bound_issuer 값을 비워 두면 인증 방법 수준의 발급자 검증이 제거됩니다. 그러나 이 검증이 이제 역할 수준에 있으므로 구성은 여전히 안전합니다.

모든 프로젝트를 ID 토큰으로 마이그레이션해 더 이상 CI_JOB_JWT를 병행 지원할 필요가 없어지면 이 구성을 되돌릴 수 있습니다. 각 역할의 bound_claims에서 iss 클레임을 제거하고, 인증 방법의 bound_issuer를 다시 단일 값으로 설정합니다.

CI/CD job 업데이트#

Vault에는 두 가지 KV 시크릿 엔진이 있습니다. 사용하는 버전에 따라 CI/CD에서 시크릿을 정의하는 방법이 달라집니다.

Vault 서버를 확인하려면 HashiCorp 지원 포털의 Which Version is my Vault KV Mount? 문서를 참조합니다.

필요하면 다음 CI/CD 문서도 검토할 수 있습니다.

다음 예시는 스테이징 데이터베이스 비밀번호를 가져오는 방법을 보여 줍니다. 이 비밀번호는 secret/myproject/staging/db의 password 필드에 저장되어 있습니다. 다음 예시에서 vault.example.com을 Vault 서버의 URL로 바꿉니다.

VAULT_AUTH_PATH 변수의 값은 마이그레이션에 사용한 방식에 따라 다릅니다.

  • 새 인증 경로: jwt_v2를 사용합니다.
  • 역할 수준 클레임: jwt를 사용합니다.

KV 시크릿 엔진 v1#

secrets:vault 키워드는 기본적으로 KV 마운트 v2를 사용하므로, v1 엔진을 사용하도록 job을 명시적으로 구성해야 합니다.

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    PASSWORD:
      vault:
        engine:
          name: kv-v1
          path: secret
        field: password
        path: myproject/staging/db
      file: false

원하면 VAULT_SERVER_URL과 VAULT_AUTH_PATH를 모두 프로젝트 또는 그룹 CI/CD 변수로 정의할 수 있습니다.

secrets:file을 false로 설정한 이유는 ID 토큰이 기본적으로 시크릿을 파일에 저장하기 때문입니다. 이전 동작과 맞추려면 시크릿이 대신 일반 변수로 동작해야 합니다.

KV 시크릿 엔진 v2#

v2 엔진에는 두 가지 형식을 사용할 수 있습니다.

긴 형식:

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    PASSWORD:
      vault:
        engine:
          name: kv-v2
          path: secret
        field: password
        path: myproject/staging/db
      file: false

이 긴 형식은 v1 엔진 예시와 같지만, 엔진에 맞게 secrets:vault:engine:name:을 kv-v2로 설정합니다.

짧은 형식도 사용할 수 있습니다.

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
      PASSWORD:
        vault: myproject/staging/db/password@secret
        file: false

업데이트한 CI/CD 구성을 커밋하면 job이 ID 토큰으로 시크릿을 가져옵니다. ID 토큰으로의 변환이 완료되었습니다.

튜토리얼: ID 토큰을 사용하도록 HashiCorp Vault 구성 업데이트

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

요약

이 튜토리얼은 현재 CI/CD 시크릿 구성을 ID 토큰을 사용하도록 변환하는 방법을 설명합니다. CI_JOB_JWT 변수는 더 이상 사용되지 않습니다. ID 토큰으로 변환하는 방법은 다음과 같습니다. 이 튜토리얼은 GitLab CI/CD와 Vault에 익숙하다고 가정합니다.

이 튜토리얼은 현재 CI/CD 시크릿 구성을 ID 토큰을 사용하도록 변환하는 방법을 설명합니다.

CI_JOB_JWT 변수는 더 이상 사용되지 않습니다. 대신 ID 토큰을 사용하려면 Vault 인증 방법과 역할 구성을 업데이트해야 합니다.

ID 토큰으로 변환하는 방법은 다음과 같습니다.

  1. Vault 구성을 업데이트합니다. 다음 중 하나를 선택합니다.
  2. CI/CD job 업데이트

시작하기 전에#

이 튜토리얼은 GitLab CI/CD와 Vault에 익숙하다고 가정합니다.

따라 하려면 다음이 필요합니다.

  • 이미 사용 중인 Vault 서버.
  • CI_JOB_JWT로 Vault에서 시크릿을 가져오는 CI/CD job.
Note

Vault 1.17 이상에서는 JWT에 aud 클레임이 포함된 경우 JWT 인증 로그인에 역할의 바운드 대상이 필요합니다. aud 클레임은 단일 문자열이거나 문자열 목록일 수 있습니다.

JWT 역할을 새 인증 경로로 마이그레이션#

이 방식은 현재 사용 중인 JWT 인증 방법과 병렬로 두 번째 JWT 인증 방법을 만든 다음, 역할이 이를 사용하도록 재생성합니다. 인증 방법을 중복해서 만들고 싶지 않다면 대신 역할 수준 클레임을 사용합니다.

Vault에서 두 번째 JWT 인증 경로 만들기#

다음 예시에서 gitlab.example.com을 GitLab 인스턴스의 URL로 바꿉니다.

CI_JOB_JWT에서 ID 토큰으로 전환하는 과정의 일부로, Vault의 bound_issuer를 업데이트하여 https://를 포함해야 합니다.

$ vault write auth/jwt/config \
    oidc_discovery_url="https://gitlab.example.com" \
    bound_issuer="https://gitlab.example.com"

이 변경을 하면 CI_JOB_JWT를 사용하는 job이 실패하기 시작합니다.

중단 없이 프로젝트 단위 또는 job 단위로 ID 토큰으로 전환하려면 Vault에서 여러 인증 경로를 만듭니다.

  1. jwt_v2라는 이름으로 새 인증 경로를 구성하려면 다음을 실행합니다.

    vault auth enable -path jwt_v2 jwt
    

    다른 이름을 선택할 수 있지만 나머지 예시에서는 jwt_v2를 사용한다고 가정하므로 필요에 따라 예시를 업데이트합니다.

  2. 인스턴스에 대한 새 인증 경로를 구성합니다.

    $ vault write auth/jwt_v2/config \
        oidc_discovery_url="https://gitlab.example.com" \
        bound_issuer="https://gitlab.example.com"
    

새 인증 경로를 사용하도록 역할 재생성#

다음 예시에서 vault.example.com을 Vault 서버의 URL로 바꿉니다.

역할은 특정 인증 경로에 바인딩되므로 job마다 새 역할을 추가해야 합니다. 역할의 bound_audiences 매개변수는 JWT에 대상(audience)이 포함된 경우 필수이며, JWT의 관련 aud 클레임 중 하나 이상과 일치해야 합니다.

  1. myproject-staging이라는 이름의 스테이징 역할을 재생성합니다.

    $ vault write auth/jwt_v2/role/myproject-staging - <<EOF
    {
      "role_type": "jwt",
      "policies": ["myproject-staging"],
      "token_explicit_max_ttl": 60,
      "user_claim": "user_email",
      "bound_audiences": ["https://vault.example.com"],
      "bound_claims": {
        "project_id": "22",
        "ref": "master",
        "ref_type": "branch"
      }
    }
    EOF
    
  2. myproject-production이라는 이름의 프로덕션 역할을 재생성합니다.

    $ vault write auth/jwt_v2/role/myproject-production - <<EOF
    {
      "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": "22",
        "ref_protected": "true",
        "ref_type": "branch",
        "ref": "auto-deploy-*"
      }
    }
    EOF
    

vault 명령에서 jwt를 jwt_v2로만 업데이트하면 됩니다. 역할 안의 role_type은 변경하지 않습니다.

iss 클레임을 역할 수준 클레임으로 이동#

이 방식은 두 번째 JWT 인증 방법을 만들거나 역할을 재생성할 필요가 없습니다. 대신 새 iss 클레임 값을 현재 역할에 직접 추가합니다. 역할마다 하나의 클레임 값만 유지하고 싶다면 대신 새 인증 경로를 사용합니다.

각 역할에 bound_issuers 클레임 맵 추가#

다음 예시에서 gitlab.example.com을 GitLab 인스턴스의 URL로, vault.example.com을 Vault 서버의 URL로, jwt를 현재 인증 방법 이름으로 바꿉니다.

Vault는 JWT 인증 방법 수준에서 여러 iss 클레임을 허용하지 않습니다. 이 수준의 bound_issuer 지시문은 단일 값만 허용하기 때문입니다. 그러나 bound_claims 맵 구성 지시문을 사용하면 역할 수준에서 여러 클레임을 구성할 수 있습니다.

이 방식에서는 Vault에 iss 클레임 검증에 사용할 여러 옵션, 즉 ID 토큰과 함께 제공되는 https:// 접두사가 붙은 GitLab 인스턴스 호스트 이름 클레임과 접두사가 없는 이전 클레임을 제공합니다.

필요한 역할에 bound_claims 구성을 추가하려면 다음을 실행합니다.

$ vault write auth/jwt/role/myproject-staging - <<EOF
{
  "role_type": "jwt",
  "policies": ["myproject-staging"],
  "token_explicit_max_ttl": 60,
  "user_claim": "user_email",
  "bound_audiences": ["https://vault.example.com"],
  "bound_claims": {
    "iss": [
      "https://gitlab.example.com",
      "gitlab.example.com"
    ],
    "project_id": "22",
    "ref": "master",
    "ref_type": "branch"
  }
}
EOF

bound_claims 섹션을 제외하고 현재 역할 구성은 변경하지 않아도 됩니다. Vault가 이 역할에서 접두사가 있는 iss 클레임과 접두사가 없는 iss 클레임을 모두 수락하도록 앞에서 보인 것처럼 iss 구성을 반드시 추가합니다.

다음 단계로 넘어가기 전에 GitLab 통합에 사용하는 모든 JWT 역할에 이 변경을 적용해야 합니다.

인증 방법에서 bound_issuers 클레임 제거#

모든 역할을 bound_claims.iss 클레임으로 업데이트한 뒤에는 이 검증에 대한 인증 방법 수준 구성을 제거할 수 있습니다.

$ vault write auth/jwt/config \
    oidc_discovery_url="https://gitlab.example.com" \
    bound_issuer=""

bound_issuer 값을 비워 두면 인증 방법 수준의 발급자 검증이 제거됩니다. 그러나 이 검증이 이제 역할 수준에 있으므로 구성은 여전히 안전합니다.

모든 프로젝트를 ID 토큰으로 마이그레이션해 더 이상 CI_JOB_JWT를 병행 지원할 필요가 없어지면 이 구성을 되돌릴 수 있습니다. 각 역할의 bound_claims에서 iss 클레임을 제거하고, 인증 방법의 bound_issuer를 다시 단일 값으로 설정합니다.

CI/CD job 업데이트#

Vault에는 두 가지 KV 시크릿 엔진이 있습니다. 사용하는 버전에 따라 CI/CD에서 시크릿을 정의하는 방법이 달라집니다.

Vault 서버를 확인하려면 HashiCorp 지원 포털의 Which Version is my Vault KV Mount? 문서를 참조합니다.

필요하면 다음 CI/CD 문서도 검토할 수 있습니다.

다음 예시는 스테이징 데이터베이스 비밀번호를 가져오는 방법을 보여 줍니다. 이 비밀번호는 secret/myproject/staging/db의 password 필드에 저장되어 있습니다. 다음 예시에서 vault.example.com을 Vault 서버의 URL로 바꿉니다.

VAULT_AUTH_PATH 변수의 값은 마이그레이션에 사용한 방식에 따라 다릅니다.

  • 새 인증 경로: jwt_v2를 사용합니다.
  • 역할 수준 클레임: jwt를 사용합니다.

KV 시크릿 엔진 v1#

secrets:vault 키워드는 기본적으로 KV 마운트 v2를 사용하므로, v1 엔진을 사용하도록 job을 명시적으로 구성해야 합니다.

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    PASSWORD:
      vault:
        engine:
          name: kv-v1
          path: secret
        field: password
        path: myproject/staging/db
      file: false

원하면 VAULT_SERVER_URL과 VAULT_AUTH_PATH를 모두 프로젝트 또는 그룹 CI/CD 변수로 정의할 수 있습니다.

secrets:file을 false로 설정한 이유는 ID 토큰이 기본적으로 시크릿을 파일에 저장하기 때문입니다. 이전 동작과 맞추려면 시크릿이 대신 일반 변수로 동작해야 합니다.

KV 시크릿 엔진 v2#

v2 엔진에는 두 가지 형식을 사용할 수 있습니다.

긴 형식:

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    PASSWORD:
      vault:
        engine:
          name: kv-v2
          path: secret
        field: password
        path: myproject/staging/db
      file: false

이 긴 형식은 v1 엔진 예시와 같지만, 엔진에 맞게 secrets:vault:engine:name:을 kv-v2로 설정합니다.

짧은 형식도 사용할 수 있습니다.

job:
  variables:
    VAULT_SERVER_URL: https://vault.example.com
    VAULT_AUTH_PATH: jwt_v2  # or "jwt" if you used the role-level claims approach
    VAULT_AUTH_ROLE: myproject-staging
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
      PASSWORD:
        vault: myproject/staging/db/password@secret
        file: false

업데이트한 CI/CD 구성을 커밋하면 job이 ID 토큰으로 시크릿을 가져옵니다. ID 토큰으로의 변환이 완료되었습니다.