OpenID Connect (OIDC) Authentication Using ID Tokens
Offering: GitLab.com, Self-managed, GitLab Dedicated
- GitLab 15.7에서 소개되었습니다.
GitLab CI/CD의 ID 토큰을 사용하여 제3자 서비스로 인증할 수 있습니다.
ID 토큰
ID 토큰은 GitLab CI/CD 작업에 추가할 수 있는 JSON 웹 토큰(JWT)입니다. 이들은 제3자 서비스와의 OIDC 인증에 사용되며, secrets
키워드를 사용하여 HashiCorp Vault로의 인증에 사용됩니다.
ID 토큰은 .gitlab-ci.yml
에서 구성됩니다. 예를 들어:
job_with_id_tokens:
id_tokens:
FIRST_ID_TOKEN:
aud: https://first.service.com
SECOND_ID_TOKEN:
aud: https://second.service.com
script:
- first-service-authentication-script.sh $FIRST_ID_TOKEN
- second-service-authentication-script.sh $SECOND_ID_TOKEN
이 예에서 두 토큰은 다른 aud
클레임을 갖고 있습니다. 제3자 서비스는 자신의 바인딩된 대상 청중과 일치하지 않는 토큰을 거부하도록 구성할 수 있습니다. 이 기능을 사용하여 토큰이 인증할 수 있는 서비스의 수를 줄일 수 있습니다. 이를 통해 토큰이 Compromised되는 심각도를 줄일 수 있습니다.
토큰 페이로드
각 ID 토큰에는 다음 표준 클레임이 포함됩니다:
필드 | 설명 |
---|---|
iss
| 토큰의 발급자, 기본적으로 GitLab 인스턴스의 도메인입니다 (“issuer” 클레임). |
sub
|
project_path:{group}/{project}:ref_type:{type}:ref:{branch_name} (“subject” 클레임).
|
aud
| 토큰의 의도된 청중, 기본적으로 GitLab 인스턴스의 도메인입니다. ID 토큰의 구성에서 지정됩니다. |
exp
| 만료 시간 (“expiration time” 클레임). |
nbf
| 토큰이 유효해지는 시간 (“not before” 클레임). |
iat
| JWT가 발급된 시간 (“issued at” 클레임). |
jti
| 토큰의 고유 식별자 (“JWT ID” 클레임). |
토큰에는 GitLab에서 제공하는 사용자 정의 클레임도 포함됩니다: … (중략)
매뉴얼 ID 토큰 인증
서드 파티 서비스와 OIDC 인증에 ID 토큰을 사용할 수 있습니다. 예를 들어:
manual_authentication:
variables:
VAULT_ADDR: http://vault.example.com:8200
image: vault:latest
id_tokens:
VAULT_ID_TOKEN:
aud: http://vault.example.com:8200
script:
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-example jwt=$VAULT_ID_TOKEN)"
- export PASSWORD="$(vault kv get -field=password secret/myproject/example/db)"
- my-authentication-script.sh $VAULT_TOKEN $PASSWORD
HashiCorp Vault를 이용한 자동 ID 토큰 인증
Offering: GitLab.com, Self-managed, GitLab Dedicated
secrets
키워드를 사용하여 HashiCorp Vault에서 시크릿을 자동으로 가져오려면 ID 토큰을 사용할 수 있습니다.
만약 이전에 CI_JOB_JWT
를 사용하여 Vault에서 시크릿을 가져오셨다면 HashiCorp Vault 구성을 ID 토큰 사용으로 변경 튜토리얼을 통해 변경하는 방법을 알아보세요.
자동 ID 토큰 인증 구성
한 개의 ID 토큰이 정의된 경우, secrets
키워드는 자동으로 해당 토큰을 사용하여 Vault와 인증합니다. 예를 들어:
job_with_secrets:
id_tokens:
VAULT_ID_TOKEN:
aud: https://example.vault.com
secrets:
PROD_DB_PASSWORD:
vault: example/db/password # $VAULT_ID_TOKEN을 사용하여 인증
script:
- access-prod-db.sh --token $PROD_DB_PASSWORD
여러 개의 ID 토큰이 정의된 경우, token
키워드를 사용하여 어떤 토큰을 사용해야 하는지 지정합니다. 예를 들어:
job_with_secrets:
id_tokens:
FIRST_ID_TOKEN:
aud: https://first.service.com
SECOND_ID_TOKEN:
aud: https://second.service.com
secrets:
FIRST_DB_PASSWORD:
vault: first/db/password
token: $FIRST_ID_TOKEN
SECOND_DB_PASSWORD:
vault: second/db/password
token: $SECOND_ID_TOKEN
script:
- access-first-db.sh --token $FIRST_DB_PASSWORD
- access-second-db.sh --token $SECOND_DB_PASSWORD
문제 해결
400: missing token
상태 코드
이 오류는 ID 토큰에 필요한 하나 이상의 기본 컴포넌트가 누락되었거나 예상대로 구성되지 않았음을 나타냅니다.
문제를 찾으려면 관리자는 인스턴스의 exceptions_json.log
에서 실패한 특정 메서드에 대한 자세한 내용을 찾을 수 있습니다.
GitLab::Ci::Jwt::NoSigningKeyError
exceptions_json.log
파일의 이 오류는 데이터베이스에서 서명 키가 누락되어 토큰을 생성할 수 없기 때문입니다. 이 문제를 확인하려면 인스턴스의 PostgreSQL 터미널에서 다음 쿼리를 실행하세요:
SELECT encrypted_ci_jwt_signing_key FROM application_settings;
반환된 값이 비어 있다면, Rails 스니펫을 사용하여 새로운 키를 생성하고 내부적으로 교체하세요:
key = OpenSSL::PKey::RSA.new(2048).to_pem
ApplicationSetting.find_each do |application_setting|
application_setting.update(ci_jwt_signing_key: key)
end