App embeds the CA of the machine that builds it
PinnedCert.kt no longer carries a pasted certificate. The build reads $XDG_CONFIG_HOME/ai-app/certs/ca.pem (AI_APP_CA overrides) and generates the constant, so the trust anchor follows the build machine: an APK built on the backend host pins that host, and one built in the dev VM pins the VM's throwaway CA and is good only for its emulator. That removes the reason to add a second trust anchor for development -- there is nothing to add and then forget to remove -- and it means the private key never has to exist near this repo, which the VM can write. Regenerating a CA now needs a rebuild instead of a paste, so a stale constant can't quietly disagree with the server. build-apk.sh is the missing counterpart to run-android.sh: it produces the APK to install through Local Updater and touches no emulator. It finds the SDK from ANDROID_HOME/ANDROID_SDK_ROOT before falling back to ~/Android/Sdk, since the host doesn't share the VM's layout, and prints the fingerprint of the CA being pinned so a wrong one is visible there rather than as a handshake failure on the phone. Verified end to end on the emulator against a server using a freshly generated CA -- which is how the first attempt was caught: the generated constant began with a newline, so CertificateFactory lost the "-----BEGIN" sniff, tried DER, and failed at runtime with an ASN.1 decode error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw
This commit is contained in:
1 parent
ce349af414
commit
eeb2dde4ab
6 files changed
+209
-37
No files matched your search
@@ -262,6 +262,16 @@ complete path out of everything spawning one created.
|
||||
- TLS with a self-signed CA, pinned in the app — `gen-dev-cert.sh` and
|
||||
`PinnedCert.kt` copied from local-updater, same idempotent-CA/reissued-leaf
|
||||
scheme, same one-way-door caveat about regenerating the CA.
|
||||
- Unlike local-updater, the pinned CA is **not a constant in the source**:
|
||||
the build reads `$XDG_CONFIG_HOME/ai-app/certs/ca.pem` from the machine
|
||||
doing the build and generates the constant (`generatePinnedCert` in
|
||||
`app/androidApp/build.gradle.kts`; `AI_APP_CA` overrides). Decided
|
||||
2026-08-25, and it does three things at once — the trust anchor follows
|
||||
the build machine, so an APK built on the backend host pins that host
|
||||
and one built in the dev VM pins the VM's throwaway CA and is only good
|
||||
for its emulator; there is no second anchor to add for development and
|
||||
forget to remove; and regenerating a CA needs a rebuild rather than a
|
||||
paste, so a stale constant can't quietly disagree with the server.
|
||||
- **The dev VM is untrusted** (decided 2026-08-25): a machine that isn't
|
||||
malicious but could become so. It matters because the repo is a
|
||||
read-write virtiofs mount shared between the VM and the backend host, so
|
||||
|
||||
Reference in new issue
Block a user