먼저 답부터 말씀드리면, 여러 저장소의 CI를 재사용 워크플로로 중앙화하는 일은 YAML를 줄이는 작업이 아니라 권한과 비밀값, 변경 책임이 저장소 경계를 넘어가는 운영 변경입니다. caller·called 경계 카드 6칸이 모두 채워졌을 때만 중앙화하고, 하나라도 불명확하면 한 저장소 파일럿 또는 보류를 선택하시는 편이 안전합니다.

핵심 요약
- 재사용 워크플로는 caller가 입력값과 비밀값을 called workflow로 전달하는 구조이므로, 공통화 전에 전달 계약을 문서로 남겨야 합니다.
- 최소 권한은 caller와 called workflow를 따로 확인해야 합니다. called 쪽 설정만 좁혀도 caller가 넓은 권한을 가진 채라면 판단은 끝나지 않습니다.
secrets: inherit는 편의를 위한 기본값이 아니라 소비 범위와 사유를 설명해야 하는 선택지입니다.- 처음부터 전 저장소에 적용하지 말고, 한 저장소에서 허용 경로·거부 경로·로그·되돌리기까지 확인한 뒤 확대하십시오.
- 통과한 CI 한 번은 중앙화 승인 근거가 아닙니다. 누가 공통 workflow의 변경을 승인하고 멈출 수 있는지도 함께 정해야 합니다.
목차
- 왜 YAML 정리가 권한 설계가 되는가
- caller·called 책임을 나누는 법
- 중앙화 판단을 위한 6칸 카드
- 한 저장소 파일럿의 확인 순서
- 즉시 보류해야 하는 실패 조건
- 자주 묻는 질문
왜 YAML 정리가 권한 설계가 되는가
AI 코딩 에이전트가 여러 저장소에 비슷하게 있는 빌드·테스트·배포 YAML를 한 곳의 reusable workflow로 묶자고 제안하는 장면은 자연스럽습니다. 중복을 줄이면 수정 지점이 하나로 모이고, 팀도 공통 규칙을 유지하기 쉬워 보입니다.
다만 호출 저장소와 공통 workflow의 연결에는 단순한 단계 재사용보다 많은 것이 들어갑니다. GitHub의 재사용 워크플로 문서는 called workflow가 입력값과 named secret을 선언하고 caller가 이를 전달하는 방식을 설명합니다. 즉, 공통화는 “어떤 명령을 실행할까”뿐 아니라 “어느 저장소가 무엇을 넘기고, 누가 그것을 사용할 수 있는가”를 다시 정하는 일입니다.
가령 세 저장소가 모두 테스트만 수행한다고 해도, 한 저장소만 패키지 게시나 배포 검증을 위해 추가 권한을 요구할 수 있습니다. 그 예외를 공통 workflow에 무심코 넣으면, 테스트용 호출에도 불필요한 능력이 섞일 수 있습니다. 공통화의 단위는 YAML 파일이 아니라 동일한 권한 계약을 공유하는 작업 단위여야 합니다.
실무 판단: “같은 단계가 세 번 있으니 합치자”는 시작 신호일 뿐입니다. 각 저장소가 필요로 하는 입력, 비밀값, 토큰 권한, 환경 접근, 실패 시 영향 범위가 같은지 확인하기 전에는 중앙화 결론을 내리지 마십시오.
caller·called 책임을 나누는 법
재사용 워크플로를 안전하게 운영하려면 caller와 called workflow를 하나의 설정 덩어리로 보지 않는 것이 좋습니다. caller는 어떤 저장소·브랜치·환경에서 공통 작업을 부를지 결정하고, called workflow는 받은 계약 안에서 어떤 작업을 실행할지 결정합니다. 두 쪽이 만나는 곳에는 공동 검증이 필요합니다.

| caller 책임 | called workflow 책임 | 공통 확인 |
|---|---|---|
| 허용 저장소·브랜치·환경을 정합니다. | 선언한 입력과 비밀값만 받도록 설계합니다. | 호출 대상과 소비 범위를 목록으로 맞춥니다. |
| 작업에 필요한 최소 토큰 권한을 정합니다. | job별로 필요한 권한만 사용하도록 좁힙니다. | 권한 확대 사유와 영향 저장소를 검토합니다. |
| 참조할 workflow 버전과 변경 시점을 관리합니다. | 중첩 호출과 외부 의존성을 드러냅니다. | 고정 참조·업데이트 검토 규칙을 합의합니다. |
| 실패 시 기존 개별 workflow로 되돌릴 수 있게 둡니다. | 실패 로그와 결과물을 읽기 쉽게 남깁니다. | 허용·거부 경로의 증거를 함께 확인합니다. |
GitHub는 Secure use reference에서 GITHUB_TOKEN에 최소 권한을 부여하고 필요한 job에서만 권한을 확대하는 방식을 안내합니다. 또한 의존하는 workflow나 action의 참조를 검토 가능한 방식으로 고정하는 선택지를 설명합니다. 이는 특정 YAML 블록을 그대로 복사하라는 처방이 아니라, 각 팀이 변경 전파 범위를 통제하기 위한 기준입니다.
중앙화 판단을 위한 caller·called 경계 6칸 카드
아래 카드는 “중앙화”, “한 저장소 파일럿”, “보류” 중 하나를 고르기 위한 기록 양식입니다. 여섯 칸의 답이 모두 같은 방향을 가리킬 때만 중앙화를 검토하십시오.
1. 목적과 허용 범위
어떤 작업을 공통화하며, 어떤 저장소·브랜치·환경만 호출할 수 있는지 적습니다. “모든 CI”처럼 넓은 표현은 파일럿 범위가 아닙니다.
2. 최소 권한
caller와 called workflow에 필요한 권한을 따로 적습니다. 기본 읽기 권한으로 가능한 작업과 특정 job에서만 추가되는 권한을 구분하십시오.
3. 입력·비밀값 계약
입력값, 필요한 secret의 역할, 소비 job을 연결합니다. secrets: inherit를 쓰려면 어떤 호출자가 어떤 비밀값을 전달할 수 있는지와 왜 named secret으로 좁히기 어려운지를 설명합니다. 환경 secret에는 재사용 workflow 호출에서 별도 동작이 있을 수 있으므로 공식 문서의 환경 secret 설명을 구현 전 다시 확인하십시오.
4. 참조와 전파 규칙
공통 workflow의 버전을 어떻게 참조할지, 중첩 workflow와 외부 action 변경을 누가 검토할지 정합니다. 한 번의 수정이 몇 개 저장소에 영향을 주는지도 기록합니다.
5. 파일럿 검증과 되돌리기
한 저장소에서 정상 실행뿐 아니라 의도적으로 권한이 부족한 경로도 확인합니다. 로그에 민감한 값이 남지 않는지 보고, 문제가 생기면 기존 개별 workflow로 되돌리는 절차와 담당자를 적습니다.
6. 소유자와 승인
호출 저장소의 소유자, 공통 workflow의 소유자, 변경 승인자, 긴급 중단 권한자를 각각 정합니다. 한 사람이 모두 맡아도 역할은 분리해 기록하는 편이 좋습니다.

