From MozillaWiki
Jump to: navigation, search

General Info


WebApps can run in one of three privilege levels. In order to run as any form of packaged app, the app must be signed. This document describes how packages are signed in Mozilla's Marketplace infrastructure.


The full URI for the service including the version string for the API as defined below
version string 
This revision of the protocol is 1.0 so the version string is "/1.0/"
user agent 
a b2g device or Mozilla delivered desktop browser
root certificate 
the app signing CA's root certificate in standard X.509 format. This certificate will be included in each build of the user agent.
signing key and certificate 
the credentials used by the signing service to generate the PKCS#7 signature. This will be certified by the root certificate.
unsigned archive 
a JAR file that has been uploaded by a developer but not signed by the service yet
signed archive 
a JAR file that has been created by Zamboni to include the contents of the unsigned archive and the generated manifest and signature files

Related documentation

JAR signing 
JDK documentation
JAR validation 
JDK documentation
Cryptographic Message Syntax is a brief intro with links

Data formats

The data formats are described in depth in the JDK documentation. There are three basic formats being dealt with:

  • Zip archives
  • An HTTP header like format for archive manifests and signatures
  • PKCS#7 detached signature in DER format


Signing clients

signing-clients is just a simple library for generating, parsing, and formatting the manifest and signature file formats.


The actual signing service. This is the same code base as the receipt signing service but runs in a separate process space to provide a degree of separation between app signing and receipt signing credentials.

Zamboni, packaged app handling specifically

Zamboni is responsible for receiving and storing an uploaded application archive, generating manifest and signature files for it via the signing-clients library, requesting a signature from the trunion signing service, and creating a new signed application archive containing the additional three files.


POST http
//<endpoint-url>/sign_app :
  • This takes an archive's signature file as multipart/form-data with a single input of the name "file" with a filename included.
  • It then returns a PKCS#7 detached signature of the uploaded content in a JSON object with a single key and value pair. The key is the uploaded content's specified filename with its extension(".sf") replaced with ".rsa". The value is a base64 encoded representation of the PKCS#7 data.

Example request

POST /1.0/sign_app HTTP/1.1
Host: localhost:5000
Content-Length: 306
Content-Type: multipart/form-data; boundary=df8e3fdaf425408e956aff8ca19d0263
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/0.14.2 CPython/2.7.1 Darwin/11.4.2

Content-Disposition: form-data; name="file"; filename="zigbert.sf"
Content-Type: application/octet-stream

Signature-Version: 1.0
MD5-Digest-Manifest: PTUbaADVign9DDK3ntq9ww==
SHA1-Digest-Manifest: FkVPRYqW9UT8kcbm8VS08TIWsH4=


Example response

Response body truncated for brevity.

HTTP/1.0 200 OK
Server: PasteWSGIServer/0.5 Python/2.6.8
Date: Wed, 28 Nov 2012 22:14:58 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 3607

{"zigbert.rsa": "MIIKfQYJKoZIhvcNAQcCoIIKbjCCCmoCAQExCzAJBgUrDgMCGgUAMAsGCSq...=="}

HTTP response codes

200 OK 
The request was processed successfully and the server is returning a PKCS#7 signature
401 Unauthorized 
The authentication credentials are invalid. At the moment authorization consists of a simple whitelist of IPs. In the future this may be used to indicate a BrowserID or other authentication mechanism has failed or the credentials are not authorized to use the service.
503 Service Unavailable 
Indicates that the server(s) are undergoing maintenance.