App Store 외 iOS 설치용 제로트러스트 웹 클라이언트
브라우저 내 WebAssembly로 Apple API를 직접 호출하고 서버는 암호화된 중계와 IPA 컴파일만 수행하는 제로트러스트 기반 iOS 앱 설치 웹 툴이다.
TL;DR
AssppWeb은 브라우저 내 WebAssembly로 libcurl.js와 Mbed TLS 1.3을 구동하여 Apple API 호출과 TLS 처리를 클라이언트에서 완료하고 서버는 암호화된 트래픽의 중계자 및 공개 CDN에서 내려받은 IPA의 컴파일·캐시만 수행하는 제로트러스트 기반 웹 애플리케이션이다. 이 설계로 서버가 사용자 Apple 자격증명을 저장하지 않아 자격증명 노출 위험을 줄이며 Docker Compose, Railway, Cloudflare Workers 같은 다양한 호스팅 경로를 문서로 제공해 배포 유연성을 확보했다. 운영상에는 리버스 프록시의 TLS 설정과 WebSocket 프록시 허용, 프런트엔드 무결성 검증이 필수적이며 공개 인스턴스 사용 시에는 프런트엔드 변조 위험 때문에 자체 호스팅이나 신뢰할 수 있는 호스트 사용이 권장된다.
주요 기능
- 브라우저에서 Apple API와 직접 통신하여 자격증명이 서버에 노출되지 않도록 한다. 이 동작은 libcurl.js와 Mbed TLS 1.3을 WebAssembly로 구동시켜 구현되며 네트워크 요청과 TLS 핸드셰이크가 클라이언트 쪽에서 끝난다. 서버는 암호화된 트래픽을 중계하고 IPA 컴파일과 캐싱만 담당하므로 자격증명 보관 부담이 줄어든다.
- 공개 CDN에서 IPA를 다운로드하여 서버에서 프로비저닝과 설치 매니페스트를 생성하고 iOS 디바이스로 전송 가능한 itms-services 링크를 제공한다. 이 과정에서 서버는 파일을 컴파일하거나 캐시하여 반복 배포 시 대역폭을 절감하며 AUTO_CLEANUP_DAYS와 AUTO_CLEANUP_MAX_MB 같은 환경변수로 저장소 관리를 제어할 수 있다. 대용량 파일 처리로 인한 DDoS 위험이 있으므로 CDN 앞단 배치가 권장된다.
- 다양한 배포 옵션을 제공하여 Cloudflare Workers, Railway, Docker Compose로 호스팅할 수 있다. Cloudflare 배포는 Containers 기능이 필요하며 Railway는 볼륨 마운트와 HEALTHCHECK 설정을 요구한다. 자체 호스팅을 통해 프런트엔드 무결성 검증과 TLS 설정을 직접 관리할 수 있다.
어떻게 동작하는가
클라이언트는 WebAssembly로 빌드된 libcurl.js와 Mbed TLS 1.3을 사용하여 브라우저 내부에서 Apple API와 직접 TLS로 통신한다. 서버는 Wisp 프로토콜을 통한 블라인드 TCP 중계자 역할만 수행하고 공개 CDN에서 가져온 IPA를 컴파일하거나 캐시하여 설치 매니페스트를 생성한다. 이러한 분리로 서버가 자격증명을 수신하지 않으며 프런트엔드의 무결성 확보와 리버스 프록시·WebSocket 설정이 작동의 전제 조건이 된다.
해결 문제
App Store 외부에서 iOS 앱을 획득하고 기기에 설치하는 과정을 웹 인터페이스로 간단화한다. 이 도구는 브라우저 내에서 직접 Apple API와 통신하여 서버가 사용자 자격증명을 보관하지 않게 함으로써 자격증명 노출 위험을 낮춘다. 또한 서버 측에서는 IPA 컴파일과 캐싱만 처리하여 배포와 설치 매니페스트 생성을 자동화한다.
차별점
- 서버가 사용자 Apple 자격증명을 전혀 수신하지 않는 제로트러스트 설계를 채용하고 있다. 클라이언트 측에서 libcurl.js와 Mbed TLS 1.3을 WebAssembly로 구동해 Apple API 호출과 TLS 처리를 끝내므로 서버는 암호화된 중계자 및 빌드 역할에만 국한된다. 이 구조는 전통적인 서버사이드 인증 위임 방식과 달리 자격증명 유출 표면을 줄인다.
- 배포 유연성을 위해 Cloudflare Workers 컨테이너, Railway 이미지 배포, Docker Compose 같은 여러 호스팅 경로를 공식적으로 문서화하고 있다. Cloudflare 배포를 위해서는 유료 플랜과 특정 권한이 필요하다고 명시되어 있으며 Railway는 볼륨 마운트와 Healthcheck 설정을 요구한다. 다양한 호스팅 옵션이 제공되므로 운영 환경에 맞춰 선택할 수 있다.
- 리버스 프록시와 WebSocket 프록시 요구사항을 명시하여 iOS 설치 흐름과 Wisp 기반 통신 실패 시나리오를 사전 경고하고 있다. README에 X-Forwarded-Proto 헤더로 인한 무한 리다이렉트 사례와 UNSAFE_DANGEROUSLY_DISABLE_HTTPS_REDIRECT 환경변수의 사용 조건을 명확히 적어두어 운영자가 문제 원인을 진단하기 쉽다. 이 점은 같은 유형의 오픈소스 프로젝트들보다 운영 가이드가 구체적이라는 차별점으로 작동한다.
사용 사례
- 자체 호스팅 환경에서 App Store 외부로 배포된 IPA를 내부 테스트용으로 빠르게 설치하고자 할 때 사용한다. 개발자는 Docker Compose로 로컬이나 사설 인프라에 서비스를 띄워 테스트 기기로 직접 설치 매니페스트를 제공할 수 있다. 서버가 자격증명을 수신하지 않으므로 내부 보안 정책과 연계해 비교적 안전하게 테스트 환경을 운영할 수 있다.
- 제로트러스트 설계 원칙을 적용해 공용 인스턴스를 경유하지 않고도 사용자가 브라우저에서 직접 Apple 계정으로 인증해 앱을 설치할 때 활용한다. 이 흐름은 인증 정보가 서버에 저장되는 것을 방지하므로 조직 내부에서 민감한 자격증명 취급을 엄격히 제한해야 하는 경우에 적합하다. 다만 프런트엔드 코드의 무결성 검증과 TLS 설정은 반드시 운영자가 책임지고 관리해야 한다.
- CDN에 저장된 대용량 IPA를 외부 사용자에게 배포할 필요가 있는 경우 서버에서의 캐시 및 자동 정리 정책을 적용해 대역폭과 저장소 사용량을 제어하면서 설치 링크를 제공할 때 사용한다. README에서 AUTO_CLEANUP와 MAX_DOWNLOAD_MB 같은 환경변수로 저장소 및 용량 관리를 제어하는 설정을 제공하므로 대용량 파일 운영 정책과 연계해 활용할 수 있다.
시작하기
Docker Compose 방식은 공식 compose.yml을 내려받아 docker compose up -d로 컨테이너를 실행하면 기본적인 호스팅이 가능하다. Cloudflare Workers로 배포하려면 ghcr.io/lakr233/assppweb:latest 이미지를 사용하고 Workers Containers 권한과 유료 플랜을 준비해야 한다. Railway 배포의 경우 이미지 등록, Healthcheck 경로 설정, 볼륨 마운트, DATA_DIR 환경변수 설정을 통해 서비스를 기동할 수 있다.
요구사항
- Cloudflare Workers 배포는 Containers 기능을 사용하므로 Cloudflare의 유료 플랜이 필요하다. README에는 해당 플랜과 함께 Workers Scripts Edit, Containers Edit, Cloudchamber Edit 권한을 포함한 빌드/배포 토큰이 요구된다고 명시되어 있다. 권한 미비로 인한 Unauthorized 오류가 발생할 수 있으므로 토큰 권한을 사전에 확인해야 한다.
- Railway에 배포할 때는 서비스의 Healthcheck Path를 /api/settings로 설정하고 볼륨을 /data로 마운트한 뒤 DATA_DIR 환경변수를 /data로 지정해야 한다. Railway 무료 체험은 볼륨 만료 및 네트워크 제한이 있어 안정적 운영을 위해 Hobby 플랜 이상을 권장한다고 README에 적혀 있다. Serverless 옵션을 활성화하면 유휴 시점에 스케일 다운이 가능하다.
- itms-services 설치 링크를 사용하려면 유효한 TLS 인증서를 제공하는 리버스 프록시가 필수이며 프록시가 WebSocket 연결을 허용해야 Wisp 프로토콜 통신이 정상 작동한다. 일부 프록시는 X-Forwarded-Proto 헤더를 잘못 설정해 무한 리다이렉트를 발생시킬 수 있으므로 프록시 설정을 검증하거나 UNSAFE_DANGEROUSLY_DISABLE_HTTPS_REDIRECT 환경변수를 최후의 수단으로 사용하는 것이 README에 권고되어 있다.
이미지 분석

3.6k
Stars
550
Forks
+323
Trending
15
조회수
관련 토론
아직 관련 토론이 없습니다.
댓글
댓글을 작성하려면 로그인이 필요합니다.