Skip to main content
SG ScreenGuardian

Security Policy

Responsible disclosure

If you've found a security issue in the ScreenGuardian app or website, please report it privately so we can fix it before it's public.

Email: screenguardian.info@gmail.com Subject line: security: <short summary>

Please include:

  • Which component (desktop app, website, update manifest, etc.)
  • Version(s) affected
  • A clear reproduction or proof-of-concept
  • Your assessment of impact

We acknowledge every report within 3 business days and aim to ship a fix or documented mitigation within 30 days for high-severity issues. You can request to be credited in the changelog.

Please do not exploit the issue against users or infrastructure beyond what's needed to demonstrate the bug. We won't take legal action against researchers who follow this policy in good faith.

Scope

In scope:

  • The ScreenGuardian desktop application (signed binaries we ship)
  • The auto-updater (app/native_updater.py, Sparkle/WinSparkle integration, signed manifests at screenguardian.app/updates/*)
  • The beta-code verifier
  • The screenguardian.app website

Out of scope:

  • Social engineering / phishing
  • Denial-of-service against Cloudflare / GitHub infrastructure
  • Vulnerabilities in third-party dependencies without a working exploitation path against ScreenGuardian

Signing architecture

Every update we publish is signed twice:

  1. Installer signatures (OS-level):
    • macOS: Apple Developer ID + notarization via Apple's notarytool.
    • Windows: Authenticode signatures (Azure Trusted Signing or a traditional OV/EV code-signing certificate).
  2. Release manifest signatures (Ed25519):
    • An Ed25519 keypair generated by scripts/generate_update_keys.py.
    • The public key is compiled into the app (app/version.py UPDATE_PUBLIC_KEY_BASE64).
    • The private key lives only in GitHub Actions as the UPDATE_SIGNING_KEY secret and in the project owner's password manager.
    • Every latest.json, appcast.xml, and beta-codes.json on the website is signed, and Sparkle/WinSparkle verify the signature before downloading or installing anything.

If either layer ever fails to verify, the update is refused. No single-layer compromise is sufficient to ship a malicious update.

Key rotation

If the Ed25519 signing key is suspected compromised:

  1. Generate a new keypair (scripts/generate_update_keys.py).
  2. Ship a new app version with the new public key. Existing users get it through the still-trusted old key.
  3. Once the population has updated (~2-4 weeks, tracked in update telemetry after opt-in lands), rotate the GitHub Actions secret and begin signing new releases with the new key.
  4. Document the rotation in the changelog.

Apple/Windows signing cert rotations follow the respective vendors' normal certificate-renewal flow.

Dependencies

We track upstream advisories for our runtime dependencies:

  • MediaPipe, OpenCV, NumPy, Pillow (vision stack)
  • PySide6 (UI)
  • cryptography (manifest verification)
  • Sparkle / WinSparkle (auto-update)

GitHub Dependabot is enabled on the repository to surface advisories automatically.