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:
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:
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:
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:
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:
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:
POST /system/trace

A request to this endpoint will trigger an exception to test that exceptions are handled correctly.

Response

N/A

Status Codes:

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.

Indices and tables