GitHub Actions 실행 보호 경계 설계
이 글에서 먼저 가져갈 세 가지
새 실행 보호 기능을 넓은 차단 규칙으로 바로 적용하지 않고, 중요한 워크플로의 실행 경계를 먼저 확인하는 방법을 다룬다.
- 01실행 주체와 시작 이벤트를 함께 본다
행위자 규칙과 이벤트 규칙은 워크플로가 실행되기 전에 함께 평가된다. 본문 1절
- 02배포 경로를 따로 보호한다
워크플로 파일별로 다른 정책을 적용할 수 있어 일반 CI와 민감한 자동화를 분리할 수 있다. 본문 2절
- 03평가 결과를 보고 활성화한다
평가 모드의 예상 차단 기록은 정책의 영향과 예외를 검토하는 자료다. 본문 3·4절
1. 워크플로 권한과 실행 권한은 같은 질문이 아니다
CI/CD 보안을 논의할 때는 대개 토큰 권한, 시크릿, 서드파티 액션 버전처럼 워크플로 안에서 무엇을 할 수 있는지에 시선이 간다. 이 확인은 여전히 필요하다. 그러나 그보다 앞에는 “누가 이 워크플로를 시작할 수 있는가”, “어떤 이벤트가 이 실행을 만들 수 있는가”라는 질문이 있다. 권한이 좁은 워크플로라도 신뢰하지 않는 요청이 반복해서 실행을 만들 수 있다면 운영 비용과 공격 표면은 달라진다.
GitHub는 2026년 9월 17일 GitHub Actions의 Workflow execution protections를 일반 제공했다. 이 기능은 워크플로를 시작할 수 있는 행위자와 허용할 이벤트를 정하는 허용 목록이다. 공식 발표에 따르면 행위자 규칙은 ‘누가’를, 이벤트 규칙은 ‘무엇이 시작할 수 있는가’를 다루며, Actions는 실행 전에 두 규칙을 평가한다. 이것은 YAML 속 permissions를 대체하는 기능이 아니라, 실행 진입점에 별도의 정책 경계를 두는 방식이다.
GitHub Docs는 이 경계가 pullrequest_target을 제한하거나, 신뢰하지 않는 주체의 수동 실행을 막고, 개별 워크플로 설정 오류보다 상위의 중앙 정책을 적용하는 데 쓰일 수 있다고 설명한다. 그렇다고 모든 이벤트를 끄는 것이 곧 좋은 정책은 아니다. 공개 저장소의 기여 검증, 릴리스 자동화, 의존성 봇, 운영자의 긴급 수동 실행은 서로 다른 신뢰 모델과 업무 목적을 가진다. 먼저 실행 경로를 나누고, 그 뒤에 보호 규칙을 연결해야 한다.
2. 한 저장소 안에서도 워크플로는 같은 위험이 아니다
이번 일반 제공에는 정책을 저장소 전체가 아니라 특정 워크플로 파일에 적용하는 기능이 포함됐다. GitHub의 예시는 deploy.yml은 지정된 팀으로 제한하면서 일반 CI 워크플로는 모든 기여자에게 열어 둘 수 있다고 설명한다. 이 차이는 실무에서 꽤 중요하다. 저장소의 모든 작업을 동일한 규칙으로 잠그면, 민감하지 않은 검사까지 운영 승인이 필요해질 수 있다. 반대로 배포 경로를 일반 PR 검사와 똑같이 열어 두면 실행 권한의 구분이 흐려진다.
먼저 .github/workflows/ 아래의 파일을 이름이 아니라 실행 효과로 분류해 보자. 외부 입력을 검사하는 CI, 패키지를 발행하는 릴리스, 인프라를 바꾸는 배포, 저장소를 정리하는 유지보수 자동화는 같은 워크플로 엔진을 쓰지만 결과의 되돌리기 어려움은 다르다. 여기서 분류는 위험 점수를 만드는 절차가 아니다. 어느 경로에 행위자 제한이 필요한지, 어느 이벤트를 허용해야 하는지, 예외가 생기면 누가 검토할지를 팀이 합의하기 위한 입력이다.
허용된 행위자와 이벤트만 실행할 수 있게 해도, 시크릿 노출·권한 과다·신뢰하지 않는 코드 실행 가능성은 워크플로 정의와 이벤트 문맥에서 따로 검토해야 한다.
3. 평가 모드를 먼저 운영 자료로 쓰기
GitHub은 평가 모드에서 어떤 실행이 차단될지를 실제 강제 전에 볼 수 있다고 안내한다. 정책 통찰은 활성 정책에서 차단된 실행과 평가 정책에서 차단될 실행을 확인하는 데 쓰인다. 따라서 새 정책을 만들 때 중요한 질문은 “이 정책이 안전한가” 하나가 아니라, “어떤 정상 작업도 함께 막히는가”, “그 작업은 경로별 예외가 필요한가”, “예외를 계속 둘 이유가 남아 있는가”가 된다.
아래 양식은 GitHub의 공식 구성 파일이나 보안 인증 기준이 아닙니다. 일반 제공된 기능을 팀의 배포·CI 경계에 맞춰 검토하기 위한 편집부 제안입니다.
# Actions 실행 보호 검토 카드
- **보호 대상 경로**: [예: 배포, 릴리스, 일반 CI]
- **이 경로가 만드는 결과**: [변경 가능한 시스템·데이터·아티팩트]
- **허용할 행위자**: [역할, 팀, 봇, 앱과 그 이유]
- **허용할 이벤트**: [push, pull_request, workflow_dispatch 등과 사용 목적]
- **평가 모드에서 본 영향**: [예상 차단 실행, 정상 업무인지 여부, 확인 근거]
- **결정**: [활성화, 경로 축소, 예외 검토, 기존 규칙 유지]
- **재검토 조건**: [새 워크플로, 권한 변경, 배포 대상 변경, 담당자]
이 카드에 “차단된 실행 수” 같은 숫자를 억지로 넣을 필요는 없다. 어떤 워크플로가 어떤 사건으로 실행됐는지, 그 실행이 제품·운영·보안 관점에서 필요한지, 예외가 넓은 범위로 퍼지지 않는지를 확인하는 것이 더 중요하다. 평가 결과에 정상적인 의존성 봇 작업이 보였다면 봇의 신원을 허용 목록에 넣을지, 더 좁은 워크플로 경로로 보호 범위를 조정할지, 그 자동화 자체를 다시 설계할지를 검토한다. 이 판단은 기능이 대신해 주지 않는다.
4. pullrequesttarget은 별도의 전환 계획이 필요하다
공식 발표은 pullrequesttarget이 기본 저장소 문맥의 시크릿에 접근할 수 있으며, 포크에서 온 코드를 실행하면 파이프라인 오염과 시크릿 유출로 이어질 수 있다고 경고한다. GitHub은 적용 가능한 이벤트 정책이 없는 공개 저장소에서 이 이벤트를 막는 기본 규칙을 도입했고, 관련 공개 저장소에는 2026년 11월 2일부터 기본 규칙을 자동 강제한다고 공지했다. 따라서 이 이벤트를 쓰는 공개 저장소라면 나중에 갑자기 실패한 실행을 해석하기보다, 현재 어떤 워크플로가 의존하는지 먼저 확인하는 편이 낫다.
이때 정답은 “무조건 허용”이나 “즉시 전면 차단” 둘 중 하나가 아니다. 사용 중인 워크플로 파일, 체크아웃하는 코드의 출처, 필요한 시크릿과 권한, 대체 이벤트, 실행 주체를 한 경로씩 확인해야 한다. 필요성이 확인되면 특정 워크플로 파일만 명시적으로 허용할 수 있는지 검토하고, 필요하지 않다면 더 좁은 이벤트 모델로 옮기는 계획을 남긴다. GitHub의 기본 규칙은 공개 저장소를 대상으로 한다는 범위를 벗어나 모든 저장소의 보안 상태를 보장하지 않는다.
일반 CI, 릴리스, 배포, 유지보수 자동화를 나누고 각 경로가 바꾸는 대상을 적는다.
각 경로에 필요한 사람·팀·앱·봇과 시작 이벤트만 남기고, 근거 없는 넓은 허용을 피한다.
예상 차단이 실제 업무인지와 경로·주체를 확인해 예외 또는 설계 변경의 근거로 삼는다.
정책을 켠 이유, 남은 예외, 다음 점검 조건을 남겨 워크플로 변화에 맞춰 다시 검토한다.
▲ 실제 정책 통찰 화면이 아니라, 차단 전에 워크플로 경로별 영향을 관찰하고 결정하는 흐름을 보여 주는 편집 이미지입니다.
5. 정책을 코드처럼 다루되, 자동 적용을 서두르지 않기
GitHub은 REST API로 엔터프라이즈·조직·저장소 수준의 실행 보호를 관리할 수 있다고 설명한다. 여러 저장소에 같은 원칙을 적용해야 한다면 정책을 코드와 같이 관리하는 선택지는 일관성을 높일 수 있다. 그러나 API로 만들 수 있다는 사실만으로 일괄 적용이 안전해지는 것은 아니다. 저장소마다 배포 경로, 외부 기여 방식, 봇, 레거시 이벤트 의존성이 다르면 같은 정책도 다른 차단 결과를 만든다.
그래서 공통 원칙과 저장소별 예외를 한 문서에 섞기보다, 상위에는 바뀌기 어려운 최소 경계를 두고 하위에는 경로·주체·이벤트에 맞춘 제한을 남기는 편이 이해하기 쉽다. GitHub Docs도 하나의 큰 정책보다 여러 개의 명확한 정책을 계층별로 적용하는 방식을 권한다. 이는 제품이 자동으로 만든 조직 설계가 아니라, 기능의 범위와 실제 워크플로를 맞추기 위한 운영 제안이다.
정책을 검토하는 사람과 워크플로를 유지하는 사람이 다를 때는 특히 연결 문장이 필요하다. 예를 들어 배포 경로를 제한했다면, 어떤 팀 또는 앱이 허용되어야 하는지뿐 아니라 그 주체가 더 이상 배포 책임을 갖지 않게 될 때 누가 정책을 갱신하는지도 적는다. 특정 이벤트를 허용했다면, 그 이벤트가 새 워크플로 파일에 추가됐을 때 기존 정책이 기대한 경로에만 적용되는지도 점검한다. 정책 통찰에 보이는 실행 기록은 이러한 변경을 발견하는 자료가 될 수 있지만, 기록을 읽는 담당자와 판단 기준이 없으면 경고 목록으로만 남는다.
또한 예외를 남길 때는 ‘기존 자동화라서’라는 이유보다 해당 예외가 어떤 사용자·배포·검증 흐름을 지키는지 써 두는 편이 좋다. 예외가 필요했던 당시의 코드 체크아웃 방식, 사용한 시크릿의 범위, 대체할 수 없는 이벤트를 함께 연결하면 나중에 예외를 줄일 기회도 찾기 쉽다. 반대로 세부 시크릿 값이나 내부 인프라 주소를 정책 설명에 적어서는 안 된다. 정책 문서는 실행 권한의 이유를 설명하는 곳이지, 민감한 접근 정보를 복제하는 저장소가 아니다.
조직의 규모와 관계없이 변경은 작게 시작할 수 있다. 예를 들어 공개 기여가 많은 저장소라면 일반 PR 검사는 계속 열어 두고, 배포를 만드는 한 파일만 평가 모드의 대상으로 삼는다. 내부 저장소라면 수동 실행이 실제로 필요한 운영 절차인지부터 확인할 수 있다. 이 사례들은 권장 설정이나 효과 측정이 아니라, 넓은 규칙을 한 번에 강제하기 전에 경계가 가장 분명한 경로부터 읽어 보자는 설명을 위한 예시다. 각 조직은 자신이 사용하는 요금제, 권한 모델, 저장소 가시성, 사고 대응 절차에 맞춰 적용 가능 여부를 판단해야 한다.
첫 단계는 정책을 많이 만드는 일이 아니다. 배포 또는 릴리스 워크플로 하나를 골라, 누가 어떤 이벤트로 실행할 수 있어야 하는지와 평가 모드에서 확인할 영향을 한 장의 카드로 남겨 보자. 결과가 기대와 다르면 활성화를 미루고 경로나 이벤트 모델을 다시 본다. 결과가 맞더라도 시크릿, 액션 버전, 코드 체크아웃 같은 기존 보안 검토는 계속해야 한다. 실행 보호는 실행 경계를 선명하게 만드는 도구이지, CI/CD 보안 전체를 끝내는 버튼은 아니다.
출처와 적용 범위
- GitHub Changelog — Workflow execution protections 일반 제공 — 일반 제공 범위, 행위자·이벤트 규칙, 파일별 정책, 평가 모드, 정책 통찰, 공개 저장소의
pullrequest_target기본 규칙과 공지 일정을 확인했다. - GitHub Docs — About Actions policies, Controlling workflow execution, Actions policies REST API — 실행 보호의 적용 범위, 허용 목록, 계층화, 행위자·이벤트 규칙, 평가 모드·통찰 및 API 관리 범위를 확인했다. 이 글의 검토 카드는 공식 정책 파일이나 인증 기준이 아닌 편집부 제안이다.
원문 참고 자료
이 글의 사실 확인과 추가 읽기를 위한 원문입니다. GitHub Changelog — Workflow execution protections
댓글 0