Skip to content

Align Android signing hardening with gptme: base64 keystore secret, cert pinning, fail-closed #208

Open

Description

@ErikBjare

gptme/gptme#3409 adopted this repo's signing flow (zipalign + apksigner for APKs, jarsigner for AABs, passwords via env) and hardened it. To keep the two projects on one consistent, battle-tested strategy (cross-referenced in #207), migrate this repo to match:

  • Deliver the keystore as a base64-encoded secret (e.g. KEY_ANDROID_JKS_B64) instead of the age-encrypted android.jks.age committed in-repo; drop the age decryption step and adnsio/setup-age-action dependency. Keeps the keystore fully private instead of public-but-encrypted, and removes the extra age identity secret.
  • Pin the expected signer certificate SHA-256 as a non-secret repo/environment variable and verify every APK's signer fingerprint (apksigner verify --print-certs) plus jarsigner -verify -strict for AABs before upload.
  • Fail closed: release-tag builds should error out when signing secrets are missing, instead of the current Makefile fallback that ships unsigned artifacts ("No key secrets set, not signing"). Non-tag CI builds can keep the unsigned path.
  • Consider moving the signing secrets into a GitHub environment for scoping.

Reference implementation: gptme/gptme .github/workflows/tauri.yml (release-android job) and docs/contributing.rst "Android release signing".

Note: the store/key passwords stay the same; only the keystore delivery mechanism changes, so this is a workflow-only migration plus one new secret + one variable.

Activity

  1. TimeToBuildBob commented on Aug 5, 2026

    @TimeToBuildBob
    Contributor

    PR up: #212

    Migrates all three signing/credential steps across build.yml and release.yml:

    • Keystore: age-encrypted android.jks.age → KEY_ANDROID_JKS_B64 (base64 secret)
    • Fastlane API: age-encrypted .json.age → KEY_FASTLANE_API_B64 (base64 secret)
    • adnsio/setup-age-action dropped from both files
    • Fail-closed check on release tags when any signing secret/variable is missing
    • Cert SHA-256 pinning via ANDROID_CERT_SHA256 repo variable (verified in both build.yml and sign_apk.sh)
    • Deleted android.jks.age and fastlane/...json.age from repo

    Operator steps to activate (before next release tag) are in the PR description.

  2. added a commit that references this issue on Oct 11, 2026
    ad73601
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions