Lab Guide: Introducing supply chain security with ansible-sign

Learn how to sign content by using ansible-sign and apply supply-chain security measures, a major Dev Tools capability.

Learning objectives

After completing this module, you will be able to:

  • Create a GPG key for signing Ansible content

  • Define a MANIFEST.in to specify files for signing

  • Sign and verify an Ansible project using ansible-sign

  • Understand how signed content integrates with Ansible Automation Platform

Lab briefing

ansible-sign: Utility for signing and verifying Ansible project directory contents.

Project signing and verification lets you sign files in your project directory, then verify whether or not that content has changed in any way, or files have been added or removed from the project unexpectedly. To do this, you require a private key for signing and a matching public key for verifying.

Lab guide: Hands-on tasks

The Workflow for Signing Ansible Automation Platform (AAP) Projects:

  • Sign your project directory containing playbooks, rulebooks, roles, etc.

  • Sync the signed project to AAP’s Project Sync

  • AAP verifies the signature before execution

  • Only validated, trusted content runs

Using ansible-sign together with the Automation Hub collection signing feature allows to secure the supply chain end-to-end from content development to production.

In this lab we will only cover the workstation side of the content signing. You can apply what you learned here to verify content on your own AAP instance later.

Task 1: Create a GPG key

To use ansible-sign your workstation needs to have a GNU Privacy Guard (GPG) key available to cryptographically sign the content. Although it exceeds the scope of this workshop, we will create one quickly to show the end to end steps.

  1. Install pinentry-curses, a dependency for gpg:

     sudo dnf install pinentry-curses -y
  2. Create a gpg.txt file with the following content:

    cat >~/gpg.txt <<EOF
    %echo Generating a basic OpenPGP key
    Key-Type: default
    Key-Length: 4096
    Subkey-Type: default
    Subkey-Length: default
    Name-Real: workshop
    Name-Comment: with no passphrase
    Name-Email: student@localhost
    Expire-Date: 0
    %no-ask-passphrase
    %no-protection
    # Do a commit here, so that we can later print "done" :-)
    %commit
    %echo done
    EOF
  3. Generate the gpg key:

    gpg --batch --gen-key ~/gpg.txt
  4. Verify the key is created:

    gpg --list-secret-keys

Task 2: Set up the environment

This task demonstrates how to cryptographically sign an Ansible Project using ansible-sign. We will be using myansibleproject and our mycowsay.yml playbook.

  1. Make sure you are in the myansibleproject directory:

    cd /home/rhel/myansibleproject
  2. Switch ade to standard mode: Before we can sign our packages, we need to disable editable mode to remove the recursive symlinks.

    ade install /home/rhel/myansibleproject/collections/ansible_collections/mynamespace/mycollection

Task 3: Create a MANIFEST.in file

  1. In VS Code, create a new file called MANIFEST.in in the root of your project. Add the following content to it. We will be excluding a couple of directories and signing a README and playbook. This is only meant as an example, your needs might vary:

    # Exclude .venv FIRST before any includes
    global-exclude .venv
    global-exclude .venv/*
    prune .venv
    
    # Exclude .git
    global-exclude .git
    global-exclude .git/*
    prune .git
    
    # Now include what you want to sign
    include README.md
    include mycowsay.yml
Internally, ansible-sign makes use of the distlib.manifest module of Python’s distlib library, and thus MANIFEST.in must follow the syntax that this library specifies. Check the Python Packaging User Guide for an explanation of the MANIFEST.in file directives.

Task 4: Sign the project with ansible-sign

  1. Now we can sign the files listed in the MANIFEST.in: The way that ansible-sign protects content from tampering is by taking checksums (sha256) of all of the secured files in the project, compiling those into a checksum manifest file, and then finally signing that manifest file.

    ansible-sign project gpg-sign .

    The output of the command above should look like this:

    [OK   ] GPG signing successful!
    [NOTE ] Checksum manifest: ./.ansible-sign/sha256sum.txt
    [NOTE ] GPG summary: signature created

Task 5: Verify the content with ansible-sign

  1. Confirm the files in MANIFEST.in got checksums:

    cat .ansible-sign/sha256sum.txt
  2. Verify your signed files have the correct checksum:

    ansible-sign project gpg-verify .
    [OK   ] GPG signature verification succeeded.
    [NOTE ] Checksum manifest: ./.ansible-sign/sha256sum.txt
    [NOTE ] GPG summary: valid signature
  3. Switch ade back to editable mode:

    ade install --editable /home/rhel/myansibleproject/collections/ansible_collections/mynamespace/mycollection

Task 6: Enable verification in AAP executions

  1. We won’t cover this here, but the next steps would be:

    1. Create a credential with our GPG Public Key

    2. Push our project to a git repository

    3. Create a project in AAP to pull from that repository and assign our GPG credential

    4. AAP will verify the content of the project at every sync


Next steps

You have successfully signed and verified your playbook, this ensured that it can’t be tampered with and continue to run unnoticed. Please click the Next button below to proceed to the next module.