OpenClaw macOS 앱 서명 및 패키징 가이드
macOS 앱을 개발하다 보면 매번 다시 빌드할 때마다 알림이나 마이크 접근 권한을 다시 허용해야 해서 번거로웠던 적이 많으셨을 거예요. macOS의 보안 정책 때문에 발생하는 이 문제는 개발 흐름을 끊는 아주 귀찮은 요소 중 하나입니다.
이런 불편함을 해결하기 위해 디버그 빌드에서도 권한 설정을 안정적으로 유지할 수 있는 서명 자동화 방법을 정리했습니다.
mac signing (debug builds)
섹션 제목: “mac signing (debug builds)”이 앱은 보통 scripts/package-mac-app.sh를 통해 빌드되며, 현재 다음과 같은 작업을 수행해요.
- 안정적인 디버그 bundle identifier를 설정합니다:
ai.openclaw.mac.debug - 해당 bundle id로 Info.plist를 작성합니다 (필요하면
BUNDLE_ID=...로 덮어쓸 수 있어요). scripts/codesign-mac-app.sh를 호출하여 메인 바이너리와 앱 번들에 서명합니다. 이렇게 하면 macOS가 재빌드된 앱을 동일한 번들로 인식해서 TCC permissions(알림, 손쉬운 사용, 화면 기록, 마이크, 음성 인식 등)을 그대로 유지해 줍니다. 권한을 안정적으로 유지하려면 실제 signing identity를 사용하는 것이 좋고, ad-hoc 방식은 선택 사항이지만 다소 불안정할 수 있습니다 (macOS permissions 참고).- 기본적으로
CODESIGN_TIMESTAMP=auto를 사용합니다. 이는 Developer ID 서명에 대해 신뢰할 수 있는 타임스탬프를 활성화해요. 오프라인에서 디버그 빌드를 할 때는CODESIGN_TIMESTAMP=off로 설정해서 타임스탬프 단계를 건너뛸 수 있습니다. - Info.plist에 빌드 메타데이터를 주입합니다:
OpenClawBuildTimestamp(UTC)와OpenClawGitCommit(짧은 해시)을 넣어 About 창에서 빌드 정보, git 정보, 디버그/릴리스 채널을 확인할 수 있게 합니다. - 패키징 기본 환경은 Node 24입니다: 스크립트가 TS 빌드와 Control UI 빌드를 실행할 때 사용해요. 호환성을 위해 Node 22 LTS(현재
22.14+)도 계속 지원합니다. - 환경 변수에서
SIGN_IDENTITY를 읽어옵니다. 셸 설정 파일(rc)에export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"또는 Developer ID Application 인증서를 추가하면 항상 본인의 인증서로 서명할 수 있어요. Ad-hoc 서명을 원한다면ALLOW_ADHOC_SIGNING=1또는SIGN_IDENTITY="-"를 명시적으로 설정해야 합니다 (권한 테스트용으로는 추천하지 않아요). - 서명 후 Team ID 감사를 실행합니다. 앱 번들 내부의 Mach-O 파일이 다른 Team ID로 서명되어 있으면 실패 처리를 해요. 이를 건너뛰려면
SKIP_TEAM_ID_CHECK=1로 설정하세요.
사용 방법
섹션 제목: “사용 방법”# from repo rootscripts/package-mac-app.sh # auto-selects identity; errors if none foundSIGN_IDENTITY="Developer ID Application: Your Name" scripts/package-mac-app.sh # real certALLOW_ADHOC_SIGNING=1 scripts/package-mac-app.sh # ad-hoc (permissions will not stick)SIGN_IDENTITY="-" scripts/package-mac-app.sh # explicit ad-hoc (same caveat)DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh # dev-only Sparkle Team ID mismatch workaroundAd-hoc 서명 참고 사항
섹션 제목: “Ad-hoc 서명 참고 사항”SIGN_IDENTITY="-" (ad-hoc)로 서명할 때, 스크립트는 자동으로 Hardened Runtime (--options runtime)을 비활성화합니다. 이는 Sparkle처럼 Team ID가 다른 임베디드 프레임워크를 로드할 때 앱이 충돌하는 것을 방지하기 위해 꼭 필요해요. 또한 ad-hoc 서명은 TCC permission 유지를 보장하지 않으니, 문제가 생기면 macOS permissions 가이드를 보고 복구 단계를 따라해 보세요.
About 메뉴를 위한 빌드 메타데이터
섹션 제목: “About 메뉴를 위한 빌드 메타데이터”package-mac-app.sh는 패키징 시점에 다음 정보를 번들에 기록합니다.
OpenClawBuildTimestamp: 패키징 시점의 ISO8601 UTC 시간OpenClawGitCommit: 짧은 git 해시 (사용 불가능할 경우unknown)
About 탭은 이 키들을 읽어서 버전, 빌드 날짜, git 커밋, 그리고 디버그 빌드 여부(#if DEBUG 사용)를 보여줍니다. 코드를 수정한 후 이 값들을 갱신하려면 패키저를 다시 실행해 주세요.
왜 이렇게 하나요?
섹션 제목: “왜 이렇게 하나요?”macOS의 TCC permissions는 bundle identifier와 code signature 두 가지 모두에 연결되어 있습니다. 서명되지 않은 디버그 빌드는 UUID가 계속 바뀌기 때문에, 재빌드할 때마다 macOS가 이전에 허용했던 권한을 잊어버리게 됩니다. 바이너리에 서명을 하고(기본적으로 ad-hoc 방식이라도) 고정된 bundle id와 경로(dist/OpenClaw.app)를 유지하면, VibeTunnel 방식과 마찬가지로 빌드 사이에서도 권한 설정을 그대로 유지할 수 있습니다.
다음 단계
섹션 제목: “다음 단계”OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.