Skip to main content

Mac App Store 제출 가이드

이 가이드는 다음 내용을 다룬다:

  • macOS에서 Electron 앱을 서명하는 방법
  • Electron 앱을 Mac App Store(MAS)에 제출하는 방법
  • MAS 빌드의 제약 사항

필수 요구 사항

Electron 앱에 서명하려면 먼저 다음 도구를 설치해야 한다:

또한 Apple Developer 계정을 등록하고 Apple Developer Program에 가입해야 한다.

Electron 앱 서명하기

Electron 앱은 Mac App Store를 통해 배포하거나 외부에서 배포할 수 있다. 각 방법마다 서명과 테스트 방식이 다르다. 이 가이드는 Mac App Store를 통한 배포에 초점을 맞춘다.

아래 단계에서는 Apple에서 인증서를 얻는 방법, Electron 앱에 서명하는 방법, 그리고 테스트하는 방법을 설명한다.

인증서 획득하기

인증서를 획득하는 가장 간단한 방법은 Xcode를 사용하는 것이다:

  1. Xcode를 열고 "Accounts" 설정을 연다.
  2. Apple 계정으로 로그인한다.
  3. 팀을 선택하고 "Manage Certificates"를 클릭한다.
  4. 인증서 관리 창의 왼쪽 하단에 있는 추가 버튼(+)을 클릭한 후, 다음 인증서를 추가한다:
    • "Apple Development"
    • "Apple Distribution"

"Apple Development" 인증서는 Apple Developer 웹사이트에 등록된 머신에서 개발 및 테스트용 앱을 서명하는 데 사용된다. 등록 방법은 프로비저닝 프로필 준비 섹션에서 설명한다.

"Apple Development" 인증서로 서명된 앱은 Mac App Store에 제출할 수 없다. 이를 위해서는 "Apple Distribution" 인증서로 서명해야 한다. 하지만 "Apple Distribution" 인증서로 서명된 앱은 직접 실행할 수 없으며, Apple이 다시 서명해야만 실행할 수 있다. 이 과정은 Mac App Store에서 앱을 다운로드한 후에만 가능하다.

기타 인증서

여러분은 다른 종류의 인증서도 존재한다는 사실을 알 수 있다.

"Developer ID Application" 인증서는 Mac App Store 외부로 앱을 배포하기 전에 서명하는 데 사용한다.

"Developer ID Installer"와 "Mac Installer Distribution" 인증서는 앱 자체가 아닌 Mac Installer Package에 서명하는 데 사용한다. 대부분의 Electron 앱은 Mac Installer Package를 사용하지 않기 때문에 일반적으로 필요하지 않다.

인증서 타입의 전체 목록은 여기에서 확인할 수 있다.

"Apple Development"와 "Apple Distribution" 인증서로 서명된 앱은 App Sandbox에서만 실행할 수 있기 때문에 반드시 Electron의 MAS 빌드를 사용해야 한다. 그러나 "Developer ID Application" 인증서는 이러한 제한이 없으므로, 이 인증서로 서명된 앱은 일반 빌드나 MAS 빌드 중 어느 것을 사용해도 된다.

레거시 인증서 이름

애플은 지난 몇 년간 인증서 이름을 변경해 왔다. 오래된 문서를 읽다 보면 이전 이름을 접할 수 있으며, 일부 유틸리티는 여전히 구식 이름을 사용하기도 한다.

  • "Apple Distribution" 인증서는 과거에 "3rd Party Mac Developer Application"과 "Mac App Distribution"으로 불렸다.
  • "Apple Development" 인증서는 이전에 "Mac Developer"와 "Development"라는 이름으로 알려졌다.

프로비저닝 프로파일 준비

Mac App Store에 앱을 제출하기 전에 로컬 머신에서 앱을 테스트하려면, "Apple Development" 인증서로 앱에 서명하고 앱 번들에 프로비저닝 프로파일을 포함시켜야 한다.

프로비저닝 프로파일을 생성하려면 아래 단계를 따르면 된다:

  1. Apple Developer 웹사이트에서 "Certificates, Identifiers & Profiles" 페이지를 연다.
  2. "Identifiers" 페이지에서 앱에 대한 새로운 App ID를 추가한다.
  3. "Devices" 페이지에서 로컬 머신을 등록한다. 머신의 "Device ID"는 "시스템 정보" 앱의 "Hardware" 페이지에서 확인할 수 있다.
  4. "Profiles" 페이지에서 새로운 Provisioning Profile을 등록하고, /path/to/yourapp.provisionprofile 경로에 다운로드한다.

Apple의 앱 샌드박스 활성화

Mac App Store에 제출된 앱은 Apple의 앱 샌드박스에서 실행되어야 하며, Electron의 MAS 빌드만 앱 샌드박스에서 실행할 수 있다. 표준 darwin 빌드의 Electron은 앱 샌드박스에서 실행할 경우 실행에 실패한다.

앱을 @electron/osx-sign으로 서명할 때, 필요한 권한이 자동으로 앱의 권한 목록에 추가된다.

electron-osx-sign을 사용하지 않을 경우 추가 단계

@electron/osx-sign을 사용하지 않고 앱을 서명하는 경우, 앱 번들의 권한 목록에 최소한 다음 키가 포함되어 있는지 확인해야 한다:

entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>TEAM_ID.your.bundle.id</string>
</array>
</dict>
</plist>

TEAM_ID는 Apple 개발자 계정의 Team ID로 대체해야 하며, your.bundle.id는 앱의 App ID로 대체해야 한다.

또한 앱 번들 내의 바이너리와 헬퍼에 다음 권한을 추가해야 한다:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>

그리고 앱 번들의 Info.plistElectronTeamID 키를 포함해야 하며, 이 키의 값은 Apple 개발자 계정의 Team ID여야 한다:

<plist version="1.0">
<dict>
...
<key>ElectronTeamID</key>
<string>TEAM_ID</string>
</dict>
</plist>

@electron/osx-sign을 사용할 경우, ElectronTeamID 키는 인증서 이름에서 Team ID를 추출하여 자동으로 추가된다. @electron/osx-sign이 올바른 Team ID를 찾지 못한 경우 이 키를 수동으로 추가해야 할 수 있다.

개발용 앱 서명하기

개발 머신에서 실행 가능한 앱에 서명하려면 "Apple Development" 인증서로 서명하고, 프로비저닝 프로파일을 @electron/osx-sign에 전달해야 한다.

const { signAsync } = require('@electron/osx-sign')

signAsync({
app: '/path/to/your.app',
identity: 'Apple Development',
provisioningProfile: '/path/to/your.provisionprofile'
})

@electron/osx-sign을 사용하지 않고 서명하는 경우, 프로비저닝 프로파일을 YourApp.app/Contents/embedded.provisionprofile 경로에 위치시켜야 한다.

서명된 앱은 프로비저닝 프로파일에 등록된 머신에서만 실행할 수 있다. 이는 Mac App Store에 제출하기 전에 서명된 앱을 테스트할 수 있는 유일한 방법이다.

Mac App Store에 제출할 앱 서명하기

Mac App Store에 제출할 앱을 서명하려면 "Apple Distribution" 인증서를 사용해야 한다. 이 인증서로 서명된 앱은 Mac App Store에서 다운로드한 경우를 제외하고는 어디에서도 실행되지 않는다.

const { signAsync } = require('@electron/osx-sign')

signAsync({
app: 'path/to/your.app',
identity: 'Apple Distribution'
})

Mac App Store에 앱 제출하기

"Apple Distribution" 인증서로 앱에 서명한 후, Mac App Store에 제출할 수 있다. 하지만 이 가이드는 앱이 Apple의 승인을 받을 것을 보장하지 않는다. Mac App Store 요구 사항을 충족하는 방법에 대한 Apple의 앱 제출 가이드를 반드시 참고해야 한다.

