Some checks failed
deploy-site / deploy (push) Failing after 3m26s
The manual install path still needed 7-Zip, which the target machine does not have, so "installable without a certificate" was not yet true. The channel now also publishes the app as byte-split zip parts, and the install script joins them and extracts with the built-in Windows Expand-Archive after verifying every part and the joined archive. Version 1.3.1 republishes the channel from a single build, because a version's artifacts can only match one build and published volumes are never overwritten.
8.4 KiB
8.4 KiB
서명 없이 배포하기 — D3RO Voice 배포 경로 정리 (2026-09 기준)
왜 이 문서가 있나: MSIX/NSIS 설치본은 public-trust Authenticode 서명이 필수다. 인증서가 없으면 릴리스 파이프라인이 fail-closed로 멈춘다(실측:
v1.2.0·v1.3.0태그 모두 서명 가드에서 실패). 그동안 사용자가 설치할 수 있는 경로가 필요해 조사하고 구현한 결과를 남긴다. MSIX 계획을 버리는 문서가 아니다 — 서명이 준비되면 기존 계획을 그대로 간다.
1. 제약 (실측)
| 제약 | 값 | 근거 |
|---|---|---|
| canonical feed 업로드 본문 한도 | 100MiB (104,857,600 bytes) — 초과 시 HTTP 413 | Cloudflare 뒤에 있음. 실측: 60MiB → 201, 110MiB → 413 (274ms, CF 오류 페이지) |
| 1.1.0 설치본이 통과한 이유 | 102,172,129 bytes = 97.4MiB (한도 미만) | 같은 feed의 latest.yml |
| 사이드카 포함 앱 크기 | unpacked 688MB → zip 243MiB / 7z 162MiB | apps/desktop/release/<v>/win-unpacked 실측 |
| 이 PC의 Smart App Control | 꺼짐 (VerifiedAndReputablePolicyState = 0) |
SAC가 켜져 있으면 서명 없는 바이너리는 채널과 무관하게 실행 차단 |
| Forgejo generic registry | HEAD 미지원(405), Range: bytes=0-0 지원(206 + content-range) |
크기/불변 검증은 Range GET으로 한다 |
결론: 서명 여부와 별개로, 100MiB를 넘는 산출물은 이 feed로 게시할 수 없다. 즉 사이드카를 포함한 NSIS 설치본(189MB)은 인증서가 있어도 지금 게시할 수 없다. 이건 서명과 무관한 별도 결함이며, 앱 크기를 줄이거나(엔진 분리 다운로드) 게시 경로를 바꾸는 작업이 필요하다(§4 백로그).
2. 서명 없이 설치되는 방법 비교 (2025-2026)
| 방법 | SmartScreen | Smart App Control | 관리자 | 자동 업데이트 |
|---|---|---|---|---|
| 대용 ZIP | 최초 실행 경고(다운로드 MOTW 전파) | 차단 | 불필요 | 없음 |
| Scoop | 패키지 매니저가 직접 내려받아 MOTW 없음 → 경고 없음 | 차단 | 불필요(per-user) | scoop update * + manifest autoupdate |
| winget | 대개 경고 없음 | 차단 | 설치 방식에 따름 | winget upgrade (manifest 등록 필요) |
| 서명 없는 NSIS/Inno | "Windows protected your PC" → Run anyway | 차단 | 사실상 필요 | 없음 |
| MSIX self-signed 사이드로드 | 서명 없는 것과 같음 | 차단 | 필요(인증서를 TrustedPeople에) | .appinstaller (ms-appinstaller는 기본 비활성) |
| Velopack(per-user Setup.exe) | 서명 없으면 자주 경고 | 차단 | 불필요 | 내장 UpdateManager |
핵심: Smart App Control이 켜진 PC에서는 어떤 무서명 경로도 통하지 않는다. SAC는 클린 설치 기본값이 켜져 있고, 끄면 다시 켤 수 없다(재설치 필요). 그래서 공개 배포의 정답은 여전히 "서명"이고, Scoop/휴대용은 SAC가 꺼진 환경(그리고 개발/테스트)에서 쓸 수 있는 보완 경로다.
3. 이 저장소가 택한 경로
3-1. 서명 없이 지금 배포되는 것 (portable 채널)
- 산출물 두 가지(같은 버라도 목적이 다름):
- 7z 분할 볼륨
D3RO-Voice-<v>-x64-portable.7z.001/.002— LZMA2로 688MB → 162MiB. Scoop 전용. - zip 분할 부품
...zip.001/.002/.003— 243MiB. 수동 설치 스크립트용. Windows 내장Expand-Archive만으로 풀 수 있어 사용자가 7-Zip을 설치할 필요가 없다.
- 7z 분할 볼륨
- 게시 위치:
.../generic/d3ro-voice/portable-<version>/와.../portable-latest/(자동 업데이트 피드latest.yml과 완전히 분리). - 설치 방법 두 가지:
- Scoop — 저장소의
bucket/디렉토리를 버킷으로 쓴다. Scoop은.7z.001볼륨을 이어서 해제하는 기능을 공식 지원한다(7-Zip 볼륨).scoop bucket add d3ro https://git.chanpaca.net/yunchan/d3ro-voice.git scoop install d3ro/d3ro-voice - 수동 설치 스크립트 —
scripts/install/install-d3ro-voice.ps1(피드에도 게시됨). zip 부품을 내려받아 부품별 SHA-256 검증 → 결합 → 결합본 SHA-256 재검증 →Expand-Archive로 해제 →%LOCALAPPDATA%\Programs\D3RO Voice에 설치 + 시작 메뉴 바로가기. 관리자 권한 불필요, 추가 도구 불필요(Windows 10/11 기본).irm https://git.chanpaca.net/api/packages/yunchan/generic/d3ro-voice/portable-latest/install-d3ro-voice.ps1 | iex
- Scoop — 저장소의
- 자동화:
.forgejo/workflows/portable.yml(태그 + 수동 실행).WIN_CSC_*가 필요 없다. - 커맨드:
npm run release:portable:build→npm run release:portable:check→npm run release:portable
안전 규칙(구현에 반영):
- 볼륨은 불변 — 같은 버전 경로에 다른 바이트가 있으면 게시 중단.
- 메타데이터(
portable.json, 설치 스크립트)만 갱신 허용. - 같은 버전을 다시 빌드하면 7z/zip 바이트가 달라져(내부 타임스탬프) 게시가 중단된다.
즉 한 버전의 portable 산출물은 한 번의 빌드에서만 나온다. 태그 파이프라인(CI)이 최초
게시자가 되도록 하고, 로컬 재게시로 채널을 덮어쓰지 않는다. 이미 게시된 세트를 갱신해야 하면
버전을 올린다(이 문서 작성 시
1.3.0부분 게시분을1.3.1로 대체). - 파일명에
-portable을 넣어 서명된 릴리스 자산과 혼동되지 않게 한다. latest.yml/update-policy.json은 절대 건드리지 않는다(자동 업데이트는 서명 릴리스 전용).
3-2. 서명이 준비되면 (원래 계획 유지)
- MSIX/NSIS는 그대로 간다. 필요한 것은 public-trust 인증서 하나다.
- 2026년 기준 가장 싼 현실적 선택:
- Azure Artifact Signing(구 Trusted Signing) — Basic $9.99/월, 하드웨어 토큰 불필요,
EXE/MSI/MSIX 서명 가능, SmartScreen/SAC 대응. 단 개인은 미국/캐나다 거주자만,
조직은 한국 포함 특정 국가에서 가능(사업자 검증 필요). CI는
signtool+ dlib 또는azure/artifact-signing-action(Windows 러너)로 연동. - SSL.com OV 코드 서명 — 약 $129/년(+클라우드 HSM/eSigner 별도), 사업자 필요.
- 참고: EV가 SmartScreen을 즉시 통과시키는 경로는 2024년에 폐지됐다. 평판은 누적된다.
- Azure Artifact Signing(구 Trusted Signing) — Basic $9.99/월, 하드웨어 토큰 불필요,
EXE/MSI/MSIX 서명 가능, SmartScreen/SAC 대응. 단 개인은 미국/캐나다 거주자만,
조직은 한국 포함 특정 국가에서 가능(사업자 검증 필요). CI는
4. 남은 백로그
| ID | 항목 | 왜 |
|---|---|---|
| GAP-REL-04 | 사이드카 포함 설치본이 Cloudflare 100MiB 한도를 넘는다(NSIS 189MB) | 인증서가 있어도 게시 불가. 크기를 줄이거나 게시 경로를 바꿔야 한다 |
| GAP-STT-07 | 엔진(사이드카) 첫 실행 다운로드 방식으로 분리 | 앱 번들을 100MiB 이하로 만들고, 엔진은 분할 다운로드 + SHA-256 검증으로 받는다. 설치 경험과 업데이트 크기가 모두 좋아진다 |
| GAP-REL-05 | winget 매니페스트 등록 | winget-pkgs 커뮤니티 저장소 제출 필요(100MiB 한도와 무관한 별도 경로) |
5. 현재 상태 (2026-09-18)
- 게시된 채널:
portable-1.3.1+portable-latest(7z 볼륨 2개, zip 부품 3개, 인덱스, 설치 스크립트). portable-1.3.0에는 7z 볼륨 2개만 있다(부분 게시, zip 부품 없음) —1.3.1이 대체한다.- updater feed(
latest.yml)는 여전히1.1.0이며 이 채널은 그것을 건드리지 않는다.
6. 검증 기록 (2026-09-18)
- 7z 볼륨 게시 후 무인증 공개 GET으로 인덱스/볼륨/스크립트 제공 확인.
- 설치 스크립트 end-to-end 실행: 볼륨 2개 다운로드 → SHA-256 검증 → 결합(162.1MiB) →
7-Zip 해제 → 설치 디렉토리에
D3RO Voice.exe,resources/sidecar/sidecar.exe,resources/sidecar/_internal/faster_whisper/assets/silero_vad_v6.onnx,resources/sox/sox.exe존재 확인 → 시작 메뉴 바로가기 생성. (검증 후 테스트 설치/바로가기는 제거) - 재게시 시도 시 동일 볼륨은 "이미 동일한 파일" 로 건너뛰는 것 확인(불변 가드 동작).
- 1.3.1 수동 설치 스크립트를 7-Zip 없이 end-to-end 실행: zip 부품 3개 다운로드 →
부품별 SHA-256 → 결합(242.9MiB) → 결합본 SHA-256 → Expand-Archive → 설치 디렉토리에
D3RO Voice.exe,resources/sidecar/sidecar.exe, VADsilero_vad_v6.onnx,resources/sox/sox.exe확인 → 시작 메뉴 바로가기 생성. (검증 후 테스트 설치/바로가기 제거)