참고: GitHub 호스트 실행기는 현재 GitHub Enterprise Server에서 지원되지 않습니다. GitHub public roadmap에 예정된 향후 지원에 대해 자세히 알아볼 수 있습니다.
OpenID Connect 개요
GitHub Actions 워크플로는 종종 소프트웨어를 배포하거나 클라우드의 서비스를 사용하기 위해 클라우드 공급자(예: AWS, Azure, GCP 또는 HashiCorp Vault)에 액세스하도록 설계되었습니다. 워크플로가 이러한 리소스에 액세스하기 전에 클라우드 공급자에게 암호 또는 토큰과 같은 자격 증명을 제공합니다. 이러한 자격 증명은 일반적으로 GitHub에 비밀로 저장되며 워크플로는 실행될 때마다 클라우드 공급자에게 이 비밀을 제공합니다.
그러나 하드 코딩된 비밀을 사용하려면 클라우드 공급자에서 자격 증명을 만든 다음, GitHub에서 비밀로 복제해야 합니다.
OIDC(OpenID Connect)를 사용하면 클라우드 공급자에게 직접 수명이 짧은 액세스 토큰을 요청하도록 워크플로를 구성하여 다른 접근 방식을 취할 수 있습니다. 또한 클라우드 공급자는 OIDC를 지원해야 하며, 액세스 토큰을 요청할 수 있는 워크플로를 제어하는 트러스트 관계를 구성해야 합니다. 현재 OIDC를 지원하는 공급자로는 Amazon Web Services, Azure, Google Cloud Platform 및 HashiCorp Vault 등이 있습니다.
OIDC 사용의 장점
OIDC 토큰을 사용하도록 워크플로를 업데이트하면 다음과 같은 적절한 보안 사례를 채택할 수 있습니다.
- 클라우드 비밀 없음: 수명이 긴 GitHub 비밀로 클라우드 자격 증명을 복제할 필요가 없습니다. 대신 클라우드 공급자에서 OIDC 트러스트를 구성한 다음, 워크플로를 업데이트하여 OIDC를 통해 클라우드 공급자로부터 단기 액세스 토큰을 요청할 수 있습니다.
- 인증 및 권한 부여 관리: 워크플로가 자격 증명을 사용하고 클라우드 공급자의 인증(authN) 및 권한 부여(authZ) 도구를 사용하여 클라우드 리소스에 대한 액세스를 제어하는 방법을 보다 세부적으로 제어할 수 있습니다.
- 자격 증명 순환: OIDC를 사용하면 클라우드 공급자가 단일 작업에만 유효한 수명이 짧은 액세스 토큰을 발급한 다음, 자동으로 만료됩니다.
OIDC 시작
다음 다이어그램에서는 GitHub의 OIDC 공급자가 워크플로 및 클라우드 공급자와 통합되는 방법에 대한 개요를 제공합니다.
- 클라우드 공급자에서 클라우드에 액세스해야 하는 클라우드 역할과 GitHub 워크플로 간에 OIDC 트러스트를 만듭니다.
- 작업이 실행될 때마다 GitHub의 OIDC 공급자는 OIDC 토큰을 자동으로 생성합니다. 이 토큰에는 인증하려는 특정 워크플로에 대해 보안이 강화되고 확인 가능한 ID를 설정하는 여러 클레임이 포함되어 있습니다.
- GitHub의 OIDC 공급자에서 이 토큰을 요청하고 클라우드 공급자에게 표시하는 단계 또는 동작을 작업에 포함할 수 있습니다.
- 클라우드 공급자가 토큰에 제공된 클레임의 유효성을 성공적으로 검사하면 작업 기간 동안에만 사용할 수 있는 수명이 짧은 클라우드 액세스 토큰을 제공합니다.
클라우드를 사용하여 OIDC 트러스트 구성
GitHub의 OIDC 공급자를 신뢰하도록 클라우드를 구성하는 경우 신뢰할 수 없는 리포지토리 또는 워크플로가 클라우드 리소스에 대한 액세스 토큰을 요청할 수 없도록 들어오는 요청을 필터링하는 조건을 추가해야 합니다.
- 액세스 토큰을 부여하기 전에 클라우드 공급자는 트러스트 설정에서 조건을 설정하는 데 사용되는
subject
및 기타 클레임이 요청의 JWT(JSON Web Token)의 클레임과 일치하는지 확인합니다. 따라서 클라우드 공급자에서 주체 및 기타 조건을 올바르게 정의하기 위해 주의해야 합니다. - OIDC 트러스트 구성 단계 및 클라우드 역할에 대한 조건을 설정(주체 및 기타 클레임 사용)하는 구문은 사용 중인 클라우드 공급자에 따라 달라집니다. 몇 가지 예제는 "주체 클레임 예제"를 참조하세요.
OIDC 토큰 이해
각 작업은 GitHub의 OIDC 공급자로부터 OIDC 토큰을 요청합니다. 이 공급자는 생성된 각 워크플로 작업에 대해 고유한 자동으로 생성된 JWT(JSON Web Token)로 응답합니다. 작업이 실행되면 클라우드 공급자에게 OIDC 토큰이 표시됩니다. 토큰의 유효성을 검사하기 위해 클라우드 공급자는 OIDC 토큰의 주체 및 기타 클레임이 클라우드 역할의 OIDC 트러스트 정의에 미리 구성된 조건과 일치하는지 확인합니다.
다음 예제 OIDC 토큰은 octo-org/octo-repo
리포지토리에 sub
라는 작업 환경을 참조하는 주체(prod
)를 사용합니다.
{
"typ": "JWT",
"alg": "RS256",
"x5t": "example-thumbprint",
"kid": "example-key-id"
}
{
"jti": "example-id",
"sub": "repo:octo-org/octo-repo:environment:prod",
"environment": "prod",
"aud": "https://HOSTNAME/octo-org",
"ref": "refs/heads/main",
"sha": "example-sha",
"repository": "octo-org/octo-repo",
"repository_owner": "octo-org",
"actor_id": "12",
"repository_visibility": "private",
"repository_id": "74",
"repository_owner_id": "65",
"run_id": "example-run-id",
"run_number": "10",
"run_attempt": "2",
"actor": "octocat",
"workflow": "example-workflow",
"head_ref": "",
"base_ref": "",
"event_name": "workflow_dispatch",
"ref_type": "branch",
"job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main",
"iss": "https://HOSTNAME/_services/token",
"nbf": 1632492967,
"exp": 1632493867,
"iat": 1632493567
}
GitHub의 OIDC 공급자에서 지원하는 모든 클레임을 보려면 https://HOSTNAME/_services/token/.well-known/openid-configuration
에서 claims_supported
항목을 검토합니다.
토큰에는 표준 대상 그룹, 발급자 및 주체 클레임이 포함됩니다.
클레임 | 클레임 유형 | Description |
---|---|---|
aud | 사용자 | 기본적으로 리포지토리를 소유하는 조직과 같은 리포지토리 소유자의 URL입니다. 사용자 지정할 수 있는 유일한 클레임입니다. 도구 키트 명령 core.getIDToken(audience) 을 사용하여 사용자 지정 대상 그룹을 설정할 수 있습니다. |
iss | 발급자 | OIDC 토큰 발급자: https://HOSTNAME/_services/token |
sub | 제목 | 클라우드 공급자가 유효성을 검사할 주체 클레임을 정의합니다. 이 설정은 액세스 토큰이 예측 가능한 방식으로만 할당되도록 하는 데 필수적입니다. |
OIDC 토큰에는 추가 표준 클레임도 포함됩니다.
클레임 | 클레임 유형 | Description |
---|---|---|
alg | 알고리즘 | OIDC 공급자가 사용하는 알고리즘입니다. |
exp | 만료 날짜 | JWT의 만료 시간을 식별합니다. |
iat | 발급 시간 | JWT가 발급된 시간입니다. |
jti | JWT 토큰 식별자 | OIDC 토큰의 고유 식별자입니다. |
kid | 키 식별자 | OIDC 토큰에 대한 고유 키입니다. |
nbf | 이전이 아님 | 이 시간 전에는 JWT를 사용할 수 없습니다. |
typ | 형식 | 토큰의 형식을 설명합니다. JWT(JSON Web Token)입니다. |
토큰에는 GitHub에서 제공하는 사용자 지정 클레임도 포함됩니다.
클레임 | 설명 |
---|---|
actor | 워크플로 실행을 시작한 개인 계정입니다. |
actor_id | 워크플로 실행을 시작한 개인 계정의 ID입니다. |
base_ref | 워크플로 실행에서 끌어오기 요청의 대상 분기입니다. |
environment | 작업에 사용되는 환경의 이름입니다. |
event_name | 워크플로 실행을 트리거한 이벤트의 이름입니다. |
head_ref | 워크플로 실행에서 끌어오기 요청의 소스 분기입니다. |
job_workflow_ref | 재사용 가능한 워크플로를 사용하는 작업의 경우 재사용 가능한 워크플로에 대한 참조 경로입니다. 자세한 내용은 "재사용 가능한 워크플로에서 OpenID 커넥트 사용"을 참조하세요. |
OIDC 클레임을 사용하여 클라우드 역할에 대한 트러스트 조건 정의
OIDC를 사용하면 클라우드 공급자의 리소스에 액세스하기 위해 GitHub Actions 워크플로에 토큰이 필요합니다. 워크플로는 클라우드 공급자로부터 JWT에서 제공하는 세부 정보를 확인하는 액세스 토큰을 요청합니다. JWT의 트러스트 구성이 일치하는 경우 클라우드 공급자는 워크플로에 임시 토큰을 발급하여 응답합니다. 그러면 클라우드 공급자의 리소스에 액세스하는 데 이 임시 토큰을 사용할 수 있습니다. 특정 조직의 리포지토리에서 시작된 요청에만 응답하도록 클라우드 공급자를 구성할 수 있습니다. 아래에 설명된 추가 조건을 지정할 수도 있습니다.
대상 그룹 및 주체 클레임은 일반적으로 클라우드 역할/리소스에 대한 조건을 설정하여 GitHub 워크플로에 대한 액세스 범위를 지정할 때 함께 사용됩니다.
- 대상 그룹: 기본적으로 이 값은 조직 또는 리포지토리 소유자의 URL을 사용합니다. 특정 조직의 워크플로만 클라우드 역할에 액세스할 수 있는 조건을 설정하는 데 사용할 수 있습니다.
- 주체: 기본적으로 미리 정의된 형식을 가지며 GitHub 조직, 리포지토리, 분기 또는 연결된
job
환경과 같은 워크플로에 대한 일부 주요 메타데이터를 연결한 것입니다. 연결된 메타데이터에서 주체 클레임이 어셈블되는 방법을 보려면 "주체 클레임 예제"를 참조하세요.
보다 세부적인 신뢰 조건이 필요한 경우 JWT에 포함된 발급자(iss
) 및 주체(sub
) 클레임을 사용자 지정할 수 있습니다. 자세한 내용은 “토큰 클레임 사용자 지정”을 참조하세요.
이러한 조건을 설정하는 데 사용할 수 있는 OIDC 토큰에서 지원되는 많은 추가 클레임이 있습니다. 또한 클라우드 공급자를 사용하면 액세스 토큰에 역할을 할당할 수 있으므로 보다 세부적인 권한을 지정할 수 있습니다.
참고: 클라우드 공급자가 액세스 토큰을 발급하는 방법을 제어하려면 신뢰할 수 없는 리포지토리가 클라우드 리소스에 대한 액세스 토큰을 요청할 수 없도록 하나 이상의 조건을 정의해야 합니다.
주체 클레임 예제
다음 예제에서는 "주체"를 조건으로 사용하는 방법과 연결된 메타데이터에서 "주체"가 어셈블되는 방법을 설명합니다. 주체는 job
컨텍스트의 정보를 사용하며, 특정 분기, 환경에서 실행되는 워크플로의 요청에 대해서만 액세스 토큰 요청을 부여할 수 있음을 클라우드 공급자에 알립니다. 다음 섹션에서는 사용할 수 있는 몇 가지 일반적인 주체에 대해 설명합니다.
특정 환경에 대한 필터링
주체 클레임에는 작업이 환경을 참조할 때의 환경 이름이 포함됩니다.
특정 환경 이름을 필터링하는 주체를 구성할 수 있습니다. 이 예제에서 워크플로 실행은 octo-org
조직이 소유한 octo-repo
라는 리포지토리에 Production
이라는 환경이 있는 작업에서 시작되어야 합니다.
- 구문:
repo:<orgName/repoName>:environment:<environmentName>
- 예:
repo:octo-org/octo-repo:environment:Production
pull_request
이벤트 필터링
워크플로가 끌어오기 요청 이벤트에 의해 트리거되는 경우 주체 클레임에 pull_request
문자열이 포함됩니다. 단, 작업에서 환경을 참조하지 않아야만 합니다.
pull_request
이벤트를 필터링하는 주체를 구성할 수 있습니다. 이 예제에서 워크플로 실행은 octo-org
조직이 소유한 octo-repo
라는 리포지토리의 pull_request
이벤트에 의해 트리거되어야 합니다.
- 구문:
repo:<orgName/repoName>:pull_request
- 예:
repo:octo-org/octo-repo:pull_request
특정 분기 필터링
주체 클레임에는 워크플로의 분기 이름이 포함됩니다. 단, 작업이 환경을 참조하지 않고 워크플로가 끌어오기 요청 이벤트에 의해 트리거되지 않는 경우에만 해당됩니다.
특정 분기 이름을 필터링하는 주체를 구성할 수 있습니다. 이 예제에서 워크플로 실행은 octo-org
조직이 소유한 octo-repo
라는 리포지토리에 demo-branch
라는 분기에서 시작되어야 합니다.
- 구문:
repo:<orgName/repoName>:ref:refs/heads/branchName
- 예: repo:octo-org/octo-repo:ref:refs/heads/demo-branch'
특정 태그 필터링
주체 클레임에는 워크플로의 태그 이름이 포함됩니다. 단, 작업이 환경을 참조하지 않고 워크플로가 끌어오기 요청 이벤트에 의해 트리거되지 않는 경우에만 해당됩니다.
특정 태그를 필터링하는 주체를 만들 수 있습니다. 이 예제에서 워크플로 실행은 octo-org
조직이 소유한 octo-repo
라는 리포지토리의 demo-tag
태그로 시작되어야 합니다.
- 구문:
repo:<orgName/repoName>:ref:refs/tags/<tagName>
- 예:
repo:octo-org/octo-repo:ref:refs/tags/demo-tag
클라우드 공급자에서 주체 구성
클라우드 공급자의 트러스트 관계에서 주체를 구성하려면 해당 트러스트 구성에 주체 문자열을 추가해야 합니다. 다음 예제에서는 다양한 클라우드 공급자가 서로 다른 방식으로 동일한 repo:octo-org/octo-repo:ref:refs/heads/demo-branch
주체를 수락하는 방법을 보여 줍니다.
클라우드 공급자 | 예제 |
---|---|
Amazon Web Services | "HOSTNAME/_services/token:sub": "repo:octo-org/octo-repo:ref:refs/heads/demo-branch" |
Azure | repo:octo-org/octo-repo:ref:refs/heads/demo-branch |
Google Cloud Platform | (assertion.sub=='repo:octo-org/octo-repo:ref:refs/heads/demo-branch') |
HashiCorp Vault | bound_subject="repo:octo-org/octo-repo:ref:refs/heads/demo-branch" |
자세한 내용은 "클라우드 공급자에 대해 OpenID Connect 사용"에 나열된 지침을 참조하세요.
OIDC에 대한 작업 업데이트
OIDC를 사용하여 인증하도록 사용자 지정 작업을 업데이트하려면 작업 도구 키트에서 getIDToken()
을 사용하여 GitHub의 OIDC 공급자로부터 JWT를 요청할 수 있습니다. 자세한 내용은 npm 패키지 설명서에서 "OIDC 토큰"을 참조하세요.
명령을 사용하여 다음 환경 변수를 curl
사용하여 JWT를 요청할 수도 있습니다.
변수 | Description |
---|---|
ACTIONS_ID_TOKEN_REQUEST_URL | GitHub의 OIDC 공급자에 대한 URL |
ACTIONS_ID_TOKEN_REQUEST_TOKEN | OIDC 공급자에 대한 요청의 전달자 토큰 |
예를 들면 다음과 같습니다.
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
사용 권한 설정 추가
작업 또는 워크플로 실행에는 id-token: write
관련 permissions
설정이 필요합니다. id-token
에 대한 permissions
설정이 read
또는 none
으로 설정된 경우 OIDC JWT ID 토큰을 요청할 수 없습니다.
이 id-token: write
설정을 통해 다음 방법 중 하나를 사용하여 GitHub의 OIDC 공급자에서 JWT를 요청할 수 있습니다.
- 실행기(
ACTIONS_ID_TOKEN_REQUEST_URL
및ACTIONS_ID_TOKEN_REQUEST_TOKEN
)에서 환경 변수 사용 - Actions 도구 키트에서
getIDToken()
사용
워크플로에 대한 OIDC 토큰을 페치해야 하는 경우 워크플로 수준에서 사용 권한을 설정할 수 있습니다. 예를 들어:
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
단일 작업에 대한 OIDC 토큰만 가져와야 하는 경우 해당 작업 내에서 이 권한을 설정할 수 있습니다. 예를 들면 다음과 같습니다.
permissions:
id-token: write # This is required for requesting the JWT
워크플로의 요구 사항에 따라 여기에서 추가 권한을 지정해야 할 수 있습니다.
재사용 가능한 워크플로의 permissions
경우 호출자 워크플로 수준 또는 재사용 가능한 워크플로를 write
호출하는 특정 작업에서 에 대한 id-token
설정을 로 설정해야 합니다. 자세한 내용은 "워크플로 다시 사용"을 참조하세요.
OIDC에 대한 워크플로 업데이트
이제 비밀 대신 OIDC 액세스 토큰을 사용하도록 YAML 워크플로를 업데이트할 수 있습니다. 인기 있는 클라우드 공급자는 OIDC를 쉽게 시작할 수 있도록 하는 공식 로그인 작업을 게시했습니다. 워크플로 업데이트에 대한 자세한 내용은 "클라우드 공급자에 OpenID Connect 사용"에 나열된 클라우드 관련 가이드를 참조하세요.
클라우드 공급자에 OpenID Connect 사용
특정 클라우드 공급자에 대해 OIDC를 사용하도록 설정하고 구성하려면 다음 가이드를 참조하세요.
- "Amazon Web Services에서 OpenID Connect 구성"
- "Azure에서 OpenID Connect 구성"
- "Google Cloud Platform에서 OpenID Connect 구성"
- "HashiCorp 자격 증명 모음에서 OpenID Connect 구성"
다른 클라우드 공급자에 대해 OIDC를 사용하도록 설정하고 구성하려면 다음 가이드를 참조하세요.