notarytool 공증 실패 점검표 2026

제출 결과에서 Invalid가 보였다고 해서 파일을 바로 다시 올리면 안 됩니다. Apple은 공증 제출의 상태와 상세 로그를 별도로 제공하며, 공증 스캔 통과와 티켓 부착, Gatekeeper 검증도 서로 다른 단계입니다. 먼저 Submission ID를 저장하고 로그를 조회한 뒤, 실패한 층만 고쳐야 재전송을 반복하지 않게 됩니다. (공증 작업 흐름에 관한 Apple 공식 문서)

이 글은 다음 경우에 적합합니다.

  • 공식 웹사이트에서 DMG, PKG 또는 ZIP으로 맥 앱을 배포하는 독립 개발자
  • 스크립트나 CI에서 서명과 공증을 자동화했지만 Invalid 또는 장시간 처리 상태를 만나는 유지보수 담당자
  • 서명 인증서, 키체인과 배포 스크립트를 원격 맥으로 옮기기 전 환경을 검증하려는 소규모 팀

01 상태부터 고정해야 하는 이유

공증 실패는 하나의 오류명이 아닙니다. 업로드가 끝나지 않은 상태, Apple의 처리가 진행 중인 상태, 스캔 결과가 Invalid인 상태, 공증은 성공했지만 티켓을 파일에 붙이지 못한 상태가 모두 다릅니다.

Apple은 공증을 앱 심사로 설명하지 않습니다. 공증 서비스는 Developer ID로 서명된 소프트웨어를 자동 검사하고, 통과하면 티켓을 생성합니다. Gatekeeper는 온라인 티켓이나 파일에 부착된 티켓을 확인해 실행 경고에 활용합니다. 따라서 공증 성공만으로 모든 맥 운영체제에서 정상 실행된다고 결론 내리면 안 됩니다.

먼저 제출 명령의 출력에서 아래 항목을 저장합니다.

xcrun notarytool submit "<배포파일 경로>" \
  --keychain-profile "<키체인 프로필>" \
  --wait

자동화 환경에서는 --wait 결과만 남기지 말고 Submission ID를 별도 파일에 기록하는 편이 좋습니다. 처리 중인 제출을 같은 파일로 다시 올리면 원인과 수정 결과를 비교하기 어렵습니다.

xcrun notarytool info "<제출 식별자>" \
  --keychain-profile "<키체인 프로필>"

xcrun notarytool log "<제출 식별자>" \
  --keychain-profile "<키체인 프로필>" \
  "<로그 저장 경로>"

주의: Team ID, Key ID, 발급자 식별자, 키체인 프로필 이름과 파일 경로는 공개 로그에 그대로 남기지 마세요. 아래 명령의 값은 모두 실제 값 대신 자리표시자로 교체해야 합니다.

02 첫 번째 단계: 서명 체인을 앱 안쪽까지 확인합니다

Apple은 공증 대상의 실행 파일에 유효한 코드 서명과 Developer ID 서명을 요구합니다. Mac App Store용 배포 인증서나 개발용 인증서를 그대로 사용하면 배포 방식과 맞지 않을 수 있습니다. 보안 타임스탬프도 확인 대상입니다. (공증 요구 사항에 관한 Apple 공식 문서)

겉으로 보이는 앱 서명만 확인하는 것이 가장 흔한 실수입니다. 다음 항목을 각각 확인합니다.

  • 메인 앱
  • Framework
  • 플러그인
  • XPC 서비스
  • 포함된 명령줄 도구
  • 제삼자 바이너리
  • PKG 안에 포함된 실행 파일
codesign --verify --deep --strict --verbose=4 "<앱 경로>"
codesign --display --verbose=4 "<앱 경로>"
codesign --verify --strict --verbose=4 "<중첩 코드 경로>"

--deep 검증은 출발점일 뿐입니다. 어떤 내부 객체가 실제로 실패했는지 알려면 중첩된 각 경로를 따로 검사해야 합니다. 서명 후 파일이 바뀌었거나, 빌드 스크립트가 마지막 단계에서 실행 파일을 교체했다면 외부 서명과 내부 해시가 맞지 않을 수 있습니다.

확인 대상 로그에서 찾을 단서 다음 조치
인증서 종류 Developer ID가 아닌 서명 신원 배포 방식에 맞는 서명 신원으로 다시 서명
개인 키 키체인에서 개인 키를 찾지 못함 인증서와 개인 키를 같은 키체인에 복원
타임스탬프 보안 타임스탬프가 없거나 서명 검증 실패 배포 서명 단계에서 타임스탬프 활성화
중첩 코드 특정 Framework, 플러그인 또는 도구 경로 해당 객체를 먼저 서명한 뒤 외부를 다시 서명
서명 후 변경 해시 또는 코드 디렉터리 불일치 서명 이후 파일을 수정하는 빌드 단계 제거

인증서의 유효성은 임의의 기간으로 추정하지 말고 키체인과 Apple의 인증서 안내를 기준으로 확인해야 합니다. Apple은 코드 서명을 식별 정보로 설명하며, 검증에는 codesign 같은 시스템 도구를 사용할 것을 안내합니다. (Apple 코드 서명 인증서 기술 문서)

