짧은 답: GitHub Secrets에서 장기 클라우드 키를 제거한 것만으로는 충분하지 않습니다. 의도한 배포 실행만 역할을 얻는지, 허용 1건과 거부 4건을 격리된 테스트 역할과 감사 기록으로 확인해야 합니다.
GitHub Actions OIDC를 도입한 뒤 가장 중요한 질문은 “키를 없앴는가?”가 아니라 “정확히 어떤 실행이 클라우드 역할을 얻을 수 있는가?”입니다. 이 글에서는 issuer, audience, 저장소·subject, ref 또는 environment, workflow의 다섯 조건을 한 장의 테스트 카드로 기록하고, 실제 배포 전에 신뢰 경계를 확인하는 방법을 정리합니다.

핵심 요약
- GitHub Actions OIDC는 장기 클라우드 자격 증명을 저장하는 대신, 실행 시점에 짧은 수명의 토큰을 교환할 수 있게 합니다.
- 워크플로의
id-token권한과 클라우드 측 신뢰 정책은 서로 다른 경계입니다. 둘 다 의도한 실행 맥락으로 제한해야 합니다. - 프로덕션 역할로 시험하지 말고, 최소 권한의 격리된 테스트 역할에서 허용 1건과 거부 4건을 먼저 실행합니다.
- 성공 화면만 보지 말고 GitHub run URL, 토큰 조건, 클라우드 감사 기록을 하나의 수용 패킷으로 연결합니다.
- 근거나 조건이 비어 있으면 장기 키를 다시 만들지 말고 해당 역할의 신뢰를 닫은 뒤 배포를 보류합니다.
장기 키를 지웠는데도, 왜 검증이 더 필요할까요?
장기 키는 유출되었을 때 회수와 추적이 어려운 문제가 있습니다. GitHub Actions의 OIDC는 워크플로가 클라우드 제공자와 직접 토큰을 교환하도록 하여, 저장소에 장기 자격 증명을 두지 않는 선택지를 제공합니다. 다만 여기서 끝나면 안 됩니다. 토큰 교환을 허용하는 클라우드 역할이 너무 넓게 열려 있으면, 의도하지 않은 branch·저장소·워크플로도 같은 역할을 얻을 수 있기 때문입니다.
따라서 도입 판단은 두 질문으로 나누는 편이 안전합니다.
질문 1. 장기 키가 더 이상 배포 경로에 남아 있지 않은가?
질문 2. 허용된 저장소·배포 맥락·워크플로만 해당 역할을 얻는가?
첫 질문이 저장 위치와 회수의 문제라면, 둘째 질문은 권한 범위와 운영 증거의 문제입니다. 이 글의 테스트 카드는 둘째 질문을 검증하기 위한 장치입니다.
배포 신뢰정책을 보는 5개 claim 테스트 카드
OIDC 토큰과 제공자별 신뢰 정책에서 실제로 쓸 수 있는 조건은 구성에 따라 다릅니다. 아래 다섯 칸은 특정 클라우드의 정책 문법이 아니라, 팀이 무엇을 확인해야 하는지 정리하는 운영 카드입니다. 지원 여부와 실제 값은 배포 전에 GitHub 및 사용하는 클라우드의 공식 문서로 다시 확인하세요.

1. Issuer
토큰을 발급한 주체가 팀이 신뢰하는 GitHub Actions 발급자인지 확인합니다. 다른 issuer를 허용하는 예외가 섞이지 않도록 기록합니다.
2. Audience
토큰의 대상이 의도한 클라우드 제공자 또는 역할 교환 경로와 맞는지 확인합니다. audience가 넓거나 예상과 다르면 교환을 중단합니다.
3. 저장소·Subject
어느 repository와 실행 주체를 허용할지 명확히 적습니다. 저장소 전체를 넓게 허용하는 대신 필요한 subject 패턴만 통과시키는지 검토합니다.
4. Ref 또는 Environment
보호된 branch, 태그, 또는 승인된 deployment environment처럼 배포 맥락을 좁힙니다. 어떤 조건을 썼는지와 이유를 change record에 남깁니다.
5. Workflow 경계
배포를 맡은 workflow 또는 재사용 workflow만 역할을 얻도록 설계합니다. 이 조건의 지원 범위는 구성에 따라 달라질 수 있으므로 실제 토큰과 문서를 함께 대조합니다.
허용 1건과 거부 4건을 실제로 실행하는 방법
테스트의 목적은 정책을 “그럴듯하게 읽는 것”이 아니라, 의도한 실행과 의도하지 않은 실행을 구분하는 증거를 남기는 것입니다. 먼저 권한이 최소화된 테스트 역할을 만들고, 아래 표의 시나리오를 조직의 위협 모델에 맞춰 실행하세요. fork를 허용하지 않는 조직이라면 fork 거부를, 환경 승인이 중요한 조직이라면 environment 조건의 거부를 우선할 수 있습니다.
| 테스트 | 실행 맥락 | 예상 결과 | 확인할 증거 | 담당 |
|---|---|---|---|---|
| 허용 1건 | 승인된 저장소 + 보호 branch + 승인된 environment의 deploy workflow | 테스트 역할 교환 허용 | run URL, subject/ref 또는 environment 값, 클라우드 principal·session 기록 | 배포 담당 |
| 거부 1건 | PR ref 실행 | 역할 교환 거부 | 실패 run, 거부 응답, 감사 기록의 부재 또는 거부 흔적 | 배포 담당 |
| 거부 2건 | fork에서 온 실행 | 역할 교환 거부 | 저장소·subject 대조, 실패 run | 저장소 관리자 |
| 거부 3건 | 보호되지 않은 다른 branch | 역할 교환 거부 | ref 대조, 실패 run | 배포 담당 |
| 거부 4건 | 다른 repository 또는 비배포 workflow | 역할 교환 거부 | repository/workflow 경계 대조, 실패 run | 권한 검토자 |
표는 모바일에서 좌우로 넘겨 확인할 수 있습니다.
재현 예시: 가장 작은 테스트부터 시작하세요
- 프로덕션 역할과 분리된 테스트 역할을 준비하고, 읽기 전용 또는 무해한 단일 동작만 허용합니다.
- 승인된 deploy workflow에서 역할 교환을 시도합니다. 성공했다면 run URL과 클라우드 측 principal 또는 session 기록을 저장합니다.
- PR, fork, 다른 branch, 다른 repository 또는 다른 workflow 중 네 가지 경로를 선택해 같은 교환을 시도합니다.
- 각 거부가 실제로 정책 조건 때문에 일어났는지 확인합니다. 단순한 YAML 오류나 네트워크 오류는 권한 거부의 증거가 아닙니다.
- 다섯 실행의 결과를 같은 change record에 묶고, 검토자가 다시 따라갈 수 있게 링크와 시각을 남깁니다.
GitHub 실행 기록과 클라우드 감사 기록을 한 묶음으로 남기세요
권한 검증의 신뢰성은 설정 스크린샷이 아니라 서로 대조 가능한 기록에서 나옵니다. GitHub 쪽에서는 어떤 workflow·ref·environment에서 실행됐는지, 클라우드 쪽에서는 어떤 identity provider와 principal 또는 session이 역할을 얻었는지 확인합니다. 두 기록이 같은 허용 run을 가리켜야 합니다.

