Skip to content

fix(android): protect credentials with Android Keystore - #838

Merged
H-Chris233 merged 13 commits into
Open-Less:betafrom
appergb:agent/issue-817-android-keystore
Jul 18, 2026
Merged

fix(android): protect credentials with Android Keystore#838
H-Chris233 merged 13 commits into
Open-Less:betafrom
appergb:agent/issue-817-android-keystore

Conversation

@appergb

@appergb appergb commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

User description

Fixes #817

Summary

  • replace the reversible Android Base64 credential envelope with AndroidKeyStore-backed AES-256-GCM
  • add a strict authenticated envelope, verified crash-safe legacy migration, rollback marker, and fixed JNI status boundary
  • keep the Marketplace bearer process-memory-only on Android
  • add JVM, instrumentation, Rust migration/fault-injection tests, plus x86_64 Android CI coverage

Validation

  • bundle SHA-256 verified: 8d015882b6d549288f5762baac281c802913d1b1bbe7d0bff213767cc25e1238
  • imported bundle HEAD verified: a1dacbafea0463c71cf17f251ed23b57a5f54135
  • CI-only and test-fixture follow-ups culminate at f8296bff48d4e855a5d4718b39cef5c68c052957
  • npm test passed all 24 frontend/contract tests after initializing the pinned submodule
  • targeted Rust Android credential tests: 5 passed after reusing one simulated Keystore instance across the migration reload
  • Android Gradle/JVM/instrumentation and emulator coverage passed in PR CI

PR Type

Bug fix, Enhancement, Tests


Description

  • Protect Android credentials with Keystore-backed AES-256-GCM

  • Add crash-safe migration scrubbing Marketplace tokens

  • Implement JNI bridge and Kotlin Keystore vault classes

  • Add JVM, instrumentation, and CI test coverage


Diagram Walkthrough

flowchart LR
    legacy["Base64 Envelope"] -->|read & sanitize| sanitized["Bearer-free Base64"]
    sanitized -->|migrate| new_env["V2 AES-GCM Envelope"]
    new_env -->|decrypt/encrypt| keystore["Android KeyStore"]
    keystore -->|rollback barrier| marker["Migration Complete Marker"]
    new_env -->|fail-closed| secure_remove["Secure Erase on Failure"]
Loading

File Walkthrough

Relevant files
Enhancement
5 files
android_credentials.rs
New Keystore-backed credential store module                           
+1285/-0
credentials.rs
Integrate Keystore vault with migration                                   
+237/-245
jni.rs
Add JNI bridge for Keystore operations                                     
+214/-1 
OpenLessCredentialVault.kt
Kotlin Keystore vault facade                                                         
+184/-0 
OpenLessCredentialCipher.kt
Pure AES-GCM packet codec                                                               
+45/-0   
Configuration changes
3 files
mod.rs
Register android_credentials module                                           
+2/-0     
copy-android-scaffolding.mjs
Copy test scaffolding to generated project                             
+65/-14 
ci.yml
Add Android x86_64 CI and emulator tests                                 
+63/-2   
Tests
3 files
OpenLessCredentialCipherTest.kt
JVM unit tests for AES-GCM cipher                                               
+111/-0 
OpenLessCredentialVaultInstrumentedTest.kt
Instrumented Keystore integration tests                                   
+89/-0   
android-credential-keystore-contract.test.mjs
Contract tests for Keystore implementation                             
+248/-0 

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit 11fb522)

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

817 - Partially compliant

Compliant requirements:

  • Protect persisted Android credentials with Android Keystore-backed authenticated encryption using a non-exportable key, unique nonce per write, and atomic owner-private storage.
  • Bind ciphertext format/version and account key as authenticated data; reject tampering and fail closed.
  • Migrate legacy Base64 envelopes without exposing values to logs/events/frontend; delete the legacy plaintext-equivalent file only after verified migration.
  • Define safe behavior for locked/unavailable/invalidated Keystore keys. Marketplace OAuth token remains memory-only on Android and requires re-login after restart.
  • Add Android/JVM or instrumented tests for round-trip, tamper, key invalidation, migration, file permissions, and secret non-exposure.

Non-compliant requirements:

(empty)

Requires further human verification:

  • "Independently security-review the implementation before merging." This is an organizational process step, not verifiable from the code alone.
⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit b34870a

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 470de3b

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit aa1ddbe

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit f8296bf

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit c163070

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit e28772a

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 3c186cb

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 1cb899e

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 11fb522

@H-Chris233
H-Chris233 merged commit 75918e0 into Open-Less:beta Jul 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security(android): replace the Base64 credential envelope with Keystore-backed protection

3 participants