APK Signer¶
Mozilla’s APK signing library and service
Description¶
The APK signing service is responsible for signing APK (Android package files) with developer keys so that the APKs can be integrated securely into the Android ecosystem.
See also:
Contents¶
API¶
Here is the web API offered by the APK Signer. Here are some URLs where you can find a deployed APK Signer:
- production
- TBD
- stage
- https://apk-signer.stage.mozaws.net/
All APIs accept standard application/x-www-form-urlencoded
POST parameters.
Authorization¶
All incoming and outgoing requests are secured by a Hawk shared key.
The setting HAWK_CREDENTIALS
is a dictionary of consumers and credentials.
The following credentials are defined for use:
- apk-factory
- The APK Factory will communicate with the signing service to sign APKs. All incoming requests to the signer must be signed with these credentials. As per Hawk, the server signs its response using the same credentials that the request was signed with.
All Hawk requests must sign their request payload (request body plus request content-type). If both of these are blank, such as in a GET request, you must sign them as empty strings.
Authorized API requests will respond with a Hawk header that signs the response, including payload. For the best security, make sure your client is authorizing incoming Hawk responses.
Signer¶
-
POST
/sign
¶ This endpoint accepts an unsigned APK file and returns a new APK file that has been signed with an Android key store. This signing process works just like the standard Android signing process.
Request
Parameters: - apk_id – A unique identifier for this APK such as one derived from a webapp manifest URL. This value will be used as an Amazon S3 storage key.
- unsigned_apk_s3_path – An Amazon S3 path (in a shared bucket) to the unsigned
APK file that should be fetched and signed.
Example:
/path/to/unsigned/file.apk
. - unsigned_apk_s3_hash – A SHA256 content hash (in hex) that can be used to verify the contents of the APK file after fetching it from Amazon S3.
- signed_apk_s3_path – An Amazon S3 path (in a shared bucket) that the final, signed APK file
should be written to.
Example:
/path/to/signed/file.apk
.
Response
Parameters: - signed_apk_s3_url – A publicly accessible Amazon S3 URL to the signed APK file.
Example:
{"signed_apk_s3_url": "https://s3.amazonaws.com/bucket/key/to/signed.apk"}
Status Codes: - 200 OK – success.
- 400 Bad Request – request was invalid.
- 403 Forbidden – authentication error.
System¶
There are some system APIs you can use to monitor the health of the APK Signer system.
-
GET
/system/auth
¶ This endpoint lets you test your Hawk client to see that you are making authorized GET requests correctly.
-
POST
/system/auth
¶ You can also POST to the same endpoint to test an authorized Hawk request.
Response
Example response to GET:
{"message": "GET authentication successful"}
Example response to POST:
{"message": "POST authentication successful"}
Status Codes: - 200 OK – success.
- 403 Forbidden – authentication error.
-
GET
/system/cef
¶ A request to this endpoint will log an internal CEF (Common Event Format) message. This will let you test that the system is hooked up for CEF logging.
Response
Example:
{"message": "CEF messages sent"}
Status Codes: - 200 OK – success.
-
GET
/system/log
¶ A request to this endpoint will send a test message to the internal logging system. This will let you test that the system is hooked up for logging.
Response
Example:
{'message': 'messages logged on server'}
Status Codes: - 200 OK – success.
-
GET
/system/stats
¶ A request to this endpoint will increment a statsd key for testing purposes.
Response
Example:
{"message": "apk_signer.system_check incremented"}
Status Codes: - 200 OK – success.
-
GET
/system/tools
¶ This endpoint reports whether or not the required command line tools are available.
Response
Example of 200 response:
{"detail": {"success": true, "keytool": "ok", "jarsigner": "ok"}}
Example of 409 response:
{"detail": {"success": false, "keytool": "MISSING", "jarsigner": "ok"}}
Status Codes: - 200 OK – success.
- 409 Conflict – conflict.
-
POST
/system/trace
¶ A request to this endpoint will trigger an exception to test that exceptions are handled correctly.
Response
N/A
Status Codes: - 500 Internal Server Error – internal error.
Development¶
Here’s a guide for how to hack on the APK Signer project.
Developer Setup¶
Set yourself up for local development using Python 2.7 and a virtualenv (recommended: virtualenvwrapper) like:
git clone git@github.com:mozilla/apk-signer.git
cd apk-signer
mkvirtualenv apk-signer
pip install --no-deps -r requirements/dev.txt
Make sure you create a local settings file:
cp apk_signer/settings/local.py-dist apk_signer/settings/local.py
Running Tests¶
./manage.py test
This uses django-nose so you can do all the nose things you’re probably used to.
Running A development server¶
Take a look at apk_signer/settings/local.py
and fill in some local settings
according to the comments. You’ll probably need to set some things up like
Amazon S3 storage credentials.
When you’re ready, start a development server like:
./manage.py runserver
Then open http://127.0.0.1:8000/
Working On Docs¶
pip install --no-deps -r requirements/docs.txt
make -C docs/ html
Deployment¶
Before configuring the app for deployment, read through Development; some concepts may apply.
See apk_signer/settings/sites/*
for site-specific settings files.
The signer can run in two user modes (in Django settings):
APK_USER_MODE = 'END_USER'
APK_USER_MODE = 'REVIEWER'
- REVIEWER mode
- The signer instance is intended for app reveiwers. In this mode APKs are self-signed with a short lived key store. Key stores are never re-used.
- END_USER mode
- The signer instance is intended for end-users on Firefox for Android. In this mode APKs are self-signed with a long-lived key store that is associated with the app’s manifest URL. When an app is updated, the same key store is used to sign new APK versions.