GitHub push rules path exceptions 운영법: 보안 규칙을 풀지 않고 예외를 관리하는 방법
요약: GitHub rulesets의 push rules가 path exceptions를 지원하기 시작했다. 특정 파일 경로나 패턴만 예외로 두고 나머지 범위에는 규칙을 유지할 수 있는 기능이다. 실무에서는 ‘보안 규칙을 엄격하게 걸면 개발이 막힌다’와 ‘예외를 허용하면 규칙이 무너진다’ 사이에서 자주 흔들린다. path exceptions는 이 문제를 더 작고 감사 가능한 단위로 풀 수 있게 해준다.
어떤 기능인가
GitHub는 2026년 8월 25일 rulesets의 push rules에서 path exceptions를 public preview로 제공한다고 밝혔다. 이제 특정 push rule을 저장소 전체 또는 지정 범위에 적용하되, 일부 파일 경로만 예외로 둘 수 있다. 현재 예외를 지원하는 규칙은 두 가지다. 하나는 Restrict file paths이고, 다른 하나는 Restrict file size다. 예를 들어 저장소 전체에서 JAR 파일 커밋을 막으면서 **/gradle/wrapper/*.jar만 허용하거나, 파일 크기 제한을 걸면서 이미 큰 파일이 있는 일부 경로만 예외 처리할 수 있다.
이 기능은 작아 보이지만 조직 운영에서는 중요하다. 보안 규칙은 대부분 예외 때문에 망가진다. 처음에는 강하게 막다가, 한 팀이 빌드 도구 때문에 예외를 요청하고, 다른 팀이 레거시 파일 때문에 예외를 요청한다. GitHub 밖에서 스크립트로 우회하거나 관리자에게 임시 해제를 부탁하다 보면 결국 규칙이 느슨해진다. path exceptions는 예외를 규칙 안으로 다시 끌어온다.
예외 관리는 보안의 일부다
많은 팀이 보안 규칙을 만들 때 ‘막을 것’만 정의한다. 하지만 실제 운영에서는 ‘왜 예외를 허용하는지’가 더 중요하다. 예외가 없으면 개발이 막히고, 예외가 너무 넓으면 규칙이 사라진다. 따라서 좋은 규칙은 기본 차단과 좁은 예외를 함께 갖는다.
예를 들어 대용량 파일 제한을 걸었다고 하자. 새 이미지, 모델 파일, 빌드 산출물이 계속 저장소에 들어오면 clone 속도가 느려지고 CI 시간이 늘어난다. 그래서 50MB 이상 파일을 막는다. 그런데 기존 레거시 테스트 fixture 하나가 이미 80MB이고 당장 제거할 수 없다. 이때 규칙 전체를 끄는 대신 해당 fixture 경로만 예외로 두면 신규 대용량 파일 유입은 막으면서 레거시 이전은 시간을 두고 진행할 수 있다.
적용 전 inventory부터 한다
path exceptions를 바로 켜기 전에 먼저 저장소 inventory를 봐야 한다. 어떤 파일 확장자가 많은지, 어떤 파일이 큰지, 빌드 도구가 요구하는 예외가 무엇인지 확인한다. Git 명령으로도 충분히 시작할 수 있다. 큰 파일은 git rev-list --objects --all과 git cat-file을 조합해 찾을 수 있고, 현재 워킹트리에서는 find로 크기 기준을 볼 수 있다. 확장자별 분포는 간단한 스크립트로 뽑으면 된다.
이 과정을 건너뛰면 규칙이 너무 넓어진다. 예를 들어 “binary 파일 금지”를 걸고 나서 build wrapper, test fixture, generated asset이 모두 걸리면 개발자는 규칙을 신뢰하지 않는다. 먼저 정상적으로 필요한 파일과 제거해야 할 파일을 분리해야 한다.
예외 패턴은 좁게 써야 한다
path exception에서 가장 흔한 실수는 glob을 너무 넓게 잡는 것이다. **/*.jar를 예외로 두면 사실상 JAR 금지 규칙은 사라진다. 반면 **/gradle/wrapper/*.jar처럼 목적이 분명한 경로만 허용하면 예외의 의미가 유지된다. 마찬가지로 assets/** 전체를 큰 파일 예외로 두는 것보다 tests/fixtures/legacy/*.bin처럼 좁게 두는 편이 낫다.
예외 패턴을 정할 때는 세 가지 질문을 붙인다. 첫째, 이 파일이 저장소에 반드시 있어야 하는가. 둘째, 다른 저장소나 artifact storage, Git LFS로 옮길 수 없는가. 셋째, 이 예외는 언제 제거할 수 있는가. 답을 못 적는 예외는 대개 영구 부채가 된다.
rollout은 차단보다 관찰부터
규칙을 처음 도입할 때 바로 hard block을 걸면 배포 직전이나 릴리즈 브랜치에서 사고가 날 수 있다. 가능하다면 먼저 dry-run이나 감사 로그 방식으로 영향 범위를 확인한다. GitHub 기능이 제공하는 범위 안에서 preview를 보고, 팀별로 걸릴 push 사례를 수집한 뒤 예외를 정리한다.
운영 순서는 다음이 좋다. 먼저 repository inventory를 만든다. 다음으로 금지 규칙 후보와 예외 후보를 PR로 공유한다. 그 다음 1~2주 동안 위반 후보를 모니터링한다. 마지막으로 ruleset을 적용하고, 예외 요청은 이슈 템플릿으로 받는다. 이렇게 하면 규칙이 갑자기 떨어진 장애처럼 느껴지지 않는다.
감사 로그와 소유자가 필요하다
예외는 생성보다 제거가 어렵다. 따라서 각 예외마다 owner와 review date가 필요하다. owner는 해당 예외가 왜 필요한지 설명할 수 있는 팀이나 사람이다. review date는 이 예외를 다시 볼 날짜다. 분기마다 path exceptions를 검토해 제거 가능한 항목을 지우면 규칙이 오래 살아남는다.
특히 보안 advisory, secret scanning, dependency review와 연결되는 저장소라면 예외 변경 자체도 리뷰 대상이어야 한다. ruleset 변경 PR이나 내부 승인 흐름을 만들어 누가 왜 예외를 추가했는지 남겨야 한다.
실행 체크리스트
- 저장소의 큰 파일, 바이너리, generated asset inventory를 먼저 만든다.
- 금지 규칙과 예외 후보를 PR 또는 문서로 공유하고 영향 팀을 확인한다.
- 예외 glob은 가능한 한 좁게 작성한다.
**/*.jar보다**/gradle/wrapper/*.jar가 낫다. - 각 예외에 owner, 사유, 제거 조건, review date를 붙인다.
- 신규 예외 요청은 이슈 템플릿으로 받고 대체 수단(Git LFS, artifact storage)을 먼저 검토한다.
- 분기마다 path exceptions를 감사하고 불필요한 예외를 제거한다.
- 출처: GitHub Changelog, Push rules in rulesets now support path exceptions, 2026-08-25.