App Store Connect Webhooks는 고빈도 상태 폴링의 대부분을 줄일 수 있지만, 검수가 끝나기 전에는 Fastlane 폴링을 삭제하면 안 됩니다. 이번 주에는 Webhooks를 주 통로로 두고 낮은 빈도의 App Store Connect API 대조를 남기는 이중화부터 적용한 뒤, 서명 검증과 멱등 처리, 누락 복구, 맥 빌드 노드 연동을 순서대로 확인해야 합니다.
이 글은 다음 팀을 위한 내용입니다.
- Fastlane으로 빌드나 심사 상태를 정기 조회하는 iOS 개발팀
- Ruby 도구 체계를 줄이고 이벤트 중심의 발행 제어면을 설계하는 데브옵스 엔지니어
- 원격 또는 클라우드 맥 노드와 이벤트 수신 서버의 연결을 검수하는 발행 책임자
마지막 업데이트: 2026년 8월 31일. 이벤트 종류, 서명 방식, 상태 정의와 API 버전은 Apple 공식 Webhooks 문서와 App Store Connect API 변경 기록을 기준으로 확인했습니다.
먼저 나눠야 할 네 개의 실행 영역
Webhooks를 Fastlane의 완전한 대체재로 보면 검수 범위를 잘못 잡게 됩니다. 이벤트는 상태 변화의 신호이고, 실제 상태의 권위 있는 값은 App Store Connect API에서 다시 조회해야 합니다. 아카이브, 서명, 내보내기와 바이너리 업로드는 여전히 macOS 환경과 Apple이 지원하는 도구가 담당합니다.
| 실행 영역 | 담당 기능 | Webhooks로 대체 가능 여부 | 검수 기준 |
|---|---|---|---|
| 제어면 | 발행 작업 생성, 상태 전이, 승인 기록 | 일부 가능 | 내부 상태 기계와 권한 분리 |
| 알림면 | 빌드와 TestFlight 상태 변화 전달 | 가능 | 서명 검증, 중복 처리, 누락 복구 |
| 조회면 | 실제 앱·버전·빌드 상태 확인 | 대체 불가 | 이벤트 수신 뒤 API 재조회 |
| macOS 실행면 | 빌드, 서명, 내보내기, 업로드 | 대체 불가 | 맥 노드 로그와 작업 식별자 연결 |
Apple은 Webhooks 이벤트와 구성 및 알림 해석 방법을 따로 설명합니다. 따라서 이벤트 수신 성공을 곧 빌드 처리 성공으로 기록해서는 안 됩니다. 이벤트에서 실제 상태를 복구할 수 없는 자동화는 무인 운영에 넣지 않는다는 원칙이 첫 번째 합격 조건입니다.
빌드 업로드 시나리오에서 상태를 다시 확인합니다
빌드 업로드는 이벤트만 저장하는 방식으로는 부족합니다. Apple의 빌드 업로드 안내와 업로드 상태 정의를 기준으로 다음 흐름을 검수합니다.
첫 단계: 식별자를 고정합니다
발행 작업을 만들 때 앱 식별자, 앱 버전, 빌드 번호, 내부 작업 식별자를 한 묶음으로 저장합니다. Webhook을 받은 뒤에는 이벤트의 대상이 현재 작업과 일치하는지 확인하고, 앱만 같다는 이유로 다음 작업을 진행하지 않습니다.
다음 단계: 이벤트를 신호로만 사용합니다
수신 서버는 이벤트를 기록한 뒤 App Store Connect API로 앱과 빌드 정보를 조회합니다. 앱 API 문서를 사용해 대상 앱을 확인하고, 조회한 빌드 상태가 실제 발행 작업과 맞을 때만 다음 상태로 이동시킵니다.
빌드 상태 이벤트를 받았는데 작업이 진행되지 않는다면 어떻게 처리해야 할까요?
먼저 서명 검증 결과, 원본 본문, 이벤트 식별자와 수신 시각을 확인합니다. 그다음 API 조회가 실패했는지, 조회 결과가 아직 처리 중인지, 대상 식별자가 다른지를 분리합니다. 이벤트가 없다는 이유로 즉시 실패 처리하지 말고, 낮은 빈도의 대조 작업과 실패 이벤트 대기열에 넣어 실제 상태를 다시 확인합니다. Apple의 API 호출 제한도 고려해야 하므로 조회 간격을 무작정 줄이는 방식은 피해야 합니다. 제한 관련 기준은 공식 rate limit 문서에서 다시 확인합니다.
합격 증거는 다음과 같습니다.
- 원본 이벤트와 검증 결과가 함께 남아 있습니다.
- 이벤트 뒤의 API 조회 결과가 저장되어 있습니다.
- 실패한 빌드의 중단 또는 재처리 기록이 있습니다.
- 동일한 발행 작업이 두 번 진행되지 않았음을 로그로 입증할 수 있습니다.
TestFlight와 버전 상태는 자동 진행선을 좁게 잡습니다
TestFlight 피드백, 베타 빌드, 앱 버전 상태는 서로 다른 업무 규칙을 가집니다. 이벤트가 왔다고 해서 심사 제출, 규정 자료 입력, 법무 승인 같은 사람의 확인 절차를 건너뛰면 안 됩니다. AppVersionState 정의를 기준으로 상태별 행동을 내부 표로 고정하는 편이 안전합니다.
- 확인 가능한 빌드 처리 완료: 테스트 배포 또는 다음 자동 검증으로 이동합니다.
- 처리 중인 상태: 대기열에 남기고 API 대조를 예약합니다.
- 심사나 규정 확인이 필요한 상태: 자동 진행을 멈추고 담당자 승인을 요구합니다.
- 예상하지 못한 상태: 성공으로 간주하지 않고 수동 보상 작업으로 보냅니다.
App Store Connect Webhooks가 Fastlane 폴링을 완전히 대신할 수 있을까요?
상태 변화 감지라는 범위에서는 가능합니다. 그러나 Webhooks는 Xcode 빌드, 코드 서명, 내보내기, 바이너리 업로드, 심사 제출 전체를 실행하지 않습니다. 그러므로 “Webhooks 수신 → API로 권위 상태 확인 → 허용된 상태 전이만 수행”이라는 구조가 완성될 때만 폴링을 줄일 수 있습니다. Fastlane은 인증서 관리, 스크린샷 생성, 플러그인 연결과 같은 주변 기능에서 여전히 가치가 있으므로 필요한 부분만 남기는 선택도 합리적입니다.
보안 수신은 성공 이벤트보다 먼저 검수합니다
수신 서버는 Apple의 Webhooks 관리 문서에 정의된 HMAC 검증 절차를 구현해야 합니다. 요청 본문을 파싱하거나 변환하기 전에 원본 본문으로 서명을 계산하고, 기대한 서명과 비교한 뒤에만 이벤트를 저장합니다.
검수할 요청은 다음과 같습니다.
- 서명 헤더가 없는 요청
- 잘못된 비밀값으로 만든 요청
- 본문 일부가 변경된 요청
- 정상 서명이지만 대상 앱이나 내부 작업이 일치하지 않는 요청
모두 거부하고, 거부 사유와 요청 식별 정보를 보안 로그에 남겨야 합니다. Webhook secret과 App Store Connect API 키는 같은 저장소와 같은 권한으로 묶지 않는 것이 좋습니다. 한 수신 서버의 노출이 전체 발행 계정의 조회와 변경 권한으로 확대되지 않도록 키의 사용 목적과 접근 주체를 분리합니다.
키를 바꾸는 기간에는 이전 비밀값과 새 비밀값을 임시로 모두 검증하되, 허용 기간과 종료 로그를 명확히 남겨야 합니다. 실패 경보가 없거나 서명 오류가 조용히 버려진다면 운영 합격으로 처리하지 않습니다.
중복과 누락은 통제된 장애로 재현합니다
이벤트 수신부는 정상 흐름보다 장애 흐름에서 품질이 드러납니다. 테스트 환경에서 같은 이벤트를 반복 전송하고, 순서를 바꾸고, API 조회를 일시적으로 실패시키며 다음 결과를 확인합니다.
- 같은 이벤트가 두 번 와도 이중 제출이나 중복 알림이 발생하지 않습니다.
- 이전 상태로 돌아가는 늦은 이벤트가 현재 상태를 덮어쓰지 않습니다.
- 수신 서버가 중단된 동안 들어온 작업을 대조 작업으로 다시 찾을 수 있습니다.
- 처리 실패 이벤트가 대기열에 남고 담당자가 재실행할 수 있습니다.
멱등 판단은 이벤트 식별자 하나에만 의존하지 않는 편이 안전합니다. 이벤트 식별자, 대상 리소스의 현재 상태, 내부 발행 작업 식별자를 함께 비교해야 합니다. 상태 기계에는 허용된 방향을 명시하고, 이미 완료된 작업에 늦은 이벤트가 도착하면 기록만 남기고 실행은 막습니다.
App Store Connect Webhook을 받지 못한 빌드는 어떻게 복구할까요?
수신 서버의 접근 로그와 서명 실패 로그를 먼저 확인한 뒤, API 대조 작업으로 앱과 빌드의 실제 상태를 찾습니다. 대조 결과를 새 이벤트처럼 무조건 재생하지 말고, 누락된 단계만 보상 작업으로 생성해야 합니다. 네트워크 장애나 서버 배포 중단을 재현했을 때 이 과정이 사람의 데이터 수정 없이 작동해야 합니다.
다섯 단계로 무인 발행 전환을 판정합니다
아래 목록은 전체 교체 선언이 아니라 생산 투입 전의 합격 기준입니다.
- [ ] 테스트 이벤트의 원본 본문과 HMAC 검증 결과를 보관합니다.
- [ ] 앱 식별자, 버전, 빌드 번호와 내부 작업을 정확히 연결합니다.
- [ ] 모든 이벤트 뒤에 API 권위 상태를 조회하고 결과를 기록합니다.
- [ ] 중복, 순서 뒤바뀜, 잘못된 서명, 대상 불일치 요청을 재현합니다.
- [ ] 누락 이벤트를 낮은 빈도의 API 대조와 실패 대기열로 복구합니다.
- [ ] 심사, 규정 자료, 승인 절차를 단일 이벤트가 우회하지 못하게 합니다.
- [ ] 맥 노드의 빌드·서명·내보내기·업로드 로그와 이벤트 작업을 연결합니다.
- [ ] 실패 시 중단, 재시도, 수동 보상 중 어떤 경로로 내려갈지 문서화합니다.
- [ ] 운영 담당자가 이중화 상태와 폴링 제거 승인 기록을 확인합니다.
점수는 항목을 단순히 더하는 방식보다 차단 조건으로 운영하는 것이 낫습니다. 보안 검증, 멱등 처리, 누락 복구, 맥 실행면 가운데 하나라도 실패하면 기존 폴링을 유지합니다. 모두 통과하면 Webhooks 주 통로와 낮은 빈도의 API 대조를 먼저 운영하고, 실제 발행 기록이 쌓인 뒤에 고빈도 폴링을 단계적으로 내립니다.
맥 실행면은 이벤트 수신부와 별도로 승인합니다
Fastlane에서 벗어나더라도 macOS에서 수행되는 아카이브, 서명, 내보내기와 바이너리 업로드 작업은 사라지지 않습니다. Webhooks는 맥 노드를 대신하는 실행기가 아니라, 실행 결과를 기다리는 제어면을 개선하는 수단입니다. 원격 맥 또는 클라우드 맥을 사용한다면 이벤트 서비스가 올바른 노드와 작업을 연결하는지 확인해야 합니다.
Fastlane을 제거한 뒤에도 어떤 맥 발행 작업을 남겨야 할까요?
빌드 환경 준비, 인증서와 프로파일 접근, 아카이브 생성, 서명 검증, 내보내기, 업로드 도구 실행, 결과 로그 보관은 남겨야 합니다. 이 작업을 순수한 서버 스크립트로 옮기려 하면 macOS 의존성과 물리적 실행 환경이라는 경계를 놓치기 쉽습니다. 맥 기반 CI/CD 운영 안내를 참고해 제어면과 실행면의 권한, 접속 방식, 로그 보존 정책을 따로 설계하는 것이 좋습니다.
현재 CI에 안정적인 macOS 실행면이 없다면 도구 교체보다 노드 확보가 먼저입니다. 자체 맥은 장기적이고 예측 가능한 고정 부하에는 유리하지만, 하드웨어 관리와 장애 대응을 직접 부담해야 합니다. 반대로 JexMac의 맥 이용 방식은 임시 발행 환경이나 원격 검증 노드를 구성할 때 검토할 수 있지만, 물리 장치 접근이 필요하거나 장기간 고정 부하가 계속되는 팀에는 자체 장비가 더 적합할 수 있습니다.
검수 결과는 세 가지 중 하나로 서명합니다. 이중 운용을 계속하거나, 고빈도 폴링만 내리거나, Fastlane의 인증서·스크린샷·플러그인 기능을 남긴 채 상태 감지만 Webhooks로 옮기는 방식입니다. 기존 방식은 구현 범위가 넓다는 장점이 있지만 Ruby 의존성, 복잡한 파일 구성, 상태 폴링 비용과 장애 추적 부담이 남습니다. 안정적인 맥 빌드·서명 실행면이 부족한 상황에서 JexMac의 원격 맥 노드를 임시 또는 검증용으로 대조하면, 전체 도구 체계를 한 번에 바꾸지 않고 이벤트 제어면의 합격 여부부터 확인할 수 있습니다. 필요한 팀은 맥 이용 요금과 제공 범위를 확인한 뒤, 자체 맥과 임시 맥 실행면의 운영 비용을 같은 검수표에 기록하면 됩니다.
JexMac으로 원격 맥 빌드를 안정적으로 운영하세요
JexMac의 원격 맥 환경에서 앱 빌드와 배포 작업을 안정적으로 진행할 수 있습니다.