Core concepts

Certificate Vault (Signing)

3 min read

The Certificate Vault stores the signing keys used to sign your Android APKs. Lunadeck supports two signing paths:

  • Hobby tier — every build is signed with a shared Lunadeck-managed debug keystore. No setup, but the cert is shared across all Hobby users so it cannot be published to the Play Store.
  • Starter tier and above — bring your own .jks or .keystore. Encrypted at rest, decrypted only inside the build worker, never logged. Eligible for Play Store publishing.

Lunadeck-managed debug keystore (Hobby)

Every Hobby build is signed with one shared self-signed keystore. The same certificate is used for everyone, so a Hobby APK is fine for sideloading and evaluation on your own device — it cannot be published to the Google Play Store (Play Store requires each developer to control their own signing key).

The keystore is stored once in our infrastructure and never rotates, so an APK you build on Lunadeck this year can still receive sideload updates from a Hobby APK you build next year (Android refuses signature changes on the same package).

Fingerprints

Verify any APK signed by the Lunadeck-managed debug keystore against these values:

AlgorithmFingerprint
SHA-2561D:A8:E4:00:7E:5F:19:15:85:BF:AA:71:FD:BA:55:88:74:43:D2:0B:6B:43:A7:C6:A2:88:C5:45:6A:CC:50:7B
SHA-170:FB:10:86:5B:D7:9D:0D:00:C3:1A:2A:79:0F:B2:FF:66:E1:25:7C

Certificate subject: CN=Lunadeck Debug, OU=Debug, O=Lunadeck, L=Unknown, ST=Unknown, C=US.

Verifying a downloaded APK

Run apksigner (ships with the Android SDK build-tools) against your downloaded APK and confirm the SHA-256 line matches the fingerprint above:

apksigner verify --print-certs your-app.apk

You should see a line like:

Signer #1 certificate SHA-256 digest: 1da8e4007e5f191585bfaa71fdba558874...

If the SHA-256 digest does not match the value in the table, the APK was not signed by Lunadeck — do not install it.

Upgrading to your own signing key

If you need a Play Store-ready APK, upgrade to Starter or higher and upload your own keystore — see Uploading a keystore below.


Bring your own keystore (Starter+)

Your uploaded .jks or .keystore is stored encrypted at rest using AES-256-GCM with a per-org key derived from a master KMS key. The decrypted key only ever lives in memory inside the build container and is never written to logs or build artifacts.

Uploading a keystore

  1. Navigate to Settings > Certificate Vault in the dashboard
  2. Click Upload Keystore
  3. Provide your .jks or .keystore file
  4. Enter the keystore password, key alias, and key password
  5. Save — credentials are encrypted immediately

Automatic signing

Once a keystore is uploaded and assigned to a project, every build of that project will be signed with it. The signing step runs after compilation and before the artifact is made available for download.

Generating a new keystore

If you don't have a keystore, Lunadeck can generate one for you:

  1. Go to Certificate Vault > Generate New
  2. Fill in the required fields (organization, country, etc.)
  3. A new keystore will be generated and stored securely

Best practices

  • Keep a backup of your keystore outside of Lunadeck — losing the key means you cannot publish updates of your app to the Play Store ever again
  • Use separate keystores for debug and release builds
  • Rotate keys periodically for enhanced security