GitHub Actions OIDC subject는 왜 이름이 아니라 ID로 묶어야 할까
CI/CD가 장기 secret을 없앴더라도, 클라우드 신뢰 정책이 여전히 바뀔 수 있는 repository 이름만 믿고 있다면 어떤 위험이 남을까?
GitHub Actions OIDC subject는 왜 이름이 아니라 ID로 묶어야 할까
- 카테고리: infra_dev
- 예상 읽기 시간: 10분
- 오늘의 질문: CI/CD가 장기 secret을 없앴더라도, 클라우드 신뢰 정책이 여전히 바뀔 수 있는 repository 이름만 믿고 있다면 어떤 위험이 남을까?
- 핵심 출처:
- Immutable subject claims for GitHub Actions OIDC tokens - 2026-04-23 게시, 2026-06-10 수정, 2026-06-26 확인
- GitHub Docs: OpenID Connect - 게시일 미표기, 2026-06-26 확인
- GitHub Docs: OpenID Connect reference - 게시일 미표기, 2026-06-26 확인
- Google Cloud IAM: Workload Identity Federation with deployment pipelines - 게시일 미표기, 2026-06-26 확인
1. 왜 지금 봐야 하나
CI/CD 보안에서 “GitHub Actions에 cloud secret을 저장하지 말고 OIDC를 쓰자”는 말은 이제 꽤 익숙하다. 워크플로가 GitHub OIDC token을 받고, AWS·Azure·GCP 같은 클라우드가 그 token의 claim을 검증한 뒤 짧은 수명의 권한을 발급하는 방식이다. 장기 credential을 없애므로 유출 반경이 줄고, 회전도 자동화된다.
그런데 OIDC로 바꿨다고 배포 신뢰 경계가 자동으로 완성되는 것은 아니다. 클라우드 쪽 trust policy가 “어떤 GitHub workflow를 믿을 것인가”를 잘못 표현하면, 짧은 수명 token도 잘못된 주체에게 권한을 줄 수 있다. 특히 repository 또는 organization 이름은 사람이 이해하기 쉽지만, rename·transfer·namespace 재사용 같은 운영 이벤트에 따라 바뀔 수 있다.
GitHub는 2026년 4월 changelog에서 GitHub Actions OIDC token의 기본 sub claim에 immutable owner/repository ID를 포함하는 변화를 발표했다. 2026년 6월 10일에는 subject 형식 예시도 repo:octo-org@123/octo-repo@456처럼 @ 구분자를 쓰도록 수정했다. GitHub 설명의 핵심은 분명하다. 기존 기본 subject가 repo:octocat/my-repo:ref:refs/heads/main처럼 mutable name에 의존했다면, repository나 organization 이름이 재사용될 때 오래된 cloud trust policy가 새 소유자를 믿을 수 있다는 것이다.
오늘의 주제는 “OIDC가 좋다”가 아니다. 이미 OIDC를 쓰는 팀이 subject claim을 이름 계약에서 ID 계약으로 옮기는 방법이다.
2. 핵심 개념
OIDC 배포 신뢰는 세 가지 질문으로 볼 수 있다.
- 누가 발급했나?
issclaim이다. GitHub Actions OIDC의 issuer는https://token.actions.githubusercontent.com이다. - 누구에게 쓰라고 발급했나?
audclaim이다. cloud provider나 내부 STS가 “이 token은 나를 대상으로 한 token인가”를 확인한다. - 어떤 workflow 실행 주체인가?
sub와 GitHub custom claims다. repository, owner, ref, environment, workflow, reusable workflow, repository ID, owner ID 같은 정보가 여기에 들어간다.
문제는 세 번째 질문이다. 예전 subject 예시는 보통 다음처럼 읽힌다.
repo:ORG-NAME/REPO-NAME:ref:refs/heads/main
repo:ORG-NAME/REPO-NAME:environment:prod
repo:ORG-NAME/REPO-NAME:pull_request
이 형식은 사람이 읽기 좋다. 하지만 이름은 identity의 영구 식별자가 아니다. 조직 이름이 바뀌거나, 저장소가 이전되거나, 삭제된 이름을 다른 주체가 다시 만들면 “문자열로는 같은 repo”처럼 보이는 상황이 생길 수 있다. 클라우드 IAM 조건이 이 문자열만 신뢰하면, 권한은 짧게 발급되더라도 신뢰 정책 자체가 오래된 이름을 계속 믿는 문제가 남는다.
GitHub의 immutable subject claim 변화는 여기에 owner ID와 repository ID를 붙인다.
repo:octo-org@123456/octo-repo@456789:ref:refs/heads/main
이렇게 되면 사람이 보는 이름이 같아도 ID가 다르면 다른 주체다. 클라우드 trust policy는 “octo-org/octo-repo라는 이름”이 아니라 “owner ID 123456과 repository ID 456789의 그 repository”를 믿게 된다.
단, 이것은 magic switch가 아니다. GitHub changelog 기준으로 모든 기존 repository가 즉시 바뀌는 것은 아니다. 기존 repository는 명시적으로 opt-in할 수 있고, 2026년 7월 15일 이후 새 repository와 rename/transfer에는 새 형식이 자동 적용된다. GitHub Enterprise Server에는 적용되지 않는다고 명시되어 있다. 그래서 운영팀은 “우리 repo는 어떤 subject 형식을 내고 있고, cloud provider trust policy는 무엇을 검사하는가”를 직접 확인해야 한다.
3. 최신 이슈와 연결
GitHub changelog의 중요한 포인트는 세 가지다.
첫째, 기존 default sub는 mutable name 중심이었다. 예를 들어 repo:octocat/my-repo:ref:refs/heads/main 같은 조건을 AWS IAM role trust policy, GCP Workload Identity Federation attribute condition, Azure federated credential에 넣었다면, 그 문자열이 보안 경계가 된다.
둘째, 새 default subject는 immutable identifier를 포함한다. GitHub가 든 예시는 repo:octocat@123456/my-repo@456789:ref:refs/heads/main이다. 이 형식은 owner/repository 이름과 ID를 함께 보여주므로 사람이 읽을 수 있으면서도 재사용 공격에 더 강하다.
셋째, 전환에는 일정과 호환성 문제가 있다. 2026년 7월 15일 이후 만들어지는 repository와 rename/transfer는 새 형식을 사용한다. 기존 repository는 설정 UI나 API로 opt-in할 수 있고, preview endpoint로 바뀔 subject prefix를 미리 확인할 수 있다. 즉, CI/CD 담당자는 “언젠가 바뀌겠지”가 아니라 cloud trust policy를 먼저 업데이트하고 워크플로가 끊기지 않는지 검증해야 한다.
GitHub Docs의 OIDC reference도 같은 결론을 뒷받침한다. cloud provider는 aud와 sub를 함께 검증해야 하고, 신뢰 조건을 최소 하나 이상 정의해야 untrusted repository가 cloud token을 받을 수 없다. 또 repository_id, repository_owner_id, repository_visibility, workflow_ref, job_workflow_ref, environment 같은 claim을 조합해 더 세밀한 조건을 만들 수 있다.
Google Cloud의 Workload Identity Federation 문서는 GitHub Actions 연동에서 google.subject=assertion.sub를 기본 매핑으로 소개하면서, repository, repository_id, repository_owner, repository_owner_id 같은 claim을 attribute condition이나 principalSet 접근에 사용할 수 있다고 설명한다. 이 말은 중요하다. cloud provider마다 문법은 다르지만, 핵심은 “토큰 안의 어떤 claim을 실제 권한 조건으로 삼을 것인가”다.
4. 개발자 관점 해석
작은 팀에서 흔한 실수는 OIDC 전환을 secret 제거 작업으로만 보는 것이다.
permissions:
id-token: write
contents: read
이 설정을 넣고 cloud login action을 붙이면 배포는 돌아간다. 하지만 보안은 GitHub workflow 파일만으로 결정되지 않는다. 실제 권한은 cloud side trust policy가 결정한다. 그래서 OIDC 운영의 본체는 YAML보다 IAM 조건이다.
개발자 관점에서 봐야 할 판단은 네 가지다.
첫째, aud는 재사용 방지 장치다. token이 특정 cloud provider나 특정 내부 broker를 향해 발급되었는지 확인한다. audience를 넓게 두면 한 곳에서 받은 token이 다른 곳에서 받아들여질 여지가 생긴다.
둘째, sub는 주체 경계다. “어느 repository, 어느 branch, 어느 environment, 어느 event를 믿을 것인가”를 표현한다. 여기서 이름만 쓰면 rename과 namespace 재사용 리스크가 남고, ID까지 쓰면 identity 안정성이 올라간다.
셋째, environment는 승인 경계다. production 배포를 ref:refs/heads/main만으로 열어두는 것보다 environment:prod를 subject 조건에 포함하고, GitHub Environment protection rule로 reviewer나 branch rule을 거는 편이 낫다. OIDC는 cloud token 발급을 막고, Environment는 workflow 실행 단계에서 사람·정책 승인을 추가한다.
넷째, reusable workflow는 별도의 공급망 경계다. 여러 repository가 공용 deploy workflow를 호출한다면 job_workflow_ref 또는 job_workflow_sha를 조건에 넣을 수 있는지 확인해야 한다. 배포 권한은 앱 repo뿐 아니라 “어떤 workflow 파일이 권한을 요청했는가”에도 의존한다.
따라서 좋은 trust policy는 대략 이런 방향을 가진다.
issuer == GitHub Actions OIDC
AND audience == 우리 cloud/provider
AND subject == owner_id/repo_id가 포함된 production subject
AND ref 또는 environment == 허용된 배포 경계
AND reusable workflow == 승인된 workflow ref 또는 sha
모든 provider가 같은 claim 조합을 같은 방식으로 지원하지는 않는다. 그래서 운영 문서에는 provider별 최종 조건 문자열과 예외를 남겨야 한다.
5. 내 프로젝트에 적용할 체크포인트
오늘 바로 점검할 목록이다.
- cloud provider의 trust policy가 GitHub OIDC issuer를 명시적으로 검증하는가?
-
aud가 기본값으로 넓게 열려 있지 않고, provider 또는 배포 broker에 맞게 제한되어 있는가? -
sub조건이 단순repo:org/repo:*처럼 너무 넓지 않은가? - production 배포는
environment:prod또는 명확한 branch/tag 조건으로 제한되어 있는가? - 기존 repository가 GitHub immutable subject claim opt-in 대상인지 확인했는가?
- opt-in 전 preview endpoint 또는 설정 UI로 새 subject prefix를 확인했는가?
- cloud trust policy에 owner ID/repository ID 기반 조건을 반영할 계획이 있는가?
- repository rename, transfer, archive, delete/recreate가 발생했을 때 IAM 조건을 검토하는 운영 절차가 있는가?
- reusable workflow를 쓴다면
job_workflow_ref또는 해당 provider가 지원하는 동등 조건을 검토했는가? - 배포 실패 시 “OIDC token 발급 실패”와 “cloud STS 교환 실패”를 구분해 로그에 남기는가?
특히 migration 순서가 중요하다. 먼저 현재 workflow에서 실제 OIDC claim을 안전한 디버그 job으로 확인한다. 그 다음 cloud policy에 새 조건을 추가하거나 병행 허용한다. 이후 GitHub repository 또는 organization에서 immutable subject claim을 opt-in한다. 마지막으로 오래된 name-only 조건을 제거한다. 순서를 반대로 하면 production 배포가 갑자기 막힐 수 있다.
6. 오늘 10분 액션
10분 동안 “내 배포 권한이 이름을 믿고 있는지”만 확인해보자.
- GitHub Actions workflow에서 OIDC를 쓰는 job을 찾는다.
permissions:
id-token: write
- cloud provider의 trust policy에서
sub조건을 찾는다.
repo:my-org/my-repo:ref:refs/heads/main
repo:my-org/my-repo:environment:prod
- 조건이 owner/repository name만 보고 있다면 메모를 남긴다.
TODO: GitHub immutable subject claim 전환 검토
- 현재 subject: repo:my-org/my-repo:environment:prod
- 필요한 확인: repository_id, repository_owner_id, 새 subject prefix
- 영향 범위: production deploy role, staging deploy role, artifact publish role
-
GCP를 쓴다면 Workload Identity Federation attribute mapping에서
repository_id,repository_owner_id를 매핑하거나 condition에 쓸 수 있는지 확인한다. AWS/Azure를 쓴다면 해당 provider의 OIDC trust condition에서 새sub문자열 또는 ID claim을 어떻게 표현할 수 있는지 확인한다. -
팀 문서에 한 문장을 추가한다.
배포 OIDC trust policy는 repository 이름만 신뢰하지 않고, 가능한 경우 immutable owner/repository ID가 포함된 subject 또는 ID claim을 사용한다.
오늘 목표는 전환 완료가 아니다. 우리 배포 권한이 “이름”에 묶여 있는지 “식별자”에 묶여 있는지 눈으로 확인하는 것이다.
7. 더 볼 자료
- GitHub Changelog: Immutable subject claims for GitHub Actions OIDC tokens: 2026년 7월 15일 전환 일정, opt-in, 새 subject 예시를 확인한다.
- GitHub Docs: OpenID Connect: GitHub Actions OIDC가 장기 secret 없이 짧은 수명 token을 교환하는 기본 흐름을 복습한다.
- GitHub Docs: OpenID Connect reference:
aud,sub,repository_id,repository_owner_id,job_workflow_ref같은 claim과 subject 형식을 확인한다. - Google Cloud IAM: Workload Identity Federation with deployment pipelines: GitHub OIDC claim을 GCP attribute로 매핑하고 조건에 쓰는 방식을 확인한다.
중복 회피 메모
로컬 content/generated와 Supabase의 최근 infra_dev 글을 확인했다. 2026-06-09에는 장기 배포 secret을 OIDC와 서명 URL로 줄이는 글이 있었고, 2026-06-23에는 Vercel custom audience를 통해 token replay를 줄이는 글이 있었다. 이번 글은 OIDC 일반론이나 audience 제한이 아니라, GitHub Actions OIDC의 2026년 immutable subject claim 변화에 맞춰 cloud trust policy가 mutable repository name 대신 owner/repository ID가 포함된 subject를 신뢰하도록 바꾸는 마이그레이션 관점에 집중한다.
핵심 출처
로그인하면 이 글을 북마크하고, 나만 보는 한 줄 메모를 남길 수 있어요.
댓글 0
최신순 ▾혹시 이 글을 읽는 동료 개발자가 있다면, GitHub으로 로그인하고 한 줄 흔적을 남겨줘요. (스팸 방지용 로그인이에요)