2026년 독점 원격 Mac CI 병렬 Job 키체인 경합과 codesign
iOS CI / DevOps 2026-04-13

2026년 독점 원격 Mac CI: 병렬 Job 아래 키체인 경합과 codesign 세션 잠금 — 사용자·키체인 분할과 security/codesign 재현 가능 SSH 의사결정 매트릭스 + FAQ

독점 원격 Mac을 자체 호스팅 CI 노드로 쓰다 병렬 Job을 올리면, 서명이 들쭉날쭉한 것처럼 보이는 실패가 자주 드러납니다. codesign 타임아웃, “User interaction is not allowed”, security 잠금 직후의 묘한 정지 등입니다. 이 가운데 다수는 “애플 버그”가 아니라 동시 접근 아래의 키체인 경합과 codesign 세션 직렬화입니다. 본 글은 경계(사용자별 vs 공유 로그인 키체인)를 이름 붙이고, 분할 전략과 SSH에서 security·codesign를 재현할 수 있는 의사결정 매트릭스를 런북에 붙일 수 있게 정리합니다. 장기 SSH 전송(ControlMaster 다중화 vs 대화형 셸)은 원격 Mac CI: SSH ControlMaster와 tmux — 자체 호스팅 Runner FAQ를, 키체인을 건드리는 공증 흐름은 헤드리스 notarytool·ASC·키체인·stapler SSH 트러블슈팅과 함께 보는 것이 좋습니다.

1. TL;DR — 무엇이 경쟁하는가

  • 키체인은 “그냥 파일”이 아닙니다. 서명 신원, 중간 신뢰, 노터리/API 비밀은 Security.framework를 거치며, 대화형 사용자에겐 종종 login 키체인이—자동화에겐 명시적으로 만든 별도 키체인 파일이 관여합니다.
  • 한 macOS 사용자 + 하나의 기본 키체인을 병렬 Job이 공유하면 잠금 대기, ACL 프롬프트, 서로 다른 codesign 호출이 충돌할 확률이 최대가 됩니다.
  • 한 호스트 안에서의 최선 격리는 보통 CI 전용 사용자를 나누는 것(각자 login 키체인·홈)이고, 계정 추가가 어렵다면 키체인 파일 경로를 Job마다 나누고 security list-keychains 순서를 엄격히 지키는 방식입니다.
  • SSH는 “누가 로그인한 것으로 보이는가”를 바꿉니다. 비대화형 ssh, launchd Job, 터미널 로그인은 키체인 잠금 해제 의미가 동일하지 않습니다—러너가 실제로 쓰는 UID·세션을 문서화하세요.

2. 키체인 경합을 쉽게 말하면

두 Job이 같은 비밀키나 같은 서명 인증서를 동시에 필요로 하면 macOS가 접근을 조율합니다. 어떤 작업은 빠르고, 어떤 항목은 UI 세션을 가정한 ACL 때문에 느리거나—securityd 내부 잠금에서 서로 기다립니다. 흔한 증상은 다음과 같습니다.

  • CPU 부하는 없는데 codesign 벽시계만 튀는 경우.
  • 다른 Job이 키체인을 가져오거나 순서를 바꾸는 순간 “키체인에서 항목을 찾을 수 없음”이 간헐적으로 나는 경우.
  • 비대화형 SSH에서는 프롬프트를 띄울 수 없어 “User interaction is not allowed”가 나는 경우.

우선 동시성 설계 문제로 보고, 사용자·키체인을 분할한 뒤에야 Xcode 업그레이드를 의심하는 편이 낫습니다.

3. codesign “세션 잠금” — 운영자가 보는 것

애플 서명 도구망은 특정 단계가 신원 또는 키체인 단위로 직렬처럼 보이기도 합니다. 이름이 잠금이든 내부 큐이든, 운영 관점에서는 같습니다: 병렬 레인마다 서명 표면(사용자 + 키체인 + 프로비저닝 캐시)을 나누면 피해 범위가 줄어듭니다.

내보낸 .p12 가져오기를 파일 잠금 없이 병렬 Job에서 공유하면 가져오기·신원 목록까지 경쟁합니다.

4. 격리 패턴 (강함 → 약함)

패턴 얻는 것 비용·주의
동시 Job마다(또는 풀마다) macOS 사용자 1명 login 키체인·홈·Derived Data 기본값·시뮬레이터 루트가 분리 운영 부담 증가, 진짜 병렬성에는 가장 잘 맞음
단일 사용자 + 키체인 파일 여러 개 (-p 등 Job별 경로) 목록 순서만 지키면 서명 신원 분리에 유리 UID는 공유, 일부 도구는 기본 login 키체인을 가정—충분히 검증 필요
서명 단계만 직렬화 (codesign / 내보내기 뮤텍스) 구현이 단순하고 동작 예측 가능 실질 병렬도 하락, 대기열 시간 증가

