Signer recipe command line migration

led run 03/27 patchset 22:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/b6f51d410a2f26fb1766b10e844afc80fb5e2b7cc4282ea57be6e822ee6a5a04/+/build.proto?server=chromium-swarm.appspot.com

led run 03/27 patchset 20:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/4afa328e0dcfa2fbbf7f11934c97aebf5d0991eb644402e4bf499e2055619b80/+/build.proto?server=chromium-swarm.appspot.com

led run 03/27 patchset 18:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/af2c80b6a1f57ac57b6a5d7dd12409a15274f455644a824f6f454b90f8826abd/+/build.proto?server=chromium-swarm.appspot.com

led run 03/27 patchset 16:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/a3f8a69d36d1009faa73eb6d42f734f06a065540cca9c3f54ee8c25865f326e2/+/build.proto?server=chromium-swarm.appspot.com

led run 03/27 patchset 13:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/e7d129d8f49afacf8f06fedd6210be2ad3d9aa668ffae39adb74898a0f3a53bd/+/build.proto?server=chromium-swarm.appspot.com

led run 03/25 patchset 11:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/a44ca0c6a64e82c384d0f4612effcda2581029e5fe7dfd542653b624cd053ebf/+/build.proto?server=chromium-swarm.appspot.com

led run 03/25 patchset 9:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/3e3be689bac963a2e85a79afda1eaafb6ab416726fa9a1683f11d17652162f0d/+/build.proto?server=chromium-swarm.appspot.com

led run 03/25 patchset 6:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/6ea9024db20773d52a967e72870c07cc0544c8eaa51b38bbd58286e3a6694ec1/+/build.proto?server=chromium-swarm.appspot.com

led run 03/24 patchset 3:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/875f0539a3fddcf8741248198f5314428557248708678f04aef8e3c292b48d66/+/build.proto?server=chromium-swarm.appspot.com

led run 03/24 patchset 1: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/7554c4be4b1f8afda3db337c7cca605bc4ff3791d76b473050b55539e1316dd2/+/build.proto?server=chromium-swarm.appspot.com

scheduled with:
led get build <mac host engine at engine head> | led edit-recipe-bundle | led edit-system -p 20 | led launch

Once this lands, the next step is to push engine_v2 recipe to finish.

Change-Id: Ie564477abedac60235bac0c51f5513c35f9e9bf9
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/41123
Reviewed-by: Godofredo Contreras <godofredoc@google.com>
Commit-Queue: Xilai Zhang <xilaizhang@google.com>
diff --git a/.style.yapf b/.style.yapf
index 3c79e54..a4860f7 100644
--- a/.style.yapf
+++ b/.style.yapf
@@ -9,3 +9,4 @@
 dedent_closing_brackets = true
 coalesce_brackets = true
 each_dict_entry_on_separate_line = false
+column_limit: 80
diff --git a/recipe_modules/kms/api.py b/recipe_modules/kms/api.py
index 5eac74e..ad9c269 100644
--- a/recipe_modules/kms/api.py
+++ b/recipe_modules/kms/api.py
@@ -45,7 +45,7 @@
 
     Args:
       env(dict): Current environment variables.
