Skip to content

chore(#23): バイナリにInfo.plistを埋め込みTCC用の安定bundle identifierを付与#291

Merged
GeneralD merged 2 commits into
mainfrom
feat/23/embed-info-plist
Jun 15, 2026
Merged

chore(#23): バイナリにInfo.plistを埋め込みTCC用の安定bundle identifierを付与#291
GeneralD merged 2 commits into
mainfrom
feat/23/embed-info-plist

Conversation

@GeneralD

@GeneralD GeneralD commented Jun 15, 2026

Copy link
Copy Markdown
Owner

type scope breaking diff files tests verified depends on

lyra バイナリに安定した CFBundleIdentifier を持つ Info.plist を埋め込み、署名にバインドする。スペクトラムアナライザ (#23) が必要とする TCC 権限基盤の前提条件を解消する。

背景 — なぜ必要か

TCC (Transparency, Consent, Control) は権限グラント(#23 のスペクトラムアナライザが将来必要とするシステム音声キャプチャ等)を bundle identity(CFBundleIdentifier)でキー する。埋め込み Info.plist が無いと、グラントは 実行ファイルのパスにキー され、Homebrew で再インストールするたびにリセットされてしまう。これが #23 を進める上での BLOCKER だった(調査メモは issue 本文に追記済み)。

そこで CLI バイナリの Mach-O に Info.plist を埋め込み、安定した bundle identity を恒久的に付与する。

変更点

ファイル 内容
Sources/CLI/Info.plist 新規。CFBundleIdentifier = com.generald.lyra を定義
Package.swift リンカフラグ -sectcreate __TEXT __info_plist で Mach-O の __TEXT,__info_plist セクションに埋め込む(バンドルリソースではなくセクション埋め込みなので exclude も指定)
Makefile (install) codesign --force --sign - で署名にバインド
.github/workflows/auto-tag.yml リリース tarball を作る両パッケージングブロックで同じ再署名を実施
version.txt 2.15.02.15.1(patch)

なぜ再署名が要るのか

swift build -c release の ad-hoc 署名は __info_plist セクションを埋め込みはするが 署名にバインドしないcodesign -dvvInfo.plist=not bound)。codesign --force --sign - で明示的に再署名すると、codesign が埋め込み CFBundleIdentifier から Identifier を自動導出してバインドする。Homebrew formula は CI ビルドのバイナリをそのまま libexec.install するので、バインドは CI パッケージングmake install の2か所で行えば全配布経路をカバーできる。

設計判断(Cache-Aside ではなく "embed at link, bind at sign"): 代替案として「アプリバンドル (.app) 化して Info.plist をリソースとして同梱」も検討したが、lyra は単一ファイル CLI として Homebrew 配布される設計なので、Mach-O セクション埋め込みの方が配布形態を変えずに済む。トレードオフは「otool -P でしか中身を確認できない(Finder では見えない)」点だが、CLI ツールとしては許容範囲。

動作確認 — UTM VM

クリーンな UTM ゲスト (macOS 26.5.1 / arm64) にビルド済みバイナリを送り込み、埋め込み・再署名・実行を実機相当で検証した。

1. 埋め込み Info.plist が Mach-O に載っているか(otool -P

(__TEXT,__info_plist) section
<plist version="1.0">
<dict>
  <key>CFBundleIdentifier</key>
  <string>com.generald.lyra</string>
  ...
</dict>
</plist>

2. codesign バインド before / after(make install / CI と同じ codesign --force --sign -

段階 Identifier Info.plist
beforeswift build -c release の ad-hoc) lyra not bound
aftercodesign --force --sign - com.generald.lyra entries=4
codesign -dvv 生ログ(ゲスト内)
===== BEFORE re-sign =====
Identifier=lyra
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set

===== AFTER re-sign (codesign --force --sign -) =====
Identifier=com.generald.lyra
Signature=adhoc
Info.plist entries=4
TeamIdentifier=not set

→ TCC が bundle identity で権限グラントをキーできる状態になった。

3. 無回帰 — 再署名後もオーバーレイは正常描画

再署名でバイナリの cdhash が変わるため、署名済みバイナリでデーモンを再起動し(PID 28492 / Identifier=com.generald.lyra で稼働)、オーバーレイが描画されることを確認した。MediaRemote ヘルパーも実 now-playing データを取得できている(ヘッダーにアートワーク+曲名)。

UTM macOS 26.5.1 ゲストで稼働する lyra オーバーレイ(埋め込み Info.plist 版)

フォローアップ

  • NSAudioCaptureUsageDescription(音声キャプチャの利用目的文字列)は Add spectrum analyzer overlay #23 の実装 PR で追加する。投機的に空の権限設定を足さない方針。
  • ローカル(debug/release ビルド、make install)でもバインド済みバイナリの実行を確認済み。

Closes なし(#23 の前提解消。アナライザ本体は #23 で継続)。

Summary by CodeRabbit

  • Bug Fixes

    • Improved macOS binary code-signing to properly support system permission features.
  • Chores

    • Version bumped to 2.15.1.

TCCは権限グラント(将来のスペクトラムアナライザのシステム音声キャプチャ等)を
bundle identityでキーする。埋め込みInfo.plistが無いとグラントは実行ファイルの
パスにキーされ、再インストールごとにリセットされる。これが#23のBLOCKER。

- Sources/CLI/Info.plist: CFBundleIdentifier=com.generald.lyra を定義
- Package.swift: -sectcreate __TEXT __info_plist でMach-Oに埋め込む
  (バンドルリソースではなくセクション埋め込みなので exclude も指定)
- Makefile / CI(auto-tag.yml): `codesign --force --sign -` で署名にバインド
  swift build -c release のad-hoc署名はInfo.plistをbindしないため再署名が必要
Copilot AI review requested due to automatic review settings June 15, 2026 10:18
@GeneralD GeneralD self-assigned this Jun 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@GeneralD, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 55 minutes and 26 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3915176f-6307-4da6-8e18-804e1cdd1b38

📥 Commits

Reviewing files that changed from the base of the PR and between ff7b485 and b0cd360.

📒 Files selected for processing (1)
  • .claude/rules/vm-verification.md
📝 Walkthrough

Walkthrough

Adds Sources/CLI/Info.plist defining bundle metadata (CFBundleIdentifier: com.generald.lyra), embeds it into the CLI Mach-O binary via Package.swift linker sectcreate flags, and inserts ad-hoc codesign steps into the Makefile install target and both paths of the CI packaging workflow. The version is bumped to 2.15.1.

Changes

Bundle Identity and Ad-hoc Codesign

Layer / File(s) Summary
Info.plist definition and Mach-O embedding
Sources/CLI/Info.plist, Package.swift
Info.plist is introduced with CFBundleIdentifier com.generald.lyra and related keys. Package.swift excludes it from SwiftPM resource processing and instead embeds it into the __TEXT,__info_plist Mach-O section via unsafeFlags with -Xlinker -sectcreate.
Ad-hoc codesign in Makefile and CI, version bump
Makefile, .github/workflows/auto-tag.yml, Sources/VersionHandler/Resources/version.txt
Makefile install target adds codesign --force --sign - after binary deployment. The CI workflow inserts the same step in both the new-release packaging path and the existing-release missing-asset path. version.txt is bumped from 2.15.0 to 2.15.1.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 Hopping through the Mach-O maze,
A plist tucked in __TEXT's haze,
The bundle ID now signs with flair,
TCC grants float through the air,
codesign --force — and lyra's away! 🎵

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is in Japanese and references issue #23, but uses non-descriptive terms that obscure the primary change. The main objective—embedding Info.plist for TCC permissions—is not clearly conveyed in the PR title. Consider using English and a more specific title like 'Embed Info.plist in binary for stable TCC bundle identifier' to clearly communicate the primary change.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/23/embed-info-plist

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

#291の署名バインドの検証方法をプロジェクトの検証レーンに反映。
併せて実地で踏んだ2点のgotchaも記録:
- run-lyraの「daemon crashed at startup」はswift-interpret初回起動の
  遅延によるfalse negativeがある(pgrepで生存確認すべき)
- run-lyra同時実行は/tmp/lyra-dropのscp衝突を起こすため禁止
- env表にLYRA_VM_SSH_HOST(Apple Virtualization backend必須)を追加
@GeneralD GeneralD merged commit 886440e into main Jun 15, 2026
3 checks passed
@GeneralD GeneralD deleted the feat/23/embed-info-plist branch June 15, 2026 10:27
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants