# Code signing

This covers the process of how to add / update code signing metadata of flutter
engine binaries.

## Overview

Flutter engine binaries are built with GN and ninja, referencing pre-defined
configurations such as ci/builders
[JSON files](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_host_engine.json).
During flutter releases, engineers need to code sign mac engine binaries to
assure users that they come from a known source, have not been tampered with,
and should not be quarantined by Gatekeepers.

Each of the Flutter engine binaries are either code signed with entitlements, or
code signed without entitlements. (An entitlement, along with information from
the developer account, grant particular permissions to binaries, such as
capability to access the user's home automation network.) For example, impellerc
is code signed with flutter entitlements, whereas .dylib files are usually code
signed without entitlements.

## Add / Update code signing metadata

### Glossary

1.  BUILD.gn files: files that include build rules of GN targets. An example is
    the
    [BUILD.gn file of flutter engine](https://github.com/flutter/flutter/blob/main/engine/src/flutter/BUILD.gn).
2.  leaf node of an engine binary: the minimal gn target that could produce such
    an engine binary. That is, this target does not have any dependencies on
    other gn targets that could build this engine binary.
3.  dependencies: Every gn target could have dependencies on other gn targets.
    The dependency of a gn target is defined in the `deps` field of the target's
    build rule.

### ways to generate engine binary

Generally, there are two ways to generate an engine binary:

1.  Through build rules defined in BUILD.gn files.

2.  Through global generator scripts. (these scripts are normally .py files)

To distinguish between the two, an engine binary is built through global
generator if it is listed in the `archives` -> `destination` field of the
builder JSON
([mac_ios_engine.json](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_ios_engine.json)
or
[mac_host_engine.json](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_host_engine.json)).
For example, `darwin-x64/FlutterEmbedder.framework.zip`. Whereas binaries built
with BUILD.gn files are listed among the `builds` field of the JSON file. For
example, `darwin-x64/artifacts.zip`. We will provide examples for both
scenarios.

### To add / update code signing metadata in BUILD.gn files:

1.  Find the leaf node where the target engine binary is built. To do so,
    Recursively trace the `deps` field of the engine artifact. The paths in
    `deps` field of the GN target correspond to the paths of other GN targets
    that are dependencies of the current GN target.

2.  Add / Update the `metadata` field of the leaf node. For a new engine binary:

    2.1 if it should be code signed with entitlements, add [the name of the
    engine binary] to the `entitlement_file_path` field in `metadata` .

    2.2 if the binary shouldn't be code signed with entitlements, add [the name
    of the engine binary] to the `without_entitlement_file_path` field in
    `metadata` .

3.  If a `entitlement_file_path` or a `without_entitlement_file_path` field does
    not exist:

    **note**: this step is only needed if the target includes solely binaries
    that have never been code signed before. This step also requires some
    background on flutter engine and gn build rules.

    Add a `metadata` field in the gn target of the leaf node, and put the name
    of the binary in this field. e.g.

    ```
    metadata = {
        entitlement_file_path = [ "libtessellator.dylib" ]
    }
    ```

    In the same file that produces the engine artifact(zip file), add a build
    rule to collect the data keys. e.g.

    ```
    generated_file("artifacts_entitlement_config") {
        outputs = [ "$target_gen_dir/entitlements.txt" ]

        data_keys = [ "entitlement_file_path" ]

        deps = [ "//flutter/lib/snapshot:generate_snapshot_bin" ]
        if (flutter_runtime_mode == "debug") {
            deps += [
            "//flutter/impeller/compiler:impellerc",
            "//flutter/impeller/tessellator:tessellator_shared",
            "//flutter/shell/testing:testing",
            "//flutter/tools/path_ops:path_ops",
            ]
        }
    }
    ```

    Finally, embed the file with collected data keys in the zip artifact. e.g.

    ```
    if (host_os == "mac") {
        deps += [ ":artifacts_entitlement_config" ]
        files += [
            {
            source = "$target_gen_dir/entitlements.txt"
            destination = "entitlements.txt"
            },
        ]
    }
    ```

#### Example

Suppose impellerc is a binary that exist in a zip bundle called artifacts.zip.
Then impellerc is the name of the binary, and artifacts.zip is the flutter
engine artifact.

1.  Following step 1, the `deps` field of the GN target of artifacts.zip
    includes the path of impeller dependency:
    `//flutter/impeller/compiler:impellerc`. Following this path, we locate the
    GN file at `flutter/impeller/compiler/BUILD.gn`, and find the leaf node that
    builds impellerc: `impeller_component("impellerc")`.

2.  Following step 2, since `impellerc` should be code signed with entitlements,
    we go to the `metadata` field of the impellerc target, and add the name
    `impellerc` to the `entitlement_file_path` array inside the `metadata`
    field.

You can reference the
[BUILD.gn file of impellerc](https://github.com/flutter/flutter/blob/main/engine/src/flutter/impeller/compiler/BUILD.gn).

### To add / update code signing metadata in global generator files:

1.  Find the generator script path listed under `generators` -> `tasks` ->
    `script` of the ci/builder JSON files
    ([mac_ios_engine.json](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_ios_engine.json)
    or
    [mac_host_engine.json](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_host_engine.json)).

    The generator script related to iOS is located at
    `sky/tools/create_ios_framework.py`, and generator script related to
    macOS is located at `sky/tools/create_macos_framework.py`.

2.  Add / Update the variables ending with `with_entitlements` /
    `without_entitlements` suffix from the generator script you found in step
    one.

    As an example, you can find variables `ios_file_without_entitlements` and
    `ios_file_with_entitlements` in sky/tools/create_ios_framework.py; and
    find variables `filepath_without_entitlements` and
    `filepath_with_entitlements` in sky/tools/create_macos_framework.py

    2.1 if the binary should be code signed with entitlements, add [the name of
    the binary] to the variable name with the `with_entitlements` suffix.
    (`ios_file_with_entitlements` or `filepath_with_entitlements` depending on
    which script)

    2.2 if the binary shouldn't be code signed with entitlements, add [the name
    of the binary] to the variable name with the `without_entitlements` suffix.

#### Example

Suppose `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` is a binary
that exist in a zip bundle called `ios/artifacts.zip`.

1.  Following step 1, in
    [mac_ios_engine.json](https://github.com/flutter/flutter/blob/main/engine/src/flutter/ci/builders/mac_ios_engine.json),
    it builds the artifact with the
    `flutter/sky/tools/create_ios_framework.py` script.

2.  Following step 2, since
    `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` shouldn't be code
    signed with entitlements, we add the binary name
    `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` to the
    `ios_file_without_entitlements` variable.

You can reference the generator script
[create_ios_framework.py](https://github.com/flutter/flutter/blob/main/engine/src/flutter/sky/tools/create_ios_framework.py).

## Code signing artifacts other than flutter engine binaries

The code signing functionality is implemented as [a recipe module in flutter recipes](https://cs.opensource.google/flutter/recipes/+/master:recipe_modules/signing/api.py). Therefore it can also be used to
code sign arbitrary flutter artifacts built through recipe, for example, flutter iOS usb dependencies.

To code sign, after the artifacts are built, pass the file paths into
the code signing recipe module and invoke the function. An example is [how engine V2 invokes the code signing recipe module](https://cs.opensource.google/flutter/recipes/+/master:recipes/engine_v2/engine_v2.py;l=197-212).
