Skip to content

feat: tool trust statement and signing CLI - #182

Closed
brunoro wants to merge 3 commits into
mainfrom
feat/tool-signing-signer-cli
Closed

brunoro wants to merge 3 commits into
mainfrom
feat/tool-signing-signer-cli

Conversation

@brunoro

@brunoro brunoro commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

This is the initial PoC for tool signing. Tool signing allows LightOS to distinguish tools built through the trusted Light pipeline from arbitrary APKs. It binds each tool ID to its developer and permanent APK signer, preserves build provenance, and provides the cryptographic identity that will later support approval and revocation lists.

The final flow will work as follows:

  1. The tool builder produces an unsigned APK and recipe.json.
  2. The signer checks the artifact and manifest against that recipe and the tool registry, then stamps the APK with a trust statement signed by the Light attestation key.
  3. The signer signs the stamped APK with the tool's permanent key.
  4. When the APK is installed, LightOS verifies the Android signature, attestation, signer identity, and APK metadata offline before applying the allowlist and blocklist policies.

This PR provides the tools for stamping, signing and verifying APKs in this flow.

Summary

  • add the initial tool trust statement schema, canonicalization, Ed25519 attestation support, and shared Python/Kotlin vectors
  • add a standalone signer CLI with keygen, stamp, sign, and verify commands
  • bind registered tool IDs to developers and permanent per-tool P-256 APK signing keys
  • validate unsigned APK hashes and manifest identity/version metadata before stamping
  • verify the final APK signature, trust-statement attestation, signer certificate, and manifest metadata offline
  • record the requested tool Git ref in recipe.json
  • target Android API 34 while retaining compile API 36 for current AndroidX dependencies
  • document PoC key custody, registry limitations, CLI usage, and future signed-envelope work

Testing

# signer unit suite and real Android signing round trip
cd signer
LIGHT_SIGNER_ANDROID_INTEGRATION=1 uv run --with pytest --env-file /dev/null python -m pytest -q tests

# builder unit suite
cd ../builder
uv run --with pytest --env-file /dev/null python -m pytest -q tests

# linting and type checks
cd ..
uv run --with ruff ruff check signer builder
uv run --with mypy mypy --strict signer/lightsigner builder/lightbuilder

# build an unsigned release APK targeting Android API 34
./gradlew :tool:assembleRelease -DlightSdk.unsigned=true

Notes

  • signer/keys/ is an ignored filesystem keystore intended only for the PoC. Production keys belong in KMS or an HSM.
  • signer/registry.json stands in for an authenticated developer portal and ownership database. This will be served by the Light backend when the feature is deployed.
  • The checked-in Ed25519 private key is explicitly test-only and is used solely for shared cross-language vectors.
  • JSON documents can have different byte representations across Python and Kotlin serializers, making JSON unsuitable as a shared signature input. This PoC uses naive minimal custom canonical JSON format. Serialization and canonicalization are a well-known attack surface, and standard signed-envelope formats are better suited to this role. Before production, we will replace the custom format with a standard such as DSSE.

@brunoro
brunoro requested a review from dupontgu August 27, 2026 17:19
@brunoro

brunoro commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

putting this on hold until we evaluate the AOSP SourceStamp functionality provided by the standard APK signing schema.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants