여러 고객 앱을 운영할 때 계정과 서명 키를 분리하는 방법
React Native와 Expo로 여러 고객 앱을 개발·배포한다면 계정, 비용, 서명 키, 스토어 권한을 어떻게 나눌지 초기에 정해야 합니다. 이 구조를 잘못 잡으면 나중에 소유권 이전, 업데이트, 보안 관리가 복잡해집니다.
핵심 원칙
고객 앱을 여러 개 운영할 때는 “개발자가 편한 구조”보다 “고객 소유권과 보안이 분리되는 구조”가 중요합니다.
권장 원칙은 다음과 같습니다.
- 고객별로 스토어 계정을 분리한다.
- 고객별로 Expo Organization 또는 프로젝트 권한을 분리한다.
- iOS와 Android 서명 키를 고객 단위로 관리한다.
- CI/CD 권한은 최소 권한으로 부여한다.
- 비밀 키는 저장소에 커밋하지 않는다.
컨트롤과 결제는 다르다
하나의 개발자 계정으로 여러 조직에 접근할 수는 있습니다. 하지만 구독 비용, 빌드 사용량, 앱 소유권은 조직이나 스토어 계정 단위로 분리하는 것이 안전합니다.
이렇게 해야 특정 고객과의 계약이 끝나도 앱과 계정 소유권을 정리하기 쉽습니다.
iOS에서 봐야 할 것
iOS는 App Store Connect 권한, 인증서, provisioning profile, API Key 관리가 중요합니다.
자동 제출을 위해 App Store Connect API Key를 사용할 수 있지만, 키 파일은 강한 보안 관리가 필요합니다. 팀에서는 필요한 앱과 역할만 접근하도록 권한을 제한하는 것이 좋습니다.
Android에서 봐야 할 것
Android는 keystore와 Google Play 서비스 계정 권한이 핵심입니다.
keystore를 잃으면 기존 앱 업데이트가 어려워질 수 있으므로 백업 정책이 필요합니다. Google Play API 자동화를 쓴다면 서비스 계정 권한도 필요한 범위로 제한해야 합니다.
고객별 분리가 주는 장점
- 앱 소유권이 명확하다.
- 고객별 비용 산정이 쉽다.
- 권한 사고의 영향 범위를 줄일 수 있다.
- 계약 종료 시 이전이 쉽다.
- 빌드·제출 자동화를 표준화하기 좋다.
작은 팀을 위한 현실적인 구조
처음에는 모든 것을 완벽하게 자동화하기보다, 고객별로 다음 항목만 명확히 관리해도 충분합니다.
- 스토어 계정 소유자
- Expo Organization 또는 프로젝트
- iOS 인증/제출 키
- Android keystore와 서비스 계정
- CI secret 보관 위치
- 권한 회수 절차
듀오랩스가 보는 관점
여러 고객 앱을 만드는 사업에서는 코드보다 운영 구조가 더 오래 남습니다. 계정과 서명 키를 고객별로 분리하면 보안, 비용, 소유권 문제를 훨씬 안정적으로 관리할 수 있습니다.
함께 읽기
- Watchman은 React Native 개발에서 왜 필요할까React Native나 Expo로 개발하다 보면 코드를 고쳤는데 앱에 바로 반영되지 않는 경우가 있습니다. 이때 원인 중 하나가 파일 변경 감시 도구인 Watchman 문제일 수 있습니다.
- 모바일 앱 스토어 배포 자동화를 설계할 때 볼 것들모바일 앱 배포는 빌드 파일을 만드는 것에서 끝나지 않습니다. 인증서, 서명 키, 스토어 메타데이터, 심사 정보, 버전 관리, 제출 자동화까지 함께 설계해야 반복 가능한 배포가 됩니다.
- Expo EAS 비용 구조와 절약 전략Expo Application Services(EAS)는 React Native 앱을 빌드, 제출, 업데이트하는 과정을 단순하게 만들어줍니다. 하지만 팀 규모와 빌드 빈도에 따라 비용 구조를 이해하고 써야 합니다.
- React Native와 Expo에서 OTA 업데이트를 이해하는 방법OTA(Over-The-Air) 업데이트는 앱 스토어 심사를 거치지 않고 설치된 앱의 JavaScript 코드와 에셋을 갱신하는 방식입니다. React Native와 Expo 환경에서는 빠른 버그 수정과 작은 기능 개선에 매우 유용합니다.
- Expo로 개발할 때 자주 쓰는 실행 명령어 모음Expo 앱을 개발하다 보면 명령어보다 “지금 다시 빌드해야 하나?”가 더 헷갈립니다. 화면 코드만 바꿨는데 Gradle 빌드를 다시 돌리기도 하고, 반대로 스플래시 이미지를 바꾼 뒤 Metro만 재시작해서 왜 그대로인지 한참 보기도 합니다.