03 Hardened Runtime과 권한은 함께 봐야 합니다

Hardened Runtime을 켰다는 사실만으로 공증 조건을 충족하는 것은 아닙니다. 앱이 런타임 보호 기능을 우회해야 한다면 해당 기능에 맞는 예외 권한이 필요하지만, 사용하지 않는 예외를 넣으면 보안 범위와 검토 부담이 커집니다. (Hardened Runtime에 관한 Apple 공식 문서)

특히 다음 세 가지를 구분해야 합니다.

  1. 권한 형식 오류
    권한 파일이 올바른 XML과 인코딩을 사용하지 않는 경우입니다.

  2. 불필요한 권한 설정
    디버깅이나 JIT 실행 같은 예외를 실제 기능과 관계없이 넣은 경우입니다.

  3. 서명 후 내용 변경
    권한을 포함해 서명한 뒤 실행 파일이나 번들을 수정한 경우입니다.

com.apple.security.get-task-allow가 배포 빌드에 활성화되어 있으면 공증이 실패할 수 있습니다. 개발 중 디버깅에 필요한 설정과 배포용 설정을 분리하고, 최종 산출물에서 실제 서명된 권한을 확인해야 합니다. (일반적인 공증 문제 해결에 관한 Apple 공식 문서)

codesign -d --entitlements :- "<앱 경로>"
codesign --verify --strict --verbose=4 "<앱 경로>"

권한을 무조건 삭제하는 방식도 위험합니다. JIT, 플러그인 로딩, 특정 파일 접근처럼 앱의 실제 기능에 필요한 예외라면 Apple 문서의 해당 권한 조건과 배포 방식을 확인한 뒤 최소 범위로 남겨야 합니다.

04 중첩 코드와 배포 파일 형식을 분리합니다

외부 앱이 정상적으로 서명되어도 내부 Framework나 XPC 서비스가 손상되면 공증 로그는 내부 경로를 문제로 표시할 수 있습니다. 따라서 앱 번들을 먼저 완성하고, 모든 내부 실행 파일을 서명한 다음, 마지막에 바깥쪽 앱을 서명해야 합니다.

DMG, PKG, ZIP은 공통 절차를 공유하지만 최종 검증 대상은 다릅니다.

  • ZIP: 압축하기 전 앱의 서명과 공증 상태가 핵심입니다.
  • DMG: 앱뿐 아니라 배포용 디스크 이미지의 티켓 부착과 검증을 확인합니다.
  • PKG: 설치 패키지 서명과 패키지 안의 앱, 도구, 중첩 실행 파일을 함께 확인합니다.
spctl --assess --type execute --verbose=4 "<앱 경로>"
spctl --assess --type install --verbose=4 "<PKG 경로>"
xcrun stapler validate "<배포 파일 경로>"

spctl 결과와 stapler 결과는 공증 로그의 대체물이 아닙니다. 공증 서비스가 파일을 받아 스캔했는지, 스캔을 통과했는지, 티켓을 로컬 파일에 부착했는지를 각각 기록해야 합니다.

05 인증과 stapler 문제를 스캔 거절과 섞지 않습니다

notarytool에서 인증 프로필을 읽지 못하면 아직 공증 스캔이 시작되지 않았을 수 있습니다. 네트워크 연결이나 업로드 대상 접근성이 문제여도 Invalid와 같은 코드 서명 거절로 단정하면 안 됩니다.

반대로 상태가 Accepted인데 stapler가 실패한다면 다음을 확인합니다.

  • 제출한 파일과 현재 부착하려는 파일의 경로가 같은지
  • 제출 후 파일을 다시 압축하거나 수정하지 않았는지
  • DMG, PKG, 앱 중 어떤 파일에 티켓을 부착해야 하는지
  • 인터넷 연결과 Apple 서비스 접근이 가능한지
  • 부착 뒤 stapler validatespctl 결과가 어떻게 달라졌는지

Apple은 notarytoolstapler를 자동화된 배포 과정에 넣을 수 있다고 안내합니다. 또한 Notary API는 제출 상태와 로그를 별도로 조회하는 구조를 제공합니다. 이 때문에 인증 실패, 처리 지연, 로그 조회 실패, 티켓 부착 실패를 하나의 공증 거절로 처리하면 안 됩니다. (공증 자동화 작업 흐름에 관한 Apple 공식 문서)

조건별로 다음 조치를 선택합니다

  • 제출 식별자가 없으면 재전송보다 명령 출력과 자동화 로그부터 복구합니다.
  • 상태가 처리 중이면 같은 파일을 다시 올리지 말고 상태 조회를 반복합니다.
  • 상태가 Invalid이고 로그가 있으면 로그에 표시된 첫 번째 문제부터 수정합니다.
  • 서명 검증이 로컬에서도 실패하면 공증 재시도 전에 빌드와 서명 단계를 고칩니다.
  • 공증은 Accepted지만 부착만 실패하면 코드 서명을 다시 하기보다 파일 경로와 부착 대상을 확인합니다.
  • 로컬 검증은 통과하지만 배포 후 Gatekeeper가 경고하면 최종 압축 파일과 실제 사용 환경에서 다시 검증합니다.
  • 키체인과 인증 정보가 매번 사라지면 임시 맥에서 반복하지 말고 지속 보관이 가능한 원격 맥 또는 전용 빌드 환경으로 이전합니다.

