Security

    Mobile signing materials are sensitive. Here is exactly how Corenna handles your keys, secrets, and builds.

    Download security whitepaper (PDF)

    Security Controls

    Builds run on your GitHub

    Corenna does not clone your source to its own servers. We orchestrate workflows on GitHub Actions runners inside your repository. Source code never leaves the GitHub trust boundary.

    Signing materials

    Android keystores, key passwords, Apple certificates (.p12), and provisioning profiles are encrypted at rest with authenticated encryption. Passwords are stored separately from the keystore blob in an encrypted vault and never written to logs or build output. Plaintext passwords never touch browser storage — see the credential lifecycle section below.

    Secrets in transit

    Signing materials are pushed into your repo's GitHub Actions Secrets using GitHub's libsodium sealed-box encryption. They are decrypted only inside ephemeral runners.

    Access control

    All endpoints require an authenticated session. Row-level security on the database scopes every read and write to the owning user, and file storage is partitioned by user folder.

    Build integrity

    Each build carries a per-build HMAC token for status updates. Terminal-state guards block replay once a build is finalized, and artifact URLs are validated server-side (HTTPS-only, length-capped, no javascript:/data:/file: schemes).

    Log handling

    Build logs are streamed from GitHub Actions and stored for retrieval. We redact known secret patterns server-side before display. Do not paste plaintext secrets into build configuration files.

    Independent validation

    Our backend has been pen-tested for token replay, workflow_dispatch abuse, and cross-tenant data access. The most recent test returned zero findings.

    Your control

    Rotate keystores, revoke certificates, export your data, or delete your account at any time from Settings. Deletion removes all signing materials within 7 days.

    Keystore credential lifecycle

    The two most sensitive values Corenna handles are the Androidkeystore_passwordandkey_password. Here is exactly where they live, and when they are wiped.

    At rest (server)

    Stored only as encrypted secrets in our managed vault. Thesigning_configstable holds vault secret IDs (UUIDs), never the plaintext password.

    In transit (server → GitHub)

    Decrypted inside an edge function, immediately re-encrypted with GitHub's libsodium sealed-box, and written to your repository's GitHub Actions Secrets. The plaintext exists only inside the edge function's request memory and is garbage-collected when the function returns.

    In transit (server → browser)

    Returned by thereveal-keystorefunction over HTTPS only when you click "Show keystore credentials" on the project page. The response is never cached.

    In the browser (memory only)

    Held in a single React useState (keystoreReveal) on the Project Detail page. Never written to localStorage, sessionStorage, IndexedDB, cookies, or any service-worker cache.

    When they are wiped

    • You close the "Keystore credentials" dialog.
    • You navigate away from the Project Detail page (component unmounts).
    • You reload the tab.
    • You close the tab or browser.

    After any of these, the only way to see the password again is to re-authenticate and click "Show keystore credentials" again. The only persisted browser state is a boolean acknowledgment flag in sessionStorage recording that you confirmed you saved your keystore.

    Runtime guard (defense in depth)

    A runtime guard wraps localStorage, sessionStorage, and document.cookie to detect and reject any write whose key or value matches keystore-credential patterns. Blocked attempts throw an error, log to the browser console, and surface a destructive toast in the UI so the issue is visible immediately.

    Responsible disclosure

    If you believe you have found a security vulnerability, please email security@corenna.app with reproduction steps. Do not publicly disclose the issue until we have had a reasonable opportunity to investigate and respond.

    Your responsibilities

    • Use a strong, unique password for your Corenna account.
    • Keep your GitHub App installation scoped to repositories you actually build.
    • Rotate keystore and certificate passwords if you suspect compromise.
    • Back up your Android keystore — losing it prevents future Play Store updates of the same app.