Skip to content

feat(push): add configurable private Apple profile - #7760

Open
rclod wants to merge 11 commits into
block:mainfrom
rclod:feat/agent-completion-push
Open

rclod wants to merge 11 commits into
block:mainfrom
rclod:feat/agent-completion-push

Conversation

@rclod

@rclod rclod commented Sep 19, 2026

Copy link
Copy Markdown

Summary

  • Let self-hosted operators define a private APNs application profile consistently across the push gateway, relay advertisement and lease validation, Helm deployment, and mobile client.
  • Add an overrideable universal iPhone/iPad app shell, notification-service extension identity, production push-gateway origin guard, and coherent per-profile notification snapshots.
  • Fail closed when runtime authority or profile ownership is missing, isolate credentials and grants by profile, and recover valid grants after ownership repair.
  • Stabilize ACP tests that spawn freshly written executables on Linux by retrying only ExecutableFileBusy errors.

This establishes the private signed-app and gateway path needed for self-hosted iOS push. Physical-device production signing, App Attest, and background/locked/terminated delivery validation remain an operator deployment gate rather than a claim of this PR.

Related issue

Fixes #5206.

Testing

  • just ci passed end to end in an isolated native arm64 Linux environment with an init process: formatting, Clippy, policy/security checks, 17 no-infrastructure Rust suites, 6,508 desktop tests, production web builds, 3,204 Tauri tests (19 platform-only ignores), and 2,256 Flutter tests (4 expected skips).
  • Separate unconfigured-build push tests passed 3/3.
  • Gateway PostgreSQL authority/bootstrap/readiness tests, relay push-lease and NIP-11 tests, Helm render/release checks, and the production iOS shell contract passed.
  • A native arm64 gateway image passed its non-root, port, CA bundle, entrypoint, and fail-closed startup contract checks.
  • Native XCTest and production APNs/App Attest validation require macOS, Apple signing credentials, and a physical device; those checks are intentionally deferred to the operator deployment gate.

No visible UI was changed, so screenshots are not applicable.

Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Pass the compiled app profile through the Dart-to-Swift snapshot boundary,
reject unsupported profiles, and select relay metadata from the matching
grant cohort. Keep both production persistence paths injectable so native
handler tests prove the contract without touching Keychain state.

Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Model PostgreSQL ownership recovery accurately by rerunning the idempotent
migration and grant path before expecting the runtime role to become ready.

Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
Freshly written adapter scripts can briefly fail with ETXTBSY under
parallel Linux test load. Retry only that bounded test-only condition so
the ACP suite reaches its protocol assertions reliably.

Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
@rclod
rclod requested a review from a team as a code owner September 19, 2026 18:38
@github-actions

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is ef2aa1ae38fadcc0bc22b8bf6ed96b35933146be...8a35d016e90b7fb930f83317aff3f936fd7f0052.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 8a35d016e90b7fb930f83317aff3f936fd7f0052 to authorize a new review.
Any previous review applies only to its recorded range.

rclod and others added 2 commits September 20, 2026 06:46
Xcode 27 raises the minimum deployment target to iOS 15 and ships Swift
6.4, which broke the iOS build in three ways:

- Several CocoaPods targets still declare iOS 10–13 minimums; lift them to
  the app's iOS 16 floor in the Podfile post_install hook.
- swift-secp256k1 0.21.1 no longer compiles (ambiguous `words` in
  UInt256); bump BuzzPushKit to 0.23.2, which rewrote that code. Its
  SharedSourcesPlugin build plugin needs a one-time trust in Xcode
  (or -skipPackagePluginValidation on the command line).
- Xcode 27 no longer forwards the generated module map for the package's
  libsecp256k1 C target to app targets that consume BuzzPushKit, so the
  P256K binary module cannot be loaded from Runner or NotificationService.
  Forward it explicitly via OTHER_SWIFT_FLAGS on both targets.

BuzzPushKit's 78 package tests pass on 0.23.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
(cherry picked from commit c9f096a)
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
`??` binds tighter than `==`, so the guard compared a `Bool?`-coalesced
`String` and failed to type-check. Accept a descriptor without an
`appProfiles` list only when the configured profile is the default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: rclod <3385524+rclod@users.noreply.github.com>
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.

NIP-PL on a self-hosted relay is unreachable by design: the default gateway is push.buzz.xyz and only block can sign APNs for the App Store app

1 participant