Apple의 공증 작업 흐름 안내일반적인 공증 문제 해결 문서를 함께 보면서 이 분기를 적용하면 됩니다.

06 자주 묻는 문제를 로그 기준으로 해결합니다

메타데이터의 질문과 답변은 본문에서 반복하지 않고, 실제 조치 순서를 보완하는 용도로 정리합니다.

07 원격 맥에서 반복 배포할 때 남겨야 할 기록

원격 환경으로 옮길 때 가장 먼저 확인할 것은 CPU 성능이 아닙니다. 서명 신원과 개인 키가 유지되는지, Xcode Command Line Tools 경로가 고정되는지, 키체인 프로필을 자동화 계정이 읽을 수 있는지가 우선입니다.

Apple은 notarytool이 Xcode에 포함된 명령줄 도구이며, 선택된 개발자 도구 경로에 따라 실행 파일이 달라질 수 있다고 안내합니다. xcode-selectDEVELOPER_DIR 설정이 서로 다른 환경을 가리키면 로컬과 원격의 결과가 달라질 수 있습니다. (최신 공증 도구로 이전하는 방법에 관한 Apple 기술 문서)

xcode-select --print-path
xcrun notarytool --help
xcrun stapler --help
codesign --help

다음 기록을 배포 번호별로 남기면 재현성이 좋아집니다.

기록 항목 보존할 내용 공개 전 처리
빌드 환경 운영체제, Xcode 경로, 명령줄 도구 경로 계정명과 내부 경로 마스킹
서명 결과 인증서 종류, 서명 검증 결과, 권한 목록 Team ID와 앱 식별자 일부 마스킹
공증 결과 Submission ID, 상태, 로그의 문제 유형 인증 정보와 비공개 경로 삭제
티켓 결과 부착 명령, 검증 결과, 대상 파일 고객 파일명과 저장 위치 마스킹
Gatekeeper 결과 실행 또는 설치 평가 결과 제품명과 내부 배포 주소 정리
배포 형식 먼저 검사할 대상 마지막 확인
ZIP 압축 전 앱과 중첩 코드 압축 파일의 공증 및 Gatekeeper 평가
DMG 앱 서명과 디스크 이미지 DMG 티켓 부착 및 검증
PKG 설치 패키지와 포함된 실행 코드 설치 평가와 설치 후 앱 실행

단발성 수정이라면 기존 맥에서 문제를 해결할 수 있습니다. 그러나 매번 인증서를 다시 가져오거나 키체인 프로필을 새로 만들고, 제출 로그가 사라진다면 그 환경은 자동 배포 서버로 보기 어렵습니다.

원격 맥 주문 환경을 사용할 때도 먼저 실제 배포 파일로 다음 순서를 검증해야 합니다.

  1. 릴리스 빌드 생성
  2. Developer ID 서명 확인
  3. 권한과 Hardened Runtime 확인
  4. notarytool 제출
  5. Submission ID와 로그 저장
  6. Accepted 상태 확인
  7. stapler 부착
  8. stapler validate 실행
  9. spctl로 앱, DMG 또는 PKG 평가
  10. 탈출 가능한 비밀 정보가 없는지 로그 검토
판정 현재 환경 유지 원격 맥 이전 검토
키체인 프로필 재부팅 뒤에도 유지됨 매번 수동 재등록 필요
서명 신원 인증서와 개인 키가 함께 검증됨 개인 키가 없거나 접근 권한이 불안정함
도구 체인 경로와 스크립트에 고정됨 실행할 때마다 다른 Xcode를 사용함
로그 보존 제출 식별자와 공증 로그를 저장함 처리 결과가 콘솔에서 사라짐
최종 검증 실제 배포 파일로 반복 통과 앱만 검사하고 DMG 또는 PKG는 미검사

08 현재 방식과 원격 맥을 비교할 시점

현재 노트북이나 임시 CI에서 계속 배포하면 키체인 삭제, 인증서 접근 권한 변화, Xcode 경로 변경, 로그 유실이 반복될 수 있습니다. 특히 장시간 켜 둘 수 없는 개발용 맥은 야간 공증과 재시도 작업에 적합하지 않습니다.

반면 원격 맥은 서명 도구, 키체인, 자동화 스크립트와 로그 저장 위치를 한 환경에 고정하기 쉽습니다. 물리적인 맥이 필요하거나 장기간 고정 부하가 계속되는 경우에는 직접 구매가 더 합리적일 수 있지만, 반복 배포용 맥이 필요하고 로컬 장비를 상시 운영하기 어렵다면 CALMVPS의 한국어 이용 안내에서 지속 실행 조건과 접근 방식을 먼저 확인해 볼 만합니다. 중요한 기준은 “맥을 빌릴 수 있는가”가 아니라, 같은 배포 파일로 서명부터 Gatekeeper 검증까지 다시 재현할 수 있는가입니다.