앱 업로드

서명된 앱을 App Store Connect에 업로드하려면 Apple Transporter를 사용해야 한다. 업로드하기 전에 반드시 레코드를 생성했는지 확인한다.

만약 private API 사용과 관련된 오류가 발생한다면, 앱이 Electron의 MAS 빌드를 사용하고 있는지 확인해야 한다.

업로드가 완료되면 앱 리뷰를 제출해야 한다.

MAS 빌드의 제약 사항

앱 샌드박싱 요구사항을 모두 충족하기 위해 MAS 빌드에서는 다음과 같은 모듈이 비활성화되었다:

  • crashReporter
  • autoUpdater

그리고 다음과 같은 동작이 변경되었다:

  • 일부 기기에서는 비디오 캡처가 작동하지 않을 수 있다.
  • 특정 접근성 기능이 제대로 동작하지 않을 수 있다.
  • 앱이 DNS 변경을 인지하지 못한다.

또한, 앱 샌드박싱을 사용하기 때문에 앱이 접근할 수 있는 리소스가 엄격히 제한된다. 더 자세한 정보는 앱 샌드박싱을 참고한다.

추가 권한 설정

앱 샌드박스 환경에서 실행되는 모든 앱은 제한된 권한 집합 하에서 작동한다. 이는 악성 코드로 인한 피해를 최소화하기 위한 조치다. 여러분의 앱이 사용하는 Electron API에 따라, 앱의 권한 설정 파일에 추가 권한을 부여해야 할 수 있다. 그렇지 않으면 앱 샌드박스가 해당 기능의 사용을 차단할 수 있다.

권한 설정은 프로퍼티 리스트(.plist)나 XML 형식의 파일로 지정한다. 애플리케이션 번들 자체에 대한 권한 설정 파일과, 모든 실행 파일(바이너리, 프레임워크(.framework), 동적 라이브러리(.dylib) 등)에 적용되는 상속된 속성을 기술하는 하위 권한 설정 파일을 제공해야 한다.

앱 샌드박스 문서에서 전체 권한 목록을 확인할 수 있지만, 여기서는 MAS 앱에 필요한 몇 가지 권한을 소개한다.

@electron/osx-sign을 사용하면 파일별로 커스텀 권한을 다음과 같이 설정할 수 있다:

const { signAsync } = require('@electron/osx-sign')

function getEntitlementsForFile (filePath) {
if (filePath.startsWith('my-path-1')) {
return './my-path-1.plist'
} else {
return './alternate.plist'
}
}

signAsync({
optionsForFile: (filePath) => ({
// 서명할 파일에 따라 적절한 권한 설정 파일 경로를 반환한다.
entitlements: getEntitlementsForFile(filePath)
})
})

네트워크 접근 설정

앱이 서버에 연결할 수 있도록 아웃바운드 네트워크 연결을 활성화하려면:

<key>com.apple.security.network.client</key>
<true/>

앱이 네트워크 리스닝 소켓을 열 수 있도록 인바운드 네트워크 연결을 활성화하려면:

<key>com.apple.security.network.server</key>
<true/>

더 자세한 내용은 네트워크 접근 활성화 문서를 참고한다.

dialog.showOpenDialog

<key>com.apple.security.files.user-selected.read-only</key>
<true/>

더 자세한 내용은 사용자 선택 파일 접근 활성화 문서를 참고한다.

dialog.showSaveDialog

<key>com.apple.security.files.user-selected.read-write</key>
<true/>

자세한 내용은 사용자 선택 파일 접근 활성화 문서를 참고한다.

Electron에서 사용하는 암호화 알고리즘

여러분이 앱을 출시하는 국가에 따라, 소프트웨어에서 사용하는 암호화 알고리즘에 대한 정보를 제공해야 할 수도 있다. 자세한 내용은 암호화 수출 규정 문서를 참고한다.

Electron은 다음과 같은 암호화 알고리즘을 사용한다: