C.W.K.
Stream
Lesson 02 of 05 · published

왜 macOS 가 자꾸 널 잊는가

~12 min · codesign, tcc, gotcha, designated-requirement

Level 0불씨 없음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"리빌드마다, macOS 가 앱을 보고 낯선 사람을 봤어. 기술적으론 맞았으니까."

증상

접근성을 허가해. 마이크를 허가해. 오타 하나 고치려고 앱을 리빌드해 — 그리고 macOS 가 둘 다 다시 물어. 또, 모든 빌드마다. 깨진 OS 나 깨진 앱처럼 느껴져. 둘 다 아냐: macOS 가 두 바이너리가 '같은 앱' 인지 정하는 방식의 완전히 논리적인 결과야.

원인: 지정 요구사항(Designated Requirement)

macOS 는 TCC 허가(접근성, 마이크 등)를 앱의 지정 요구사항 — '이게 그 앱이다' 라고 말하는 코드 서명 규칙 — 에 묶어. 평범한 swift build애드혹 서명을 만들고, 그 지정 요구사항은 바이너리의 cdhash 에 고정돼. 소스 한 글자를 바꾸면 cdhash 가 바뀌고, DR 이 바뀌고, 방금 빌드한 앱이 유저가 허가한 앱과 안 맞아. macOS 가 잊는 게 아니라 — 이건 이름만 같은 다른 앱이라고 올바르게 결론 내리는 거야.

swift build -> 애드혹 서명 -> DR 이 cdhash 에 고정
     |
     v  한 줄 편집, 리빌드
cdhash 바뀜 -> DR 바뀜 -> TCC: "넌 누구야?" -> 영원히 재프롬프트

해법: 안정된 아이덴티티 하나로 서명 -> DR 안정 -> 허가 지속

해법, 그리고 해법 안의 함정

해법은 모든 앱이 공유하는 단일하고 안정된 자체 서명 아이덴티티 — 앱별 인증서가 아니라, 그건 문제를 곱하기만 해. 기계당 한 번 임포트하고, 빌드 스크립트가 그걸로 서명하게 하면, DR 이 바뀌길 멈춰. 그다음 알아둘 값어치가 있는 해법 안의 함정이 있어: security find-identity -v 는 Gatekeeper-유효 아이덴티티로 필터링하고, 자체 서명 인증서는 유효가 아니라(신뢰 안 됨으로 보고), 네 아이덴티티가 존재 안 하는 것처럼 보여. security find-identity -p codesigning-v 없이 — 로 감지해. 플래그 하나가 '설계대로 작동' 과 한 시간의 혼란 사이에 서 있어. 마지막으로, 첫 제대로-서명된 빌드 후, 낡은 애드혹-고정 허가를 tccutil reset 으로 한 번 지우고 다시 허가해; 그때부터 지속돼.

OS 가 자꾸 '잊으면', 실제로 뭘 키로 삼는지 물어. 권한 시스템은 앱을 이름이나 경로로 추적 안 해 — 암호학적 아이덴티티로 추적해. 허가가 증발하면, 버그를 만난 게 아니라; 의도치 않게 아이덴티티를 바꾼 거야. OS 가 뭘 네 아이덴티티로 여기는지 찾고, 안정시키면, 증상이 우회되는 대신 뿌리에서 사라져.
앱별 인증서를 만들지 마. 이걸 발견하면 본능이 '좋아, 앱마다 자기 인증서로 서명하지' 야. 그건 인증서 더, 모든 기계에 임포트 더, 만료될 것 더 — 공유 문제를 N 번 푸는 거야. 앱 가족 전체에 걸친 공유 아이덴티티 하나가 엄격히 일이 더 적고 엄격히 실패 모드가 더 적어.

Code

감지 함정: -v 가 네 자체 서명 아이덴티티를 숨김·bash
# 틀림 — Gatekeeper-유효 아이덴티티로 필터링.
# 자체 서명 인증서는 CSSMERR_TP_NOT_TRUSTED 로 보고돼 숨겨져서,
# 이건 아무것도 안 찍고 넌 아이덴티티가 설치 안 됐다고 결론 내려.
security find-identity -v

# 맞음 — 유효성 필터 없이 코드서명 아이덴티티 나열.
security find-identity -p codesigning

# 공유 아이덴티티 하나로 서명 (빌드 스크립트가 자동으로 함):
codesign --force --sign "cwk-codesign" --options runtime dist/YourApp.app

# 첫 제대로-서명된 빌드 후, 낡은 애드혹 허가를 한 번 지움:
tccutil reset Accessibility com.example.yourapp
tccutil reset Microphone    com.example.yourapp
# 한 번 다시 허가. 여기서부터 리빌드를 넘어 지속됨.

External links

Exercise

OS 나 서비스가 이미 설정한 걸 자꾸 '잊었던' 때를 떠올려 — 권한, 신뢰된 기기, 저장된 자격증명. 그게 뭘 키로 삼고 있었고, 시도 사이에 모르고 뭘 바꾸고 있었어? 그 아이덴티티를 어떻게 안정시킬래?
Hint
패턴은 코드 서명을 훨씬 넘어 일반화돼: 상태가 자꾸 증발할 때마다, 네가 상수라고 믿는 뭔가가 실제론 변하고 있어 — 해시, 기기 지문, 설치 id, 컨테이너 id. 해법은 절대 '더 조심해서 다시 허가' 가 아니라; 변하는 키를 찾아 고정하는 거야. 아이덴티티 요동에 대한 증상-수준 해법은 늘 돌아와.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.