배포 수용 패킷 체크리스트
- 테스트 역할의 이름과 최소 권한 범위를 기록했나요?
id-token권한과 클라우드 측 신뢰 조건을 같은 변경 기록에 남겼나요?- 허용 run의 저장소·ref·environment·workflow 맥락이 예상과 일치하나요?
- 조직에 의미 있는 거부 네 경로를 실제로 실행했나요?
- 각 run URL을 클라우드 감사 기록의 principal 또는 session 증거와 연결했나요?
- 마지막 검증 시각, 책임자, 비상 회수 절차를 적었나요?
이 방식은 비용과 운영 부담도 줄여줍니다. 장기 키 교체와 유출 대응에 의존하기보다, 변경 때마다 작은 테스트 역할에서 경계를 확인할 수 있기 때문입니다. 다만 기록을 남길 권한, 감사 로그 보존 기간, 검토 책임자가 빠지면 기술적으로는 동작해도 운영상 신뢰하기 어렵습니다.
다음 조건에서는 배포를 멈추고 신뢰를 닫으세요
OIDC 전환 중 가장 위험한 실수는 증거가 부족할 때 장기 access key를 “잠시만” 다시 발급하는 것입니다. 이 우회는 새 경로의 검증을 늦추고, 회수해야 할 비밀을 다시 늘립니다. 아래 중 하나라도 해당하면 역할 신뢰를 닫고 원인을 확인하는 편이 낫습니다.
- 허용 run의 저장소·ref·environment·workflow 값 중 하나를 확인할 수 없습니다.
- 거부 테스트가 정책 거부가 아니라 구성 오류로만 끝나 구분 증거가 없습니다.
- 클라우드 감사 기록에서 교환한 principal 또는 session을 run과 연결할 수 없습니다.
- 테스트 역할과 프로덕션 역할이 분리되지 않아 거부 시험이 실제 자원에 영향을 줄 수 있습니다.
- 공유 workflow, fork 정책, environment 보호 규칙이 바뀌었는데 테스트 카드를 갱신하지 않았습니다.
회수 절차는 단순해야 합니다. 대상 역할의 신뢰 조건을 닫고, 해당 배포를 보류하고, 마지막으로 통과한 수용 패킷과 변경 사항을 비교하세요. 그 다음 최소 권한 테스트 역할에서 다섯 실행을 다시 확인하면 됩니다.
다음으로 함께 보면 좋은 글
자주 묻는 질문
OIDC를 쓰면 GitHub Secrets의 모든 비밀을 없앨 수 있나요?
그렇지는 않습니다. OIDC는 주로 클라우드 자격 증명 교환에 쓰입니다. 다른 서비스 토큰이나 애플리케이션 비밀은 별도의 회수·권한 분리·보관 정책이 필요합니다.
PR과 fork 거부 테스트는 프로덕션 역할로 해도 되나요?
권장하지 않습니다. 최소 권한의 격리된 테스트 역할에서 먼저 실행하세요. 거부 시험이 실수로 통과하더라도 실제 자원에 영향을 주지 않게 설계해야 합니다.
다섯 claim을 모두 정책에 넣어야 하나요?
아닙니다. 제공자와 workflow 구성에 따라 사용할 수 있는 조건이 다릅니다. 핵심은 지원되는 조건으로 필요한 실행 맥락을 가장 좁게 표현하고, 실제 토큰과 감사 기록으로 확인하는 것입니다.
감사 기록이 없으면 무엇을 먼저 해야 하나요?
새 배포 권한을 넓히지 말고 역할 신뢰를 닫으세요. 이후 로그 수집 경로와 보존 기간을 확인한 뒤, 테스트 역할에서 허용·거부 실행을 다시 수행하는 편이 안전합니다.
AWS 예시를 다른 클라우드에 그대로 적용해도 되나요?
안 됩니다. identity provider와 신뢰 정책이라는 역할은 비슷해도 정책 문법과 지원 조건은 다릅니다. 사용하는 제공자의 공식 문서와 실제 실행 기록으로 별도 검증하세요.
참고 자료
- GitHub Actions — OpenID Connect: GitHub Actions에서 OIDC 토큰으로 클라우드 제공자와 짧은 수명의 자격 증명을 교환하는 기본 개념을 설명합니다.
- GitHub Actions — Configuring OpenID Connect in cloud providers:
id-token권한과 클라우드 측 조건 제한을 함께 구성하는 경계를 설명합니다. - AWS IAM — Create OpenID Connect identity providers: AWS에서 OIDC identity provider와 역할 신뢰 정책을 구성하는 방법을 다룹니다. AWS의 구체 문법은 다른 클라우드에 그대로 적용하지 마세요.
이 글이 마음에 드세요?
FLOWIT on YouTube
영상으로도 FLOWIT을 이어서 보세요
AI 자동화, Claude Code, n8n, 데이터 분석 흐름을 블로그와 영상으로 함께 정리하고 있습니다.
AI 에이전트가 같은 일을 두 번 실행했다면? 외부 행동을 묶는 7칸 action ID 계약
AI 에이전트 장기 메모리, 많이 저장할수록 똑똑해질까?
AI 에이전트 정기 작업, ‘성공’인데 결과가 없다면?