Chapter 4. Collections and content signing in private automation hub As an automation administrator for your organization, you can configure private automation hub for signing and publishing Ansible content collections from different groups within your organization. For additional security, automation creators can configure Ansible-Galaxy CLI to verify these collections to ensure they have not been changed after they were uploaded to automation hub. 4.1. Configuring content signing on private automation hub To successfully sign and publish Ansible Certified Content Collections, you must configure private automation hub for signing. Prerequisites Your GnuPG key pairs have been securely set up and managed by your organization. Your public/private key pair has proper access for configuring content signing on private automation hub. Procedure Create a signing script that accepts only a filename. Note This script acts as the signing service and must generate an ascii-armored detached gpg signature for that file using the key specified through the PULP_SIGNING_KEY_FINGERPRINT environment variable. The script then prints out a JSON structure with the following format. {"file": "filename", "signature": "filename.asc"} All the file names are relative paths inside the current working directory. The file name must remain the same for the detached signature, as shown. The following example shows a script that produces signatures for content: #!/usr/bin/env bash FILE_PATH=USD1 SIGNATURE_PATH="USD1.asc" ADMIN_ID="USDPULP_SIGNING_KEY_FINGERPRINT" PASSWORD="password" # Create a detached signature gpg --quiet --batch --pinentry-mode loopback --yes --passphrase \ USDPASSWORD --homedir ~/.gnupg/ --detach-sign --default-key USDADMIN_ID \ --armor --output USDSIGNATURE_PATH USDFILE_PATH # Check the exit status STATUS=USD? if [ USDSTATUS -eq 0 ]; then echo {\"file\": \"USDFILE_PATH\", \"signature\": \"USDSIGNATURE_PATH\"} else exit USDSTATUS fi After you deploy a private automation hub with signing enabled to your Ansible Automation Platform cluster, new UI additions display when you interact with collections. Review the Ansible Automation Platform installer inventory file for options that begin with automationhub_* . [all:vars] . . . automationhub_create_default_collection_signing_service = True automationhub_auto_sign_collections = True automationhub_require_content_approval = True automationhub_collection_signing_service_key = /abs/path/to/galaxy_signing_service.gpg automationhub_collection_signing_service_script = /abs/path/to/collection_signing.sh The two new keys ( automationhub_auto_sign_collections and automationhub_require_content_approval ) indicate that the collections must be signed and require approval after they are uploaded to private automation hub. 4.2. Using content signing services in private automation hub After you have configured content signing on your private automation hub, you can manually sign a new collection or replace an existing signature with a new one so that users who want to download a specific collection have the assurance that the collection is intended for them and has not been modified after certification. Content signing on private automation hub provides solutions for the following scenarios: Your system does not have automatic signing configured and you must use a manual signing process to sign collections. The current signatures on the automatically configured collections are corrupted and must be replaced with new signatures. Additional signatures are required for previously signed content. You want to rotate signatures on your collections. Procedure Log in to your private automation hub instance in the automation hub UI. In the left navigation, click Collections Approval . The Approval dashboard is displayed with a list of collections. Click Sign and approve for each collection you want to sign. Verify that the collections you signed and manually approved are displayed in the Collections tab. 4.3. Downloading signature public keys After you sign and approve collections, download the signature public keys from the automation hub UI. You must download the public key before you add it to the local system keyring. Procedure Log in to your private automation hub instance in the automation hub UI. In the navigation pane, select Signature Keys . The Signature Keys dashboard displays a list of multiple keys: collections and container images. To verify collections, download the key prefixed with collections- . To verify container images, download the key prefixed with container- . Choose one of the following methods to download your public key: Select the menu icon and click Download Key to download the public key. Select the public key from the list and click the Copy to clipboard icon. Click the drop-down menu under the Public Key tab and copy the entire public key block. Use the public key that you copied to verify the content collection that you are installing. 4.4. Configuring Ansible-Galaxy CLI to verify collections You can configure Ansible-Galaxy CLI to verify collections. This ensures that collections you download are approved by your organization and have not been changed after they were uploaded to automation hub. If a collection has been signed by automation hub, the server provides ASCII armored, GPG-detached signatures to verify the authenticity of MANIFEST.json before using it to verify the collection's contents. You must opt into signature verification by configuring a keyring for ansible-galaxy or providing the path with the --keyring option. Prerequisites Signed collections are available in automation hub to verify signature. Certified collections can be signed by approved roles within your organization. Public key for verification has been added to the local system keyring. Procedure To import a public key into a non-default keyring for use with ansible-galaxy , run the following command. gpg --import --no-default-keyring --keyring ~/.ansible/pubring.kbx my-public-key.asc Note In addition to any signatures provided by the automation hub, signature sources can also be provided in the requirements file and on the command line. Signature sources should be URIs. Use the --signature option to verify the collection name provided on the CLI with an additional signature. ansible-galaxy collection install namespace.collection --signature https://examplehost.com/detached_signature.asc --signature file:///path/to/local/detached_signature.asc --keyring ~/.ansible/pubring.kbx You can use this option multiple times to provide multiple signatures. Confirm that the collections in a requirements file list any additional signature sources following the collection's signatures key, as in the following example. # requirements.yml collections: - name: ns.coll version: 1.0.0 signatures: - https://examplehost.com/detached_signature.asc - file:///path/to/local/detached_signature.asc ansible-galaxy collection verify -r requirements.yml --keyring ~/.ansible/pubring.kbx When you install a collection from automation hub, the signatures provided by the server are saved along with the installed collections to verify the collection's authenticity. (Optional) If you need to verify the internal consistency of your collection again without querying the Ansible Galaxy server, run the same command you used previously using the --offline option.

Commands:
file: filename
signature: filename.asc
#!/usr/bin/env bash FILE_PATH=USD1 SIGNATURE_PATH="USD1.asc" ADMIN_ID="USDPULP_SIGNING_KEY_FINGERPRINT" PASSWORD="password" Create a detached signature gpg --quiet --batch --pinentry-mode loopback --yes --passphrase USDPASSWORD --homedir ~/.gnupg/ --detach-sign --default-key USDADMIN_ID --armor --output USDSIGNATURE_PATH USDFILE_PATH Check the exit status STATUS=USD? if [ USDSTATUS -eq 0 ]; then echo {\"file\": \"USDFILE_PATH\", \"signature\": \"USDSIGNATURE_PATH\"} else exit USDSTATUS fi
[all:vars] . . . automationhub_create_default_collection_signing_service = True automationhub_auto_sign_collections = True automationhub_require_content_approval = True automationhub_collection_signing_service_key = /abs/path/to/galaxy_signing_service.gpg automationhub_collection_signing_service_script = /abs/path/to/collection_signing.sh
gpg --import --no-default-keyring --keyring ~/.ansible/pubring.kbx my-public-key.asc
ansible-galaxy collection install namespace.collection --signature https://examplehost.com/detached_signature.asc --signature file:///path/to/local/detached_signature.asc --keyring ~/.ansible/pubring.kbx
requirements.yml collections: - name: ns.coll version: 1.0.0 signatures: - https://examplehost.com/detached_signature.asc - file:///path/to/local/detached_signature.asc ansible-galaxy collection verify -r requirements.yml --keyring ~/.ansible/pubring.kbx