From 0a45b9b5c38849f67436a9ef0d4220c088220cb9 Mon Sep 17 00:00:00 2001 From: Aron Gunn Date: Thu, 12 Sep 2024 14:40:43 -0500 Subject: [PATCH] 9/12/24 - ritz303 : Edits to the README doc --- README.md | 351 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 182 insertions(+), 169 deletions(-) diff --git a/README.md b/README.md index d215869d..b4629813 100644 --- a/README.md +++ b/README.md @@ -1,181 +1,192 @@ -# RHTAS Ansible Collection +# Red Hat Trusted Artifact Signer Ansible collection -Automation to deploy the RHTAS ecosystem on RHEL +The purpose of this Ansible collection is to automate the deployment of the Red Hat Trusted Artifact Signer (RHTAS) service on Red Hat Enterprise Linux (RHEL). -:warning: **The contents of this repository are a Work in Progress.** +> [!IMPORTANT] +Deploying RHTAS by using Ansible is a Technology Preview feature only. +Technology Preview features are not supported with Red Hat production service level agreements (SLAs), might not be functionally complete, and Red Hat does not recommend to use them for production. +These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process. +See the support scope for [Red Hat Technology Preview](https://access.redhat.com/support/offerings/techpreview/) features for more details. ## Overview -The automation within this repository establishes the components of RHTAS, the downstream redistribution of [Sigstore project](https://sigstore.dev) within a single Red Hat Enterprise Linux (RHEL) machine using a standalone containerized deployment. Containers are spawned using Kubernetes based manifests using -[podman kube play](https://docs.podman.io/en/latest/markdown/podman-kube-play.1.html). +The RHTAS service is the downstream redistribution of the [Sigstore](https://sigstore.dev) project. +The automation contained within this Git repository installs and configures the components of RHTAS to run on a single RHEL server, which uses a standalone containerized deployment. +A Kubernetes-based manifest creates containers that uses [`podman kube play`](https://docs.podman.io/en/latest/markdown/podman-kube-play.1.html). -The following Sigstore components are deployed as part of this architecture: +The RHTAS Ansible collection deploys the following RHTAS components: * [Rekor](https://docs.sigstore.dev/rekor/overview) - * [Trillian](https://github.com/google/trillian) - * Optionally a MariaDB instance and a Redis instance, although it is possible to use instances managed outside of Ansible + * [Trillian database](https://github.com/google/trillian) + * Optional: A self-managed MariaDB instance, and a Redis instance. * [Fulcio](https://docs.sigstore.dev/fulcio/overview) * [Certificate Log](https://docs.sigstore.dev/fulcio/certificate-issuing-overview) * [Timestamp Authority](https://docs.sigstore.dev/verifying/timestamps/#timestamp-authorities) -* [TUF](https://theupdateframework.io/) server +* [The Update Framework (TUF) server](https://theupdateframework.io/) -An [NGINX](https://www.nginx.com) frontend is placed as an entrypoint to the various backend components. Communication is secured via a set of self-signed certificates that are generated at runtime. +An [NGINX](https://www.nginx.com) front end places an entrypoint to the various backend components. +A set of self-signed certificates get generated at runtime to establishing secure communications. -Utilize the steps below to understand how to setup and execute the provisioning. +This automation also deploys and configures a software load balancer as a central point of ingress. +The ingress host names are as follows, where `` is your deployment's base hostname: -## Prerequisites - -RHEL 9.2+ x86\_64 is supported to run the RHTAS components. - -Ansible must be installed and configured on a control node that will be used to perform the automation. - -Perform the following steps to prepare the control node for execution. - -### Dependencies - -Install the required Ansible collections by executing the following (this can be skipped if installing from Ansible Automation Hub, as `ansible-galaxy install` will install dependencies automatically). - -```shell -ansible-galaxy collection install -r requirements.yml -``` - -### OIDC provider - -An installation of an OIDC provider, such as [Keycloak](https://console.redhat.com/ansible/automation-hub/repo/published/redhat/sso/), must be provided to allow for integration with containerized RHTAS. - -### Ingress - -The automation deploys and configures a software load balancer as a central point of ingress. Multiple hostnames underneath a _base hostname_ are configured and include the following hostnames: - -* https://rekor. -* https://fulcio. -* https://tsa. -* https://tuf. - -Each of these hostnames must be configured in DNS to resolve to the target machine. The `base_hostname` parameter must be provided when executing the provisining. To configure hostnames in DNS, edit `/etc/hosts` with the following content: - -``` - fulcio. fulcio - rekor. rekor - tsa. tsa - tuf. tuf -``` - -### Cosign - -[cosign](https://github.com/sigstore/cosign) is used as part of testing and validating the setup and configuration. It is an optional install if there is not a desire to perform the validation as described below. - -## Provision - -In order to deploy RHTAS on a RHEL 9.2+ VM: - -1. Create an `inventory` file with a single VM in the `rhtas` group: - ``` - [rhtas] - 123.123.123.123 - ``` -2. Create a simple Ansible playbook `play.yml`: - ``` - - hosts: rhtas - vars: - base_hostname: TODO # e.g. example.com - # access credentials for registry.redhat.io (https://access.redhat.com/RegistryAuthentication) - tas_single_node_registry_username: TODO - tas_single_node_registry_password: TODO - tas_single_node_oidc_issuers: - - issuer: TODO # your OIDC provider (e.g. keycloak) URL - client_id: trusted-artifact-signer - url: TODO # your OIDC provider (e.g. keycloak) URL - type: email - tasks: - - name: Include TAS single node role - ansible.builtin.include_role: - name: redhat.artifact_signer.tas_single_node - vars: - ansible_become: true - ``` -3. Execute the following command if the collection is installed from Ansible Automation Hub: - ```shell - ansible-playbook -i inventory play.yml - ``` -4. Execute the following command if you're running from the collection repository checked out locally: - ```shell - ANSIBLE_ROLES_PATH="roles/" ansible-playbook -i inventory play.yml - ``` - -### Add the root CA that was created to your local truststore. - -The certificate can be downloaded from the browser Certificate Viewer by navigating to `https://rekor.`. -Download the _root_ certificate that issued the Rekor certificate. -In Red Hat based systems, the following commands will add a CA to the system truststore. - -```shell -$ sudo openssl x509 -in ~/Downloads/root-cert-from-browser -out tas-ca.pem --outform PEM -$ sudo mv tas-ca.pem /etc/pki/ca-trust/source/anchors/ -$ sudo update-ca-trust -``` - -## Signing a Container +* https://rekor.`` +* https://fulcio.`` +* https://tsa.`` +* https://tuf.`` -Utilize the following steps to sign a container that has been published to an OCI registry - -1. Export the following environment variables substituting `BASE_HOSTNAME`, `KEYCLOAK_URL` and if necessary also `KEYCLOAK_REALM` with the values used as part of the provisioning: - -```shell -export BASE_HOSTNAME="TODO-provide-base-hostname" -export KEYCLOAK_URL="TODO-your-keycloak-url" -export KEYCLOAK_REALM=trusted-artifact-signer - -export TUF_URL=https://tuf.$BASE_HOSTNAME -export OIDC_ISSUER_URL=$KEYCLOAK_URL/auth/realms/$KEYCLOAK_REALM -export COSIGN_FULCIO_URL=https://fulcio.$BASE_HOSTNAME -export COSIGN_REKOR_URL=https://rekor.$BASE_HOSTNAME -export COSIGN_MIRROR=$TUF_URL -export COSIGN_ROOT=$TUF_URL/root.json -export COSIGN_OIDC_CLIENT_ID=$KEYCLOAK_REALM -export COSIGN_OIDC_ISSUER=$OIDC_ISSUER_URL -export COSIGN_CERTIFICATE_OIDC_ISSUER=$OIDC_ISSUER_URL -export COSIGN_YES="true" -export SIGSTORE_FULCIO_URL=$COSIGN_FULCIO_URL -export SIGSTORE_OIDC_ISSUER=$COSIGN_OIDC_ISSUER -export SIGSTORE_REKOR_URL=$COSIGN_REKOR_URL -export REKOR_REKOR_SERVER=$COSIGN_REKOR_URL -``` - -2. Initialize the TUF roots - -```shell -cosign initialize -``` - -Note: If you have used `cosign` previously, you may need to delete the `~/.sigstore` directory - -3. Sign the desired container - -```shell -cosign sign -y -``` - -Authenticate with the Keycloak instance using the desired credentials. +## Prerequisites -4. Verify the signed image +* RHEL x86\_64 9.2 or greater. +* Command-line access to the Ansible control node with a user that has `sudo` privileges. +* Update DNS records or `/etc/hosts` entries with the ingress host names and IP addresses. +* Installation and configuration of Ansible on a control node to perform the automation. +* Installation of the Ansible collections on the control node. + * If installing from the Ansible Automation Hub, then run `ansible-galaxy install redhat.artifact_signer`. + * If installing from this Git repository, then clone it locally, and run `ansible-galaxy collection install -r requirements.yml`. +* An OpenID Connect (OIDC) provider, such as [Keycloak](https://console.redhat.com/ansible/automation-hub/repo/published/redhat/sso/). +* The ability to resolve the ingress host names, by using the Domain Name System (DNS) or the `/etc/hosts` file. +* Optional: + Installation of the `podman` and [`cosign`](https://github.com/sigstore/cosign) binaries to verify that the RHTAS service is working as expected. + +## Deploying + +1. Create an `inventory` file with a single node under the `rhtas` group: + + ``` + [rhtas] + 123.123.123.123 + ``` + +2. Create an Ansible Playbook named `play.yml`, and replace `TODO` with your relevant information: + + ```yaml + - hosts: rhtas + vars: + base_hostname: TODO # e.g. example.com + # access credentials for registry.redhat.io (https://access.redhat.com/RegistryAuthentication) + tas_single_node_registry_username: TODO + tas_single_node_registry_password: TODO + tas_single_node_oidc_issuers: + - issuer: TODO # your OIDC provider (e.g. keycloak) URL + client_id: trusted-artifact-signer + url: TODO # your OIDC provider (e.g. keycloak) URL + type: email + tasks: + - name: Include TAS single node role + ansible.builtin.include_role: + name: redhat.artifact_signer.tas_single_node # Use if deploying from Ansible Automation Hub. + vars: + ansible_become: true + ``` + > [!NOTE] + If running this Playbook from a locally-cloned Git repository, then replace the `redhat.artifact_signer.tas_single_node` value with `tas_single_node`. + +3. Install the RHTAS Ansible collection. + + - If installing from Ansible Automation Hub, then run the following command: + + ```shell + ansible-playbook -i inventory play.yml + ``` + + - If running from a locally-cloned Git repository, then run the following command: + + ```shell + export ANSIBLE_ROLES_PATH="roles/" ; ansible-playbook -i inventory play.yml + ``` + +4. Add the root certificate authority (CA) to your local truststore: + + ```shell + sudo openssl x509 -in ~/Downloads/root-cert-from-browser -out tas-ca.pem --outform PEM + sudo mv tas-ca.pem /etc/pki/ca-trust/source/anchors/ + sudo update-ca-trust + ``` + > [!TIP] + The certificate can be downloaded from the Certificate Viewer by navigating to `https://rekor.` in a web browser. + Download the _root_ certificate that issued the Rekor certificate. + + > [!NOTE] + Add this certificate to all RHTAS client nodes that use the `cosign` and `gitsign` binaries for signing and verifying artifacts. + +## Verifying the deployment by signing a test container + +1. Export the following environment variables, replacing `TODO` with your relevant information: + + ```shell + export BASE_HOSTNAME="TODO" + export KEYCLOAK_URL="TODO" + export KEYCLOAK_REALM=TODO + + export TUF_URL=https://tuf.$BASE_HOSTNAME + export OIDC_ISSUER_URL=$KEYCLOAK_URL/auth/realms/$KEYCLOAK_REALM + export COSIGN_FULCIO_URL=https://fulcio.$BASE_HOSTNAME + export COSIGN_REKOR_URL=https://rekor.$BASE_HOSTNAME + export COSIGN_MIRROR=$TUF_URL + export COSIGN_ROOT=$TUF_URL/root.json + export COSIGN_OIDC_CLIENT_ID=$KEYCLOAK_REALM + export COSIGN_OIDC_ISSUER=$OIDC_ISSUER_URL + export COSIGN_CERTIFICATE_OIDC_ISSUER=$OIDC_ISSUER_URL + export COSIGN_YES="true" + export SIGSTORE_FULCIO_URL=$COSIGN_FULCIO_URL + export SIGSTORE_OIDC_ISSUER=$COSIGN_OIDC_ISSUER + export SIGSTORE_REKOR_URL=$COSIGN_REKOR_URL + export REKOR_REKOR_SERVER=$COSIGN_REKOR_URL + ``` + +2. Initialize The Update Framework (TUF) system: + + ```shell + cosign initialize + ``` + + > [!NOTE] + If you have used `cosign` before, you might need to delete the `~/.sigstore` directory first. + +3. Sign a test container image. + + a. Create an empty container image: + + ```shell + echo "FROM scratch" > ./tmp.Dockerfile + podman build . -f ./tmp.Dockerfile -t ttl.sh/rhtas/test-image:1h + ``` + + b. Push the empty container image to the `ttl.sh` ephemeral registry: + + ```shell + podman push ttl.sh/rhtas/test-image:1h + ``` + + c. Sign the container image: + + ```shell + cosign sign -y ttl.sh/rhtas/test-image:1h + ``` + + A web browser opens allowing you to sign the container image with an email address. + + d. Remove the temporary Docker file: + + ```shell + rm ./tmp.Dockerfile + ``` + +4. Verify the signed image by replacing `TODO` with the signer's email address: + + ```shell + cosign verify --certificate-identity=TODO ttl.sh/rhtas/test-image:1h + ``` + + If the signature verification does not result in an error, then the deployment of RHTAS was successful! -Refer to this example that verifies an image signed with email identity `sigstore-user@email.com` and issuer `https://github.com/login/oauth`. - -```shell -cosign verify \ ---certificate-identity-regexp sigstore-user \ ---certificate-oidc-issuer-regexp keycloak \ - -``` - -If the signature verification did not result in an error, the deployment of RHTAS was successful! ## Contributing ### Testing locally -This repository contains GitHub actions that will test PRs that come in with `ansible-lint` and `sanity-test` to enforce good code quality and practices. +This Git repository has GitHub actions that tests incoming PRs with `ansible-lint` and `sanity-test` to enforce good code quality and practices. To run `ansible-lint` locally: @@ -188,25 +199,27 @@ ansible-lint To run `sanity-test` locally: -The `ansible-test` command relies on a specific directory structure for collections to function correctly. This structure follows the format: - -`{...}/ansible_collections/{namespace}/{collection}/` +The `ansible-test` command relies on a specific directory structure for collections to function correctly. +This structure follows the format, `{...}/ansible_collections/{namespace}/{collection}/`. -To enable testing, make sure your local machine adheres to this format, which you can achieve by copying, symlinking, moving or cloning a repo into this structure. -`namespace` and `collection` names are not critical, as long as the overall format is kept, and no illegal characters are used such as `-`. -The `collection` refers to the current repository `artifact-signer-ansible`, while the namespace can be anything you want. +To enable testing, make sure your local machine adheres to this format, which you can achieve by copying, symlinking, moving or cloning a Git repository into this structure. +By keeping the overall format, and not using invalid characters, such as `-`, the `namespace` and `collection` names are not critical. +The `collection` refers to the current repository `artifact-signer-ansible`, while the `namespace` can be anything you want. -A valid path for our collection would be: -`{...}/ansible_collections/redhat/artifact_signer_ansible/` +A valid path for our collection would be, `{...}/ansible_collections/redhat/artifact_signer_ansible/`. -When this is achieved, you can run sanity checks by executing +To achieve this, you can run sanity checks by running the following: -`ansible-test sanity` +```shell +ansible-test sanity +``` -### Testing Deployment on a VM +### Testing Deployment on a virtual machine -The [molecule/README.md](molecule/README.md) file contains instructions on testing the deployment on a VM. By default, [testing-farm](https://docs.testing-farm.io/) is used as the VM provider. +The [molecule/README.md](molecule/README.md) file has instructions on testing the deployment on a virtual machine (VM). +By default, the VM provider is [testing-farm.io](https://docs.testing-farm.io/). ## Feedback -Any and all feedback is welcome. Submit an [Issue](https://github.com/securesign/artifact-signer-ansible/issues) or [Pull Request](https://github.com/securesign/artifact-signer-ansible/pulls) as desired. +Any and all feedback is welcome. +Submit an [Issue](https://github.com/securesign/artifact-signer-ansible/issues) or [Pull Request](https://github.com/securesign/artifact-signer-ansible/pulls) as needed.