결론을 고르는 기준: 범위·권한·비밀값·참조·검증·소유자가 모두 명확하면 중앙화를 검토할 수 있습니다. 하나가 아직 확인 중이면 한 저장소 파일럿, 비밀값 소비자나 권한 책임을 설명할 수 없으면 즉시 보류가 적절합니다.
한 저장소 파일럿은 이렇게 확인하십시오
파일럿의 목표는 공통 workflow가 “실행된다”는 사실을 확인하는 데 있지 않습니다. 호출 경계가 의도대로 막히고, 필요한 경우에만 열리는지를 확인하는 데 있습니다.
- 대상을 하나로 제한합니다. 가장 단순한 저장소 하나와 비배포 환경 하나를 정하고, 다른 저장소에는 변경을 적용하지 않습니다.
- 허용 경로를 기록합니다. 예상한 입력으로 호출했을 때 필요한 job만 정상 완료되는지 확인합니다.
- 거부 경로를 시험합니다. 권한 또는 필수 입력을 의도적으로 충족하지 않는 호출이 기대한 지점에서 실패하는지 확인합니다. 실제 비밀값을 노출하는 방식의 시험은 피하십시오.
- 로그와 결과물을 검토합니다. 민감한 값이 출력되지 않았는지, 실패 이유가 운영자가 이해할 수 있는 형태인지 살핍니다.
- 되돌리기를 실행해 봅니다. 문서에만 있는 절차가 아니라 기존 개별 workflow로 복귀하는 변경을 실제로 검토합니다.
- 두 소유자의 확인을 남깁니다. 호출 저장소 담당자와 공통 workflow 담당자가 같은 결과를 보고 확대 여부를 결정합니다.
Artifact attestation을 함께 쓰는 경우에는 더 세밀한 확인이 필요합니다. GitHub의 재사용 workflow와 artifact attestation 안내는 해당 시나리오에서 caller와 reusable workflow 양쪽에 필요한 권한이 있고, 검증 시 caller workflow와 서명 workflow를 구분한다고 설명합니다. 이것을 모든 workflow에 적용되는 권한 목록으로 일반화하지 말고, 도입하려는 작업의 요구 사항으로만 확인하십시오.
이 신호가 보이면 중앙화를 보류하십시오
- 어떤 저장소가 어떤 비밀값을 왜 전달하는지 목록으로 설명할 수 없습니다.
- “권한은 넉넉히 주고 나중에 줄이자”는 상태로 파일럿을 시작하려 합니다.
- 공통 workflow의 변경이 영향을 주는 저장소 수를 알 수 없거나, 변경 승인자가 없습니다.
- 정상 실행만 시험했고, 부족한 권한이나 누락 입력이 막히는지 확인하지 않았습니다.
- 기존 workflow로 돌아갈 경로가 없거나, 긴급 중단을 결정할 담당자가 없습니다.
이 경우 보류는 실패가 아닙니다. 필요한 계약과 소유권을 먼저 채우는 것이, 이후 여러 저장소에서 동시에 발생할 수 있는 운영 문제를 줄이는 가장 빠른 경로일 수 있습니다.
다음에 함께 보면 좋은 FLOWIT 글
- AI 에이전트가 Actions 실행 경계 안으로 들어가기 전 점검 카드
- 배포 역할을 받기 전 OIDC claim을 확인하는 테스트
- 빌드 산출물의 출처를 확인하는 admission receipt
- 에이전트가 의존성·action 참조를 바꿨을 때의 별도 심사 카드
자주 묻는 질문
Q1. secrets: inherit를 쓰면 항상 위험한가요?
항상 그렇다고 단정할 수는 없습니다. GitHub는 같은 조직 또는 엔터프라이즈 안의 caller에서 사용할 수 있는 방식을 문서화하고 있습니다. 다만 어떤 호출자가 어떤 비밀값을 전달하고, called workflow의 어느 job이 그것을 소비하는지 설명하지 못한다면 named secret으로 좁히거나 파일럿으로 제한하는 편이 낫습니다.
Q2. called workflow의 권한만 최소화하면 충분한가요?
충분하지 않습니다. caller가 어떤 조건에서 호출하고 어떤 권한을 가지는지, called workflow가 그 권한을 어떤 job에서 사용하는지, 두 쪽의 연결이 어떻게 검증되는지를 함께 보셔야 합니다.
Q3. CI가 한 번 성공하면 전 저장소로 확대해도 되나요?
아닙니다. 정상 경로의 성공은 필요한 기능이 작동했다는 신호일 뿐입니다. 권한 부족 경로, 누락 입력, 로그 검토, 되돌리기, 소유자 승인을 확인한 뒤에 확대 여부를 결정하십시오.
Q4. 공통 workflow를 누가 승인해야 하나요?
최소한 호출 저장소를 책임지는 사람과 공통 workflow를 책임지는 사람이 역할을 분명히 해야 합니다. 배포나 민감한 접근이 포함된다면 해당 환경의 승인 체계도 별도로 연결하십시오.
Q5. OIDC나 artifact attestation을 사용하면 이 카드는 필요 없나요?
필요합니다. OIDC와 attestation은 각각 역할 획득과 산출물 검증에 도움을 주는 수단입니다. 재사용 workflow 도입에서 누가 무엇을 호출하고, 어떤 권한과 비밀값이 경계를 넘는지는 별도로 판단해야 합니다.
참고 자료
- GitHub Docs — Reuse workflows: reusable workflow의 inputs, named secrets, secret 전달과 호출 구조를 확인할 수 있습니다.
- GitHub Docs — Secure use reference: 최소 권한과 참조 고정 같은 안전한 운영 원칙을 확인할 수 있습니다.
- GitHub Docs — Artifact attestations and reusable workflows: attestation 시나리오에서 caller와 reusable workflow의 권한 및 검증 출처를 구분하는 방법을 설명합니다.
- GitHub Docs — Authenticate with GITHUB_TOKEN: workflow와 job 단위의
GITHUB_TOKEN권한 설정을 확인할 수 있습니다.
이 글이 마음에 드세요?
FLOWIT on YouTube
영상으로도 FLOWIT을 이어서 보세요
AI 자동화, Claude Code, n8n, 데이터 분석 흐름을 블로그와 영상으로 함께 정리하고 있습니다.
AI 코딩 에이전트 의존성 변경, 병합 전 6칸 판단표
AI 데이터 에이전트, 잘 쓰는 사람이 늘면 바로 확대해도 될까? 접근 범위를 여는 5지표 게이트
AI 코딩 에이전트가 만들기 전에 합의해야 할 것: 완료 정의를 고정하는 6칸 스프린트 계약