Signing Builds

Generating the keys

From the root of your Android tree, run these commands, altering the subject line to reflect your information:

subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
mkdir ~/.android-certs
for x in releasekey platform shared media networkstack testkey; do \
    ./development/tools/make_key ~/.android-certs/$x "$subject"; \

You should keep these keys safe, and store the passphrase in a secure location.

Generating an install package

Generating and signing target files

After following the build instructions for your device, instead of running brunch <codename>,
run the following:

breakfast <codename>
mka target-files-package otatools

Sit back and wait for a while – it may take a while depending on your computer’s specs. After
it’s finished, you just need to sign all the APKs:

./build/tools/releasetools/sign_target_files_apks -o -d ~/.android-certs \
    $OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \

Generating the install package

Now, to generate the installable zip, run:

./build/tools/releasetools/ota_from_target_files -k ~/.android-certs/releasekey \
    --block --backup=true \ \

Then, install the zip in recovery as you normally would.

Changing keys

Using a migration build

You can set up your own migration builds by running:

LineageOS 16.0:

repopick 239520

LineageOS 15.1:

repopick -f 192655 -P vendor/lineage
repopick -f 192656 -P frameworks/base

LineageOS 14.1:

repopick 156047 162144

Then, follow the instructions to generate an install package.

Going back

After installing the migration build, you can switch back to building normal builds:

LineageOS 16.0:

cd frameworks/base
git reset --hard github/lineage-16.0

LineageOS 15.1:

cd vendor/lineage
git reset --hard github/lineage-15.1
cd frameworks/base
git reset --hard github/lineage-15.1

LineageOS 14.1:

cd vendor/cm
git reset --hard github/cm-14.1
cd frameworks/base
git reset --hard github/cm-14.1

Using a script

You can also use a script or small flashable zip designed to be run once, before installing
a build with the new keys. The script is available under

The script can also be made into a zip, by inserting it into a zip similar to
this. This zip has the script placed in
META-INF/com/google/android/update-binary with some additions to print status messages to
the recovery.

Test-keys to official or vice versa

If you are moving from a test-keys build (eg an “unsigned” unofficial build) to an official
LineageOS build, you can push the script to your device and run it from Android:

adb root # This requires an userdebug/eng build and ADB root access to be enabled
adb shell stop
adb push ./lineage/scripts/key-migration/ /data/local/tmp/
adb shell chmod +x /data/local/tmp/
adb shell sh /data/local/tmp/ official
adb reboot recovery
# Now install the official LineageOS install zip

Or run it from recovery:

# Ensure both /data and /system are mounted, then continue
adb push ./lineage/scripts/key-migration/ /data/local/tmp/
adb shell chmod +x /data/local/tmp/
adb shell /data/local/tmp/ official

If you are migrating from an official build to your own “unsigned” builds, you can run the
script in the same way, but instead using the argument “unofficial” instead of “official”.

Test-keys to your own release-keys or vice versa

If you are moving from test-keys to your own signed builds, you can add your own keys to the
script. First, export your keys to the required format, by running the script in

This will print the keys and certs to the terminal in the format required. Next, edit the
script to use your keys. You will need to comment out (by prepending a #), or remove the
existing definitions of the “release” keys and certs. Now, copy and paste your output from
above into the script where the previous lines were. Make sure to leave the “test” keys and
certs definitions untouched.

Your script is ready to go! Push it to the device and run it, in the same way as described
above, then install your own signed zip. If you ever need to run this in reverse, simply
use the “unofficial” argument instead of “official”, and your keys will be replaced with
the official keys.

Content of this page based on informations from LineageOS Wiki, under CC BY-SA 3.0 licence.