5. SSH 의사결정 매트릭스: security & codesign

헤드리스 독정 Mac에서 “로컬·VNC에서는 되는데 SSH만 실패”를 볼 때 쓰는 표입니다.

증상 가능성 높은 원인 우선 조치
ssh에서만 서명 실패, 콘솔에서는 정상 해당 세션에 키체인이 잠금 해제되지 않음, ACL이 UI 요구 테스트와 동일 UID로 실행, CI용 비대화형 잠금 해제 패턴 사용, GUI 프롬프트 의존 금지
병렬 Job에서 간헐적 “키체인에 없음” 공유 키체인 변경·순서 경쟁 사용자 또는 키체인 파일 분할, 동일 기본 키체인에 동시 import 금지
codesign이 CPU는 낮은데 멈춤 securityd 대기 또는 다른 서명 작업과 경합 동시 서명자 수 축소, 다른 Job과 시간대 겹침 확인, 레인별 신원 분리
쉘에선 노터리 API가 되는데 러너만 실패 환경·키체인 항목 가시성 불일치 launchd EnvironmentVariables를 대화형 셸과 맞추고, 러너 UID가 읽을 수 있는 위치에 API 키 저장

6. 재현 가능한 명령 체크리스트 (조회 위주)

CI Job이 쓰는 것과 동일 사용자로 실행하세요. 프로덕션 비밀을 바꾸지 않고 상태를 스냅샷하는 데 유용합니다.

  • security list-keychains -d user — 키체인이 여러 개일 때 검색 순서 확인.
  • security find-identity -v -p codesigning — 해당 세션에 보이는 서명 신원 확인.
  • codesign -dvvv Your.app — 실패 후 실제 서명 상태 점검.
  • 러너 로그의 Job 시작 시각과 겹치는 codesign 구간을 대조.

7. FAQ

Q1: 병렬 Job마다 같은 login 키체인을 써도 될까요?

가능하면 피하세요. UID를 나눌 수 없다면 신원을 별도 키체인 파일로 쪼개고 가져오기 순서를 문서화하고, 더 나은 방법은 사용자 분리입니다.

Q2: VNC가 GPU 때문이 아니라 서명을 “고쳐 주나요?”

대개 아니요—GUI 세션이 있어 프롬프트를 처리할 수 있기 때문입니다. 헤드리스 CI는 파이프라인 중간에 UI 승인이 필요 없게 설계하세요.

Q3: export/archive만 뮤텍스로 잠그면 충분할까요?

당장의 완충책으로는 종종 충분하지만, 대기열 깊이를 재세요. 서명이 병목이면 전역 잠금 하나보다 신원 분할에 투자하는 편이 낫습니다.

Q4: SSH ControlMaster는 어디에 쓰이나요?

전송 재사용을 최적화할 뿐, 키체인 정합성을 대신하지 않습니다. 위에 링크한 ControlMaster vs tmux 글을 참고하세요.

Q5: 호스티드 macOS 러너는요?

제공사 스케줄 뒤에 경합이 가려집니다. 독점 머신에서는 운영자가 사용자·키체인 폭발 반경을 직접 설계해야 합니다.

Mac mini급 하드웨어가 이 문제에 여전히 맞는 이유

서명 레인을 나누는 것만이 이야기의 절반이고, 나머지는 Xcode·보안 서비스·Derived Data I/O를 안정적인 macOS 스택 위에서 돌리는 일입니다. Apple Silicon 통합 메모리는 동시 컴파일·서명 부하에서 메모리 기아형 PC 팜처럼 굴복하지 않게 하고, macOS는 Gatekeeper·SIP·FileVault로 비밀과 실행 파일의 신뢰 모델을 분명히 합니다. Mac mini는 유휴 전력이 매우 낮고 소음도 적어 24/7 무인 Job에 잘 맞습니다.

환경 드리프트와 싸우지 않고 병렬 CI를 돌리고 싶다면, 이런 패턴을 Mac mini M4 급 호스트에 올리는 것은 비용 대비 Apple 네이티브 서명 동작을 확보하는 현실적인 방법입니다—SSHMac 홈에서 옵션을 확인하고 키체인 분할을 미세 조정하기 전에 하드웨어부터 맞춰 보세요.

서명 부하가 큰 독점 원격 Mac CI가 필요하신가요?

SSHMac 원격 Mac mini

실제 Apple 하드웨어에서 사용자와 키체인을 격리한 뒤, 위 SSH·codesign 매트릭스를 노트북 발열 추측 없이 적용해 보세요.

홈에서 옵션 보기