사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
데스크톱 배포
인터넷에서 내려받는 데스크톱 앱은 OS가 열어 주도록 서명해야 합니다. Gatekeeper는 서명·공증하지 않은 macOS 앱을 막고, SmartScreen은 서명하지 않은 Windows 프로그램에 경고합니다.
akan build-desktop은 --sign을 주면 서명하고 --notarize를 주면 공증하며, 신원은 환경 변수가 가리키는 것을 씁니다. 환경 변수만으로는 서명하지 않습니다. --installer true로 내려받을 파일을 만들고, --arch로 Windows·Linux 앱의 CPU를 고릅니다. macOS 앱은 Apple silicon만 만듭니다.Terminal


데스크톱 앱은 그 OS에서 빌드합니다. Mac은 macOS 앱을, Windows PC는 Windows 앱을 만듭니다. 아래 CI 레시피는 교차 빌드 대신 OS마다 작업을 하나씩 돌립니다.
서명
macOS
--sign을 주면 Developer ID Application 인증서로 모든 Mach-O 파일을 안쪽부터 서명합니다. 서버의 네이티브 애드온과 bin도 포함하고, hardened runtime과 보안 타임스탬프를 붙입니다. 실행 파일은 Bun JIT용 entitlements와, 사용 설명이 요구하면 카메라·마이크 entitlements를 받습니다. native.desktop.entitlements로 앱의 것을 더합니다. 이어서 --notarize가 공증에 내고 ticket을 staple한 뒤 spctl로 확인합니다.AKAN_NATIVE_MACOS_IDENTITY— 키체인의 인증서 이름(“Developer ID Application: Name (TEAMID)”) 또는 SHA-1입니다. 인증서가 이미 있는 Mac은 이것만 적습니다.AKAN_NATIVE_MACOS_CERTIFICATE + _PASSWORD— .p12 파일과 비밀번호입니다. 빌드가 자기 키체인에 넣었다가 끝나면 지웁니다. CI에서 쓰는 방식입니다.AKAN_NATIVE_MACOS_NOTARY_KEY + _KEY_ID + _ISSUER— App Store Connect API 키(AuthKey_XXXX.p8 파일, 키 ID, 발급자 ID)입니다.--notarize가 공증과 staple에 쓰는 자격 증명입니다.AKAN_NATIVE_MACOS_NOTARY_PROFILE— 키 대신xcrun notarytool store-credentials가 키체인에 저장한 프로필입니다.
Windows
--sign을 주면 Authenticode로 앱의 모든 PE 파일(실행 파일, DLL, 서버의 애드온과 bin)을 SHA-256과 RFC 3161 타임스탬프로 서명하고 확인합니다. signtool은 Windows SDK의 것을 씁니다(AKAN_NATIVE_SIGNTOOL로 다른 것을 고릅니다).AKAN_NATIVE_WINDOWS_CERTIFICATE + _PASSWORD— .pfx 파일과 비밀번호입니다.AKAN_NATIVE_WINDOWS_THUMBPRINT— Windows 인증서 저장소의 인증서를 SHA-1 지문으로 고릅니다. USB 토큰이나 HSM의 인증서입니다.AKAN_NATIVE_WINDOWS_SIGN_COMMAND— 다른 서명 도구를 JSON 배열로 적습니다. 파일마다 {file}을 바꿔 한 번씩 실행합니다. 예: Azure Trusted Signing을 쓰는 signtool ["signtool","sign","/fd","SHA256","/tr","http://timestamp.acs.microsoft.com","/td","SHA256","/dlib","Azure.CodeSigning.Dlib.dll","/dmdf","metadata.json","{file}"].AKAN_NATIVE_WINDOWS_TIMESTAMP_URL— RFC 3161 타임스탬프 서버입니다. 기본은 http://timestamp.digicert.com입니다.


업데이트 릴리스도 같은 방식으로 서명해야 합니다. 업데이터가 설치된 앱의 서명을 확인하므로, 서명된 설치 앱은
akan publish-update --sign으로 같은 신원으로 서명한 릴리스만 받습니다.설치 파일과 CPU
- macOS ·
<fileName>-<version>-<arch>.dmg— 앱과 Applications 바로가기가 든 디스크 이미지입니다. 열면 Applications로 끌어다 놓으라는 창이 뜨고, 디스크 아이콘은 앱 아이콘입니다.native.desktop.dmg로 배경(background,background2x)을 바꾸고 창과 아이콘 위치를 옮깁니다. 앱처럼 서명·공증·staple합니다. - Windows ·
<fileName>-<version>-<arch>-setup.exe— 사용자 단위 NSIS 설치 프로그램입니다(/S면 조용히 설치). 설치 프로그램과 그것이 쓰는 제거 프로그램도 서명합니다. - Linux ·
<fileName>-<version>-<arch>.AppImage— WebKitGTK 4.1과 GTK 3이 있는 어느 배포판에서나 도는 실행 파일 하나입니다. 빌드에는mksquashfs(squashfs-tools)가 필요합니다. AppImage는 스스로 업데이트하지 못합니다.
--arch arm64 또는 --arch x64는 Windows·Linux 앱을 그 OS의 해당 CPU용으로 빌드합니다. Rust 라이브러리, Bun 실행 파일, 서버의 bun install --cpu, bin 파일이 모두 따릅니다. macOS 앱은 Apple silicon(arm64)만 만들며, Intel Mac은 대상이 아닙니다.네이티브 애드온
.node 애드온이 있는 서버 패키지에는 대상 OS·CPU용 바이너리가 있어야 하고, /opt의 ROS나 Homebrew처럼 시스템 밖의 라이브러리를 링크하면 안 됩니다. 설치하면서 스스로 컴파일하는 패키지는 trustedDependencies에 적습니다. Bun은 신뢰하지 않은 패키지의 설치 스크립트를 돌리지 않기 때문입니다. 빌드는 사용자 컴퓨터에서 실패할 애드온을 나열하고 멈춥니다.CI 레시피
GitHub Actions에서 OS마다 작업 하나로 설치·빌드·서명·포장·업로드합니다. 인증서와 공증 키는 base64로 저장소 secret에 넣습니다. 각각 러너의 임시 폴더에 파일로 쓰고 변수로 넘기며, 비밀번호는 어떤 파일에도 남지 않습니다.
.github/workflows/desktop-release.yml


myapp을 앱 이름으로 바꾸고, 이미지 배포처럼 서버 설정 env를 준비합니다. macOS 러너에는 codesign·notarytool이, Windows 러너에는 Windows SDK의 signtool과 NSIS가 있습니다.