# Signing remote action scripts on Mac (classic)

The following is a step-by-step guide to signing remote action scripts on a Mac device.

{% hint style="info" %}
For the production environment, we recommend using a code signing certificate.
{% endhint %}

## Create your certificate <a href="#signingremoteactionscriptsonmac-classic-createyourcertificate" id="signingremoteactionscriptsonmac-classic-createyourcertificate"></a>

* Launch Keychain Access on your Mac device.
* Go to Keychain Access > Certificate Assistant > **Create a Certificate…**

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-60ca3c99acf701c49083aa135c2b9b75affdb20f%2Fimage-20231026-133403.png?alt=media" alt="Create a certificate" width="760"><figcaption></figcaption></figure>

* Enter the name of your certificate.
* Choose **Code Signing** for the **Certificate Type**.
* For testing purposes, you can leave **Let me override defaults** unchecked.

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-d552e086d77e8861b670ebbce07775b6cc3e1fc9%2Fimage-20210723-101154.png?alt=media" alt=""><figcaption></figcaption></figure>

* Click **Create** and **Done**. The system has generated the certificate.

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-9a05899661f21fb6fe4a1a9db47cb075e2bc6de4%2Fimage-20210723-101311.png?alt=media" alt=""><figcaption></figcaption></figure>

## Signing and packaging a remote action script <a href="#signingremoteactionscriptsonmac-classic-signingandpackagingaremoteactionscript" id="signingremoteactionscriptsonmac-classic-signingandpackagingaremoteactionscript"></a>

### Signing <a href="#signingremoteactionscriptsonmac-classic-signing" id="signingremoteactionscriptsonmac-classic-signing"></a>

Sign the remote action scripts using the standard macOS codesign utility.

```
codesign -s <your certificate identity> --timestamp --prefix=<code signature identifier prefix> --force <script file name>
```

Parameters:

```
-s <your certificate identity>
```

The identity of your code signing certificate is in the Keychain. Generally, it is a certificate subject common name or a certificate hash. See the [codesign manual page](https://www.unix.com/man-page/osx/1/codesign/) for a full description.

```
--timestamp
```

A trusted timestamp for a signature.

```
--prefix
```

A prefix to a code signature identifier. It attaches your company identity to an identifier and helps to make an identifier unique. See the code signature identifier generation rules on the [codesign manual page](https://www.unix.com/man-page/osx/1/codesign/).

```
--force
```

This forces a code signature to be rewritten if it already exists.

### **Example**

Example of a test certificate for *example\_ra\_script.sh* remote action script:<br>

```
codesign -s "RA scripts code signing certificate" --timestamp --prefix=com.my-organisation.remote-action.macos. --force example_ra_script.sh
```

\
The signature for the script file is generated in the file system extended attributes associated with the file. Use the codesign utility to get the code signature details and validate the signature:

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-c967761b49bc8e192f842f1abe0d24d6cd074de0%2Fimage-20210723-101721.png?alt=media" alt="Screenshot of the terminal" width="742"><figcaption></figcaption></figure>

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-3b5402fb5768865a585eb7eeaa91e14524c5988d%2Fimage-20210723-101735.png?alt=media" alt="Screenshot of the terminal" width="742"><figcaption></figcaption></figure>

### Packaging <a href="#signingremoteactionscriptsonmac-classic-packaging" id="signingremoteactionscriptsonmac-classic-packaging"></a>

Package the remote action script with a .tar archive and .gzip compression. The extension ".tar.gz" is mandatory.

```
tar -czvf ./<your script name>.tar.gz ./<your script name>.sh
```

If the script file is signed, the tar utility will pack its extended attributes as well. This way, the system can transport the code signature along with a script file.\
\
**Limitations**

* Only one script can be put into one archive.
* A script file should be put into the root package folder, the `./myscript/myscript.sh` path is not correct.
* A script must have the .sh extension.
* A script filename must be UTF-8 encoded, which is the default on macOS.

### **Example**

Example of packaging the `test.sh` script:

```
tar -czvf ./example_ra_script.tar.gz ./example_ra_script.sh
```

The resulting `example_ra_script.tar.gz` is the remote action script file.

#### Signing and packaging a remote action script <a href="#signingremoteactionscriptsonmac-classic-signingandpackagingaremoteactionscript.1" id="signingremoteactionscriptsonmac-classic-signingandpackagingaremoteactionscript.1"></a>

Nexthink recommends using this script to simplify the signing and packaging process.

```
#!/bin/bash
#
# script_signing.sh
# 
# Copyright (C) 2023 by Nexthink S.A., Switzerland. Any usage, copy or partial copy of
# this code without the explicit agreement of Nexthink S.A. is prohibited and will be
# pursued to the full extend of the law.
#
# The arguments for the script:
# - input script filename
# - output archive filename
# - Certificate owner
# - Prefix
#
 
 
# Error handling
set -euo pipefail
trap "echo unrecoverable error !" ERR
 
 
# Check codesign
if [[ ! -x /usr/bin/codesign ]]
then
    echo "Error: this script requires that codesign is installed"
    exit 2
fi
 
# Check tar
if [[ ! -x /usr/bin/tar ]]
then
    echo "Error: this script requires that tar is installed"
    exit 2
fi
 
 
# Check arguments
if [[ $# -lt 4 ]]
then
    echo "Usage: script_signing.sh inputScriptFilename outputArchiveFilename CertificateOwner prefix"
    echo "Example: ./script_signing.sh script.sh script.tar.gz \"John Doe\" com.john.remote-action.macos."
    exit 1
fi
 
/usr/bin/codesign -s "$3" --timestamp --prefix="$4" --force "$1"
/usr/bin/tar czf "$2" "$1"
```

### Exporting a code signing certificate to install on endpoints <a href="#signingremoteactionscriptsonmac-classic-exportingacodesigningcertificatetoinstallonendpoints" id="signingremoteactionscriptsonmac-classic-exportingacodesigningcertificatetoinstallonendpoints"></a>

If you have your code signing certificate in the Keychain and want to install its public version on endpoints, you need to export it first.<br>

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-f3f7592c725fb91bf46b71979d822cfe6c1b332a%2Fimage-20210723-102807.png?alt=media" alt=""><figcaption></figcaption></figure>

* Choose the *Certificate (.cer)* file format for a public certificate in the pop-up window.

### Importing a code signing certificate to the Keychain on endpoints <a href="#signingremoteactionscriptsonmac-classic-importingacodesigningcertificatetothekeychainonendpoints" id="signingremoteactionscriptsonmac-classic-importingacodesigningcertificatetothekeychainonendpoints"></a>

* Import your code-signed certificate into the System keychain to use remote action scripts with a *Trusted Publisher* execution policy.
* Double-click a .cer file and choose the **System** option in the **Keychain** drop-down menu.

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-0dd5dff3d4fb25f407c4806aa54f83944f0ae9bd%2Fimage-20210723-102902.png?alt=media" alt="Add certificates" width="745"><figcaption></figcaption></figure>

* Enter the root password to import the certificate.

If the certificate is self-signed, it should also be trusted for code signing.

* Double-click the Keychain Access utility certificate and choose **Always trust** for the **Code Signing** option.

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-9aaf51e861fafb10d3b239ddfff2fd12873e92e1%2Fimage-20210723-102935.png?alt=media" alt="Certificate details"><figcaption></figcaption></figure>

To automate these tasks, use the [security utility](https://www.unix.com/man-page/osx/1/security/) (external link) or your automation framework.

### Verify that the certificate was properly imported to an endpoint <a href="#signingremoteactionscriptsonmac-classic-verifythatthecertificatewasproperlyimportedtoanendpoint" id="signingremoteactionscriptsonmac-classic-verifythatthecertificatewasproperlyimportedtoanendpoint"></a>

* Copy and unpack your signed remote action script to the endpoint.

```
tar -xzvf example_ra_script.tar.gz
```

* Verify your signature.

```
codesign -vvvv -R="certificate leaf trusted" example_ra_script.sh
```

If the signature is properly imported, you should see the following output:

<figure><img src="https://268444917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxJSUDk9NTtCHYPG5EWs3%2Fuploads%2Fgit-blob-9828e7e7115722833c9057a116e7529e4a591e3c%2Fimage-20210723-103057.png?alt=media" alt="" width="745"><figcaption></figcaption></figure>

***

RELATED TOPIC

* [Writing scripts for remote actions on Mac for Finder (classic)](https://docs.nexthink.com/platform/user-guide/remote-actions/remote-actions-in-finder-classic/writing-scripts-for-remote-actions-on-mac-for-finder-classic)