-      secrets(dict): The key is the n. me of the env variable referencing the
+      secrets(dict): The key is the name of the env variable referencing the
         decrypted file and the value is the path to the encrypted file in gcs.
     """
     for k, v in secrets.items():
diff --git a/recipes/engine_v2/signer.expected/config_from_file.json b/recipes/engine_v2/signer.expected/config_from_file.json
index f8c2f61..1a8e114 100644
--- a/recipes/engine_v2/signer.expected/config_from_file.json
+++ b/recipes/engine_v2/signer.expected/config_from_file.json
@@ -76,8 +76,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/codesign_team_id.encrypted",
-      "[CLEANUP]/codesign_team_id.encrypted"
+      "gs://flutter_configs/flutter_p12.encrypted",
+      "[CLEANUP]/flutter_p12.encrypted"
     ],
     "infra_step": true,
     "name": "gsutil download"
@@ -87,9 +87,9 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/codesign_team_id.encrypted",
+      "[CLEANUP]/flutter_p12.encrypted",
       "-output",
-      "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted",
+      "[CLEANUP]/FLUTTER_P12",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
     "name": "cloudkms get key"
@@ -131,8 +131,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/codesign_app_specific_password.encrypted",
-      "[CLEANUP]/codesign_app_specific_password.encrypted"
+      "gs://flutter_configs/p12_password.encrypted",
+      "[CLEANUP]/p12_password.encrypted"
     ],
     "infra_step": true,
     "name": "gsutil download (2)"
@@ -142,9 +142,9 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/codesign_app_specific_password.encrypted",
+      "[CLEANUP]/p12_password.encrypted",
       "-output",
-      "[CLEANUP]/tmp_tmp_2/codesign_app_specific_password.encrypted",
+      "[CLEANUP]/FLUTTER_P12_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
     "name": "cloudkms get key (2)"
@@ -186,8 +186,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/codesign_app_store_id.encrypted",
-      "[CLEANUP]/codesign_app_store_id.encrypted"
+      "gs://flutter_configs/codesign_team_id.encrypted",
+      "[CLEANUP]/codesign_team_id.encrypted"
     ],
     "infra_step": true,
     "name": "gsutil download (3)"
@@ -197,37 +197,209 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/codesign_app_store_id.encrypted",
+      "[CLEANUP]/codesign_team_id.encrypted",
       "-output",
-      "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted",
+      "[CLEANUP]/CODESIGN_TEAM_ID",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
     "name": "cloudkms get key (3)"
   },
   {
     "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (4)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/codesign_app_specific_password.encrypted",
+      "[CLEANUP]/codesign_app_specific_password.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (4)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/codesign_app_specific_password.encrypted",
+      "-output",
+      "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (4)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (5)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/codesign_app_store_id.encrypted",
+      "[CLEANUP]/codesign_app_store_id.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (5)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/codesign_app_store_id.encrypted",
+      "-output",
+      "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (5)"
+  },
+  {
+    "cmd": [
+      "security",
+      "delete-keychain",
+      "build.keychain"
+    ],
+    "name": "delete previous keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "create-keychain",
+      "-p",
+      "",
+      "build.keychain"
+    ],
+    "name": "create keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "default-keychain",
+      "-s",
+      "build.keychain"
+    ],
+    "name": "default keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "unlock-keychain",
+      "-p",
+      "",
+      "build.keychain"
+    ],
+    "name": "unlock build keychain"
+  },
+  {
+    "cmd": [
       "chmod",
       "755",
-      "RECIPE[flutter::engine_v2/signer].resources/runner.sh"
+      "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh"
     ],
-    "env_prefixes": {
-      "PATH": [
-        "[CLEANUP]/tmp_tmp_1"
-      ]
-    },
+    "infra_step": true,
     "name": "Set execute permission"
   },
   {
     "cmd": [
-      "bash",
-      "RECIPE[flutter::engine_v2/signer].resources/runner.sh"
+      "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh"
     ],
+    "env": {
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_1/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+    },
     "env_prefixes": {
       "PATH": [
         "[CLEANUP]/tmp_tmp_1"
       ]
     },
-    "name": "unlock keychain"
+    "name": "import certificate"
+  },
+  {
+    "cmd": [
+      "security",
+      "set-key-partition-list",
+      "-S",
+      "apple-tool:,apple:,codesign:",
+      "-s",
+      "-k",
+      "",
+      "build.keychain"
+    ],
+    "name": "set key partition list"
+  },
+  {
+    "cmd": [
+      "security",
+      "find-identity",
+      "-v"
+    ],
+    "name": "show-identities"
   },
   {
     "cmd": [
@@ -239,28 +411,47 @@
       "----",
       "cp",
       "gs://a/b/c/artifact.zip",
-      "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip"
+      "[CLEANUP]/tmp_tmp_2/unsigned_artifact.zip"
     ],
     "infra_step": true,
     "name": "gsutil download gs://a/b/c/artifact.zip"
   },
   {
     "cmd": [
+      "security",
+      "unlock-keychain",
+      "-p",
+      "",
+      "build.keychain"
+    ],
+    "name": "unlock build keychain (2)"
+  },
+  {
+    "cmd": [
       "[CLEANUP]/tmp_tmp_1/codesign",
       "--codesign-cert-name",
       "FLUTTER.IO LLC",
       "--no-dryrun",
       "--app-specific-password-file-path",
-      "[CLEANUP]/tmp_tmp_2/codesign_app_specific_password.encrypted",
+      "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
       "--codesign-appstore-id-file-path",
-      "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted",
+      "[CLEANUP]/CODESIGN_APP_STORE_ID",
       "--codesign-team-id-file-path",
-      "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted",
+      "[CLEANUP]/CODESIGN_TEAM_ID",
       "--input-zip-file-path",
-      "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip",
+      "[CLEANUP]/tmp_tmp_2/unsigned_artifact.zip",
       "--output-zip-file-path",
-      "[CLEANUP]/tmp_tmp_3/artifact.zip"
+      "[CLEANUP]/tmp_tmp_2/artifact.zip"
     ],
+    "env": {
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_1/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+    },
     "env_prefixes": {
       "PATH": [
         "[CLEANUP]/tmp_tmp_1"
@@ -278,7 +469,7 @@
       "ensure-directory",
       "--mode",
       "0777",
-      "[CLEANUP]/tmp_tmp_4/b/c"
+      "[CLEANUP]/tmp_tmp_3/b/c"
     ],
     "infra_step": true,
     "name": "Ensure b/c"
@@ -291,11 +482,11 @@
       "--json-output",
       "/path/to/tmp/json",
       "copy",
-      "[CLEANUP]/tmp_tmp_3/artifact.zip",
-      "[CLEANUP]/tmp_tmp_4/b/c"
+      "[CLEANUP]/tmp_tmp_2/artifact.zip",
+      "[CLEANUP]/tmp_tmp_3/b/c"
     ],
     "infra_step": true,
-    "name": "Copy [CLEANUP]/tmp_tmp_3/artifact.zip to tmp location"
+    "name": "Copy [CLEANUP]/tmp_tmp_2/artifact.zip to tmp location"
   },
   {
     "cmd": [
@@ -307,16 +498,33 @@
       "----",
       "cp",
       "-r",
-      "[CLEANUP]/tmp_tmp_4/*",
+      "[CLEANUP]/tmp_tmp_3/*",
       "gs://a/"
     ],
     "infra_step": true,
-    "name": "gsutil Upload [CLEANUP]/tmp_tmp_3/artifact.zip to gs://a/b/c/artifact.zip",
+    "name": "gsutil Upload [CLEANUP]/tmp_tmp_2/artifact.zip to gs://a/b/c/artifact.zip",
     "~followup_annotations": [
       "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/a/@@@"
     ]
   },
   {
+    "cmd": [
+      "security",
+      "delete-keychain",
+      "build.keychain"
+    ],
+    "name": "delete keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "default-keychain",
+      "-s",
+      "login.keychain"
+    ],
+    "name": "restore default keychain"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json b/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json
new file mode 100644
index 0000000..392890c
--- /dev/null
+++ b/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json
@@ -0,0 +1,442 @@
+[
+  {
+    "cmd": [],
+    "name": "Dependencies"
+  },
+  {
+    "cmd": [],
+    "name": "Dependencies.Installing Mac codesign CIPD pkg",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CLEANUP]/tmp_tmp_1",
+      "-ensure-file",
+      "flutter/codesign/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Dependencies.Installing Mac codesign CIPD pkg.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/codesign/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/flutter_p12.encrypted",
+      "[CLEANUP]/flutter_p12.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/flutter_p12.encrypted",
+      "-output",
+      "[CLEANUP]/FLUTTER_P12",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (2)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/p12_password.encrypted",
+      "[CLEANUP]/p12_password.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (2)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/p12_password.encrypted",
+      "-output",
+      "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (2)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (3)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/codesign_team_id.encrypted",
+      "[CLEANUP]/codesign_team_id.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (3)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/codesign_team_id.encrypted",
+      "-output",
+      "[CLEANUP]/CODESIGN_TEAM_ID",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (3)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (4)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/codesign_app_specific_password.encrypted",
+      "[CLEANUP]/codesign_app_specific_password.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (4)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/codesign_app_specific_password.encrypted",
+      "-output",
+      "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (4)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[START_DIR]/cloudkms",
+      "-ensure-file",
+      "infra/tools/luci/cloudkms/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "ensure_installed (5)",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/luci/cloudkms/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "gs://flutter_configs/codesign_app_store_id.encrypted",
+      "[CLEANUP]/codesign_app_store_id.encrypted"
+    ],
+    "infra_step": true,
+    "name": "gsutil download (5)"
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cloudkms/cloudkms",
+      "decrypt",
+      "-input",
+      "[CLEANUP]/codesign_app_store_id.encrypted",
+      "-output",
+      "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+    ],
+    "name": "cloudkms get key (5)"
+  },
+  {
+    "cmd": [
+      "security",
+      "delete-keychain",
+      "build.keychain"
+    ],
+    "name": "delete previous keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "create-keychain",
+      "-p",
+      "",
+      "build.keychain"
+    ],
+    "name": "create keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "default-keychain",
+      "-s",
+      "build.keychain"
+    ],
+    "name": "default keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "unlock-keychain",
+      "-p",
+      "",
+      "build.keychain"
+    ],
+    "name": "unlock build keychain"
+  },
+  {
+    "cmd": [
+      "chmod",
+      "755",
+      "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh"
+    ],
+    "infra_step": true,
+    "name": "Set execute permission"
+  },
+  {
+    "cmd": [
+      "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh"
+    ],
+    "env": {
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_1/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CLEANUP]/tmp_tmp_1"
+      ]
+    },
+    "name": "import certificate"
+  },
+  {
+    "cmd": [
+      "security",
+      "set-key-partition-list",
+      "-S",
+      "apple-tool:,apple:,codesign:",
+      "-s",
+      "-k",
+      "",
+      "build.keychain"
+    ],
+    "name": "set key partition list"
+  },
+  {
+    "cmd": [
+      "security",
+      "find-identity",
+      "-v"
+    ],
+    "name": "show-identities"
+  },
+  {
+    "cmd": [
+      "security",
+      "delete-keychain",
+      "build.keychain"
+    ],
+    "name": "delete keychain"
+  },
+  {
+    "cmd": [
+      "security",
+      "default-keychain",
+      "-s",
+      "login.keychain"
+    ],
+    "name": "restore default keychain"
+  },
+  {
+    "cmd": [],
+    "name": "RECIPE CRASH (Uncaught exception)",
+    "~followup_annotations": [
+      "@@@STEP_EXCEPTION@@@",
+      "The recipe has crashed at point 'Uncaught exception'!",
+      "",
+      "Traceback (most recent call last):",
+      "  File \"RECIPE_REPO[flutter]/recipes/engine_v2/signer.py\", line 56, in RunSteps",
+      "    KeychainSetup(api, env, env_prefixes)",
+      "  File \"RECIPE_REPO[flutter]/recipes/engine_v2/signer.py\", line 106, in KeychainSetup",
+      "    raise ValueError(",
+      "ValueError('identities are , does not include flutter identity')"
+    ]
+  },
+  {
+    "failure": {
+      "humanReason": "Uncaught Exception: ValueError('identities are , does not include flutter identity')"
+    },
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipes/engine_v2/signer.py b/recipes/engine_v2/signer.py
index a9740cd..ec7534c 100644
--- a/recipes/engine_v2/signer.py
+++ b/recipes/engine_v2/signer.py
@@ -2,9 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Recipe that executes apple code signing on a code signing bot. A code
-# signing bot is a machine with flutter certificates and signing related
-# set ups.
+# Recipe that executes apple code signing on a mac bot.
 #
 # This recipe receives as properties the list of google cloud bucket paths
 # of engine artifacts, and reads code sign related passwords from
@@ -26,6 +24,7 @@
     'recipe_engine/path',
     'recipe_engine/platform',
     'recipe_engine/properties',
+    'recipe_engine/raw_io',
     'recipe_engine/step',
 ]
 
@@ -34,43 +33,133 @@
   if not api.platform.is_mac:
     pass
 
-  # Installing dependencies for code sign.
+  # Install dependencies for code sign.
   env = {}
   env_prefixes = {}
   with api.step.nest('Dependencies'):
     codesign_path = api.flutter_deps.codesign(env, env_prefixes)
 
+  secrets_dict = {
+      'FLUTTER_P12': 'flutter_p12.encrypted',
+      'FLUTTER_P12_PASSWORD': 'p12_password.encrypted',
+      'CODESIGN_TEAM_ID': 'codesign_team_id.encrypted',
+      'CODESIGN_APP_SPECIFIC_PASSWORD':
+        'codesign_app_specific_password.encrypted',
+      'CODESIGN_APP_STORE_ID': 'codesign_app_store_id.encrypted'
+  }
+
+  api.kms.decrypt_secrets(env, secrets_dict)
+
+  env['CODESIGN_PATH'] = codesign_path
+
+  try:
+    KeychainSetup(api, env, env_prefixes)
+
+    SignerBuilds(
+        api, codesign_path, env, env_prefixes
+    )
+
+  finally:
+    KeychainCleanup(api)
+
+
+def KeychainSetup(api, env, env_prefixes):
+  """KeychainSetup adds flutter .p12 to a temporary keychain named 'build'.
+
+  Args:
+      codesign_path (str): path of codesign cipd package.
+      p12_filepath (str) : path of the .p12 file that has flutter credentials.
+      p12_password_raw (str) : the password to decode the .p12 flutter file.
+  """
+  api.step(
+      'delete previous keychain',
+      ['security', 'delete-keychain', 'build.keychain'],
+      ok_ret='any'
+  )
+  api.step(
+      'create keychain',
+      ['security', 'create-keychain', '-p', '', 'build.keychain']
+  )
+  api.step(
+      'default keychain',
+      ['security', 'default-keychain', '-s', 'build.keychain']
+  )
+  api.step(
+      'unlock build keychain',
+      ['security', 'unlock-keychain', '-p', '', 'build.keychain']
+  )
+  ImportCertificate(api, env, env_prefixes)
+  api.step(
+      'set key partition list', [
+          'security', 'set-key-partition-list', '-S',
+          'apple-tool:,apple:,codesign:', '-s', '-k', '', 'build.keychain'
+      ]
+  )
+  show_identities_step = api.step(
+      'show-identities', ['security', 'find-identity', '-v'],
+      ok_ret='any',
+      stdout=api.raw_io.output_text(),
+      stderr=api.raw_io.output_text()
+  )
+  flutter_identity_name = 'FLUTTER.IO LLC'
+  if flutter_identity_name not in show_identities_step.stdout:
+    raise ValueError(
+        'identities are %s, does not include flutter identity' %
+        (show_identities_step.stdout)
+    )
+
+
+def ImportCertificate(api, env, env_prefixes):
+  """Import flutter codesign identity into keychain.
+
+  This function triggers a shell script that supplies p12 password,
+  and grants codesign cipd and system codesign the correct access controls.
+  The p12 password is hidden from stdout.
+
+  Args:
+      env (dict): environment variables.
+      env_prefixes (dict) : environment paths.
+  """
+  resource_name = api.resource('import_certificate.sh')
+  api.step(
+      'Set execute permission',
+      ['chmod', '755', resource_name],
+      infra_step=True,
+  )
+  # Only filepath with a .p12 suffix will be recognized.
+  p12_suffix_filepath = api.path['cleanup'].join('flutter.p12')
+  env['P12_SUFFIX_FILEPATH'] = p12_suffix_filepath
+  with api.context(env=env, env_prefixes=env_prefixes):
+    api.step('import certificate', [resource_name])
+
+
+def SignerBuilds(
+    api, codesign_path, env, env_prefixes
+):
+  """Concurrently creates jobs to codesign each binary.
+
+  Args:
+      codesign_path (str): path of codesign cipd package.
+      env (dict): environment variables.
+      env_prefixes (dict) : environment paths.
+  """
   # The list is iterated running one signer tool command per file. This can be
   # optimized using the multiprocessing API.
   final_sources_list = api.properties.get('signing_file_list', [])
-  signer_builds = []
-  codesign_dir = api.path.mkdtemp()
-  app_specific_password_filepath = codesign_dir.join(
-      'codesign_app_specific_password.encrypted'
-  )
-  appstore_id_filepath = codesign_dir.join('codesign_app_store_id.encrypted')
-  team_id_filepath = codesign_dir.join('codesign_team_id.encrypted')
-  api.kms.get_secret('codesign_team_id.encrypted', team_id_filepath)
-  api.kms.get_secret(
-      'codesign_app_specific_password.encrypted', app_specific_password_filepath
-  )
-  api.kms.get_secret('codesign_app_store_id.encrypted', appstore_id_filepath)
 
-  # unlock keychain
-  with api.context(env=env, env_prefixes=env_prefixes):
-    resource_name = api.resource('runner.sh')
-    api.step('Set execute permission', ['chmod', '755', resource_name])
-    cmd = ['bash', resource_name]
-    api.step('unlock keychain', cmd)
-
-  # keep track of the output zip files in separate temp folders to avoid name conflicts
+  # keep track of the output zip files in separate temp folders to avoid name
+  # conflicts
   output_zips = {}
 
   codesign_string_path = "%s" % codesign_path
+  app_specific_password_filepath = env['CODESIGN_APP_SPECIFIC_PASSWORD']
+  appstore_id_filepath = env['CODESIGN_APP_STORE_ID']
+  team_id_filepath = env['CODESIGN_TEAM_ID']
+  signer_builds = []
   with api.osx_sdk('ios'):
     for source_path in final_sources_list:
       input_tmp_folder = api.path.mkdtemp()
-      _, artifact_base_name = api.path.split(source_path) 
+      _, artifact_base_name = api.path.split(source_path)
       local_zip_path = input_tmp_folder.join('unsigned_%s' % artifact_base_name)
       local_zip_string_path = str(local_zip_path)
 
@@ -94,6 +183,7 @@
   for source_path, output_zip_path in output_zips.items():
     api.archives.upload_artifact(src=output_zip_path, dst=source_path)
 
+
 def RunSignerToolCommand(
     api, env, env_prefixes, input_zip_string_path, output_zip_string_path,
     app_specific_password_filepath, appstore_id_filepath, team_id_filepath,
@@ -114,6 +204,10 @@
       cipd package. This is to differentiate codesign cipd from mac system codesign.
   """
   flutter_certificate_name = 'FLUTTER.IO LLC'
+  api.step(
+      'unlock build keychain',
+      ['security', 'unlock-keychain', '-p', '', 'build.keychain']
+  )
   with api.context(env=env, env_prefixes=env_prefixes):
     api.step(
         'codesign Apple engine binaries',
@@ -136,6 +230,15 @@
     )
 
 
+def KeychainCleanup(api):
+  """Clean up temporary keychain used in codesign process."""
+  api.step('delete keychain', ['security', 'delete-keychain', 'build.keychain'])
+  api.step(
+      'restore default keychain',
+      ['security', 'default-keychain', '-s', 'login.keychain']
+  )
+
+
 def GenTests(api):
 
   yield api.test(
@@ -146,5 +249,23 @@
               'version': 'latest',
           }],
           signing_file_list=["gs://a/b/c/artifact.zip"]
-      )
+      ),
+      api.step_data(
+          'show-identities',
+          stdout=api.raw_io.output_text(
+              '1) ABCD "Developer ID Application: FLUTTER.IO LLC (ABCD)"'
+          )
+      ),
+  )
+
+  yield api.test(
+      'import_flutter_identity_failure',
+      api.properties(
+          dependencies=[{
+              'dependency': 'codesign',
+              'version': 'latest',
+          }],
+          signing_file_list=["gs://a/b/c/artifact.zip"]
+      ),
+      api.expect_exception('ValueError'),
   )
diff --git a/recipes/engine_v2/signer.resources/import_certificate.sh b/recipes/engine_v2/signer.resources/import_certificate.sh
new file mode 100644
index 0000000..f4151e1
--- /dev/null
+++ b/recipes/engine_v2/signer.resources/import_certificate.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# Helper script to import a flutter p12 identity.
+# Note: do not enable -x to display expanded values of the variables, as this will leak the passwords.
+set -e
+
+RAW_PASSWORD=$(cat $FLUTTER_P12_PASSWORD)
+# Only filepath with a .p12 suffix will be recognized
+mv $FLUTTER_P12 $P12_SUFFIX_FILEPATH
+/usr/bin/security import $P12_SUFFIX_FILEPATH -k build.keychain -P $RAW_PASSWORD -T $CODESIGN_PATH -T /usr/bin/codesign
\ No newline at end of file
diff --git a/recipes/engine_v2/signer.resources/runner.sh b/recipes/engine_v2/signer.resources/runner.sh
deleted file mode 100644
index a35286d..0000000
--- a/recipes/engine_v2/signer.resources/runner.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-# Helper script to unlock the keychain in the same session
-# as the test runner script.
-set -e
-
-if [ -f /usr/local/bin/unlock_login_keychain.sh ]
-then
-  /usr/local/bin/unlock_login_keychain.sh
-else
-  echo "This bot does not support codesigning"
-fi
\ No newline at end of file