This page explains how to create an attestor in Binary Authorization using
the Google Cloud CLI. As an alternative, you can perform these steps by using the
[Google Cloud console](https://docs.cloud.google.com/binary-authorization/docs/creating-attestors-console) or
the [REST API](https://docs.cloud.google.com/binary-authorization/docs/creating-attestors-rest). This task is
part of [setting up Binary Authorization](https://docs.cloud.google.com/binary-authorization/docs/setting-up).

As a Cloud Build user, you can instead use the `built-by-cloud-build` attestor
to [deploy only images built by Cloud Build](https://docs.cloud.google.com/binary-authorization/docs/deploy-cloud-build).

An [attestor](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#attestors) is a
Google Cloud resource that Binary Authorization uses to verify an [attestation](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#attestations). To learn more about attestations, see
[Binary Authorization overview](https://docs.cloud.google.com/binary-authorization/docs/overview).

To create an attestor, you do the following:

- Create a [note](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#analysis_notes) in [Artifact Analysis](https://docs.cloud.google.com/artifact-analysis/docs/artifact-analysis) to store trusted metadata used in the attestation process.
- Set up a Public-Key Infrastructure (X.509) (PKIX) key pair that can be used to verify the identity of the attestor. (Asymmetric key pairs generated by [Cloud Key Management Service](https://docs.cloud.google.com/kms/docs) (Cloud KMS) are in PKIX-compatible format.)
- Create the attestor itself in Binary Authorization, and associate the note and public key you created.

In a single-project setup, you create the attestor in the same Google Cloud
project where you configure your Binary Authorization [policy](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#policies).
For an end-to-end, single-project tutorial that includes these steps, see
[Get started using the Google Cloud CLI](https://docs.cloud.google.com/binary-authorization/docs/getting-started-cli)
or [Get started using the Google Cloud console](https://docs.cloud.google.com/binary-authorization/docs/getting-started-console).

In a multi-project setup, we recommend that you have separate projects: a
*deployer project* , where your policy is configured; an *attestor project* ,
where your attestors are stored; and an *attestation project* for attestations.
For an end-to-end, multi-project tutorial that includes these steps, see
[multi-project setup](https://docs.cloud.google.com/binary-authorization/docs/multi-project-setup-cli).

## Before you begin

Before you create attestors, do the following:

1. [Enable Binary Authorization.](https://docs.cloud.google.com/binary-authorization/docs/enabling)

2. [Set up Binary Authorization for your platform.](https://docs.cloud.google.com/binary-authorization/docs/set-up-platform)

## Set up the project environment

In this section, you set up environment variables.

Set up environment variables to store your project names and numbers. If your
attestor and deployer projects are the same project, use the same
project ID for both variables.

```
DEPLOYER_PROJECT_ID=DEPLOYER_PROJECT_ID=
DEPLOYER_PROJECT_NUMBER="$(
    gcloud projects describe "${DEPLOYER_PROJECT_ID}" \
      --format="value(projectNumber)"
)"

ATTESTOR_PROJECT_ID=ATTESTOR_PROJECT_ID
ATTESTOR_PROJECT_NUMBER="$(
    gcloud projects describe "${ATTESTOR_PROJECT_ID}" \
    --format="value(projectNumber)"
)"
```

You must also get the service account names for the projects:

```
DEPLOYER_SERVICE_ACCOUNT="service-${DEPLOYER_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
ATTESTOR_SERVICE_ACCOUNT="service-${ATTESTOR_PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
```

## Create a Artifact Analysis note

Binary Authorization uses
[Artifact Analysis](https://docs.cloud.google.com/artifact-analysis/docs/artifact-analysis) to
store trusted metadata used in the authorization process. For each attestor you
create, you must create one Artifact Analysis
[note](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#analysis_notes). Each
[attestation](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#attestations) is stored as
an occurrence of this note.

To create the note, follow these steps:

1. Set up environment variables to store the note ID and a human-readable
   description:

   ```
   NOTE_ID=NOTE_ID
   NOTE_URI="projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}"
   DESCRIPTION=DESCRIPTION
   ```

   Replace the following:
   - `NOTE_ID`: the internal name of the note in alphanumeric characters with no spaces---for example, `test-attestor-note`
   - `NOTE_URI`: the fully-qualified path to the note resource
   - `DESCRIPTION`: a human-readable display name for the note---for example, `Test Attestor Note`
2. Create a JSON file that describes the note:

   ```
   cat > /tmp/note_payload.json << EOF
   {
     "name": "${NOTE_URI}",
     "attestation": {
       "hint": {
         "human_readable_name": "${DESCRIPTION}"
       }
     }
   }
   EOF
   ```
3. Create the note by sending an HTTP request to the
   Artifact Analysis REST API:

   ```
   curl -X POST \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
       -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
       --data-binary @/tmp/note_payload.json  \
       "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/?noteId=${NOTE_ID}"
   ```

   > [!CAUTION]
   > **Caution:** Binary Authorization doesn't support Artifact Analysis [regional
   > storage](https://docs.cloud.google.com/artifact-analysis/docs/locations) or [regional
   > endpoints](https://docs.cloud.google.com/artifact-analysis/docs/endpoints). We recommend that you use the Artifact Analysis global API endpoint (`https://containeranalysis.googleapis.com/`).

   To verify that the note was created successfully, run the following command:

   ```
   curl \
       -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
       -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
       "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/"
   ```

## Set IAM permissions on the note

You must grant an [Identity and Access Management (IAM)](https://docs.cloud.google.com/iam/docs/overview) role to
the attestor project service account on the Artifact Analysis
note resource. You do this by adding the attestor project service account to the
`containeranalysis.notes.occurrences.viewer` role in the note's
IAM policy.

To add the role, do the following:

1. Generate a JSON file that contains the information needed to set the IAM
   role on your note:

   ```
   cat > /tmp/iam_request.json << EOM
   {
     "resource": "${NOTE_URI}",
     "policy": {
       "bindings": [
         {
           "role": "roles/containeranalysis.notes.occurrences.viewer",
           "members": [
             "serviceAccount:${ATTESTOR_SERVICE_ACCOUNT}"
           ]
         }
       ]
     }
   }
   EOM
   ```
2. Add the service account and requested access roles to the IAM policy for the
   note you created:

   ```
   curl -X POST  \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $(gcloud auth print-access-token)" \
       -H "x-goog-user-project: ${ATTESTOR_PROJECT_ID}" \
       --data-binary @/tmp/iam_request.json \
       "https://containeranalysis.googleapis.com/v1/projects/${ATTESTOR_PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
   ```

   > [!NOTE]
   > **Note:** When you add a role to the policy using the preceding method, it replaces any existing roles on the note. If you want to preserve existing roles, make sure that you include them in the preceding JSON data file.

### Multi-project use

If you store the attestor in one project and you deploy in a separate project,
you must grant the `roles/binaryauthorization.attestorsVerifier` role to the
service account associated with the deployer project on the attestor.

## Set up cryptographic keys

Binary Authorization lets you use PKIX keys or post-quantum cryptography (PQC)
keys to verify [attestations](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#attestations). You only need to set
up one type of key using one of the following methods:

- **[Create post-quantum cryptography (PQC) keys](https://docs.cloud.google.com/binary-authorization/docs/creating-attestors-cli#pqc-keys):** Create PQC keys managed by Cloud Key Management Service to help address threats from future quantum computers.
- **[Generate a key pair](https://docs.cloud.google.com/binary-authorization/docs/creating-attestors-cli#generate-key-pair):** Create standard PKIX key pairs using Cloud KMS or local tools.

### Create post-quantum cryptography (PQC) keys

To provide long-term security and address threats from future quantum computers,
Binary Authorization supports keys that use post-quantum cryptography (PQC)
algorithms. These algorithms are standardized to be resistant to attacks from
both classical and quantum computers.

- **Supported algorithms:** Binary Authorization supports PQC signature algorithms, such as ML-DSA-65 (Dilithium3), for creating and verifying attestations.
- **Key management:** We recommend that you manage your PQC keys using Cloud Key Management Service. Cloud KMS provides secure storage and management for these cryptographic keys.

#### Generate a PQC key pair

To create the key pair in Cloud KMS, do the following:

1. To set up environment variables needed to create the key pair, run the
   following commands:

   <br />

           KMS_KEY_PROJECT_ID=KMS_KEY_PROJECT_ID
           KMS_KEY_LOCATION=KMS_KEY_LOCATION
           KMS_KEYRING_NAME=KMS_KEYRING_NAME
           KMS_KEY_NAME=KMS_KEY_NAME
           KMS_KEY_VERSION=KMS_KEY_VERSION
           KMS_KEY_PURPOSE=asymmetric-signing
           KMS_KEY_ALGORITHM=KMS_KEY_ALGORITHM
           KMS_PROTECTION_LEVEL=KMS_PROTECTION_LEVEL
         
   <br />

2. Replace the following:

   - `KMS_KEY_PROJECT_ID`: the ID of the project where the keys are stored
   - `KMS_KEY_LOCATION`: the location of the key
   - `KMS_KEYRING_NAME`: the name of the key ring
   - `KMS_KEY_NAME`: the name of the key
   - `KMS_KEY_VERSION`: the key version
   - `KMS_KEY_ALGORITHM`: the algorithm; `ml-dsa-65`
   - `KMS_PROTECTION_LEVEL`: the protection level---for example, `software`
3. To create the key ring, run the following command:

         gcloud kms keyrings create ${KMS_KEYRING_NAME} \
             --location ${KMS_KEY_LOCATION}

4. To create the key, run the following command:

         gcloud kms keys create ${KMS_KEY_NAME} \
             --location ${KMS_KEY_LOCATION} \
             --keyring ${KMS_KEYRING_NAME}  \
             --purpose ${KMS_KEY_PURPOSE} \
             --default-algorithm ${KMS_KEY_ALGORITHM} \
             --protection-level ${KMS_PROTECTION_LEVEL}

### Generate a key pair

In this guide, you use the recommended [Elliptic Curve Digital Signature Algorithm (ECDSA)](https://docs.cloud.google.com/kms/docs/algorithms#asymmetric_signing_algorithms)
to generate a PKIX key pair. You can also use RSA or PGP key pairs.
See [Key purposes and algorithms](https://docs.cloud.google.com/kms/docs/algorithms) for more information on
signing algorithms.

A [PKIX key pair](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#cryptographic_keys)
comprises a private key that [signers](https://docs.cloud.google.com/binary-authorization/docs/key-concepts#signers)
use to sign attestations, and a public key that you add to the attestor. At
deployment time, Binary Authorization uses this public key to verify the
attestation.

### PKIX (Cloud KMS)

To create the key pair in Cloud KMS, do the following:

1. To set up environment variables needed to create the key pair, run the
   following commands:

       KMS_KEY_PROJECT_ID=KMS_KEY_PROJECT_ID
       KMS_KEY_LOCATION=KMS_KEY_LOCATION
       KMS_KEYRING_NAME=KMS_KEYRING_NAME
       KMS_KEY_NAME=KMS_KEY_NAME
       KMS_KEY_VERSION=KMS_KEY_VERSION
       KMS_KEY_PURPOSE=asymmetric-signing
       KMS_KEY_ALGORITHM=KMS_KEY_ALGORITHM
       KMS_PROTECTION_LEVEL=KMS_PROTECTION_LEVEL

   Replace the following:
   - `KMS_KEY_PROJECT_ID`: the ID of the project where the keys are stored
   - `KMS_KEY_LOCATION`: the location of the key
   - `KMS_KEYRING_NAME`: the name of the key ring
   - `KMS_KEY_NAME`: the name of the key
   - `KMS_KEY_VERSION`: the key version
   - `KMS_KEY_ALGORITHM`: the algorithm; `ec-sign-p256-sha256` is recommended
   - `KMS_PROTECTION_LEVEL`: the protection level---for example, `software`
2. To create the key ring, run the following command:

       gcloud kms keyrings create ${KMS_KEYRING_NAME} \
           --location ${KMS_KEY_LOCATION}

3. To create the key, run the following command:

       gcloud kms keys create ${KMS_KEY_NAME} \
           --location ${KMS_KEY_LOCATION} \
           --keyring ${KMS_KEYRING_NAME}  \
           --purpose ${KMS_KEY_PURPOSE} \
           --default-algorithm ${KMS_KEY_ALGORITHM} \
           --protection-level ${KMS_PROTECTION_LEVEL}

   Replace the following:
   - `KMS_KEY_NAME`: the name of the key
   - `KMS_KEY_LOCATION`: the location of the key
   - `KMS_KEYRING_NAME`: the name of the key ring
   - `KMS_KEY_PURPOSE`: the purpose of the key, set to `ASYMMETRIC_SIGN`
   - `KMS_KEY_ALGORITHM`: the algorithm, `ec-sign-p256-sha256` is recommended
   - `KMS_PROTECTION_LEVEL`: the protection level---for example, `software`

### PKIX (local key)


> [!WARNING]
> **Warning:** We strongly recommend against using locally generated key pairs in production environments as they present a security risk. We recommend that you instead use Cloud Key Management Service. This example is provided for illustrative purposes only.

<br />

To generate a new local asymmetric PKIX key pair and store it in a file,
do the following:

1. Generate the private key:

   <var translate="no">PRIVATE_KEY_FILE</var> is the name of the file containing the
   private key used for signing the attestation payload.

   ```
   PRIVATE_KEY_FILE="/tmp/ec_private.pem"
   openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
   ```
2. Extract the public key from the private key and store it in a file:

   <var translate="no">PUBLIC_KEY_FILE</var> is the name of the file containing the public
   key that is stored in the attestor.

   ```
   PUBLIC_KEY_FILE="/tmp/ec_public.pem"
   openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
   ```

## Create the attestor

To create the attestor, follow these steps:

1. Set up an environment variable to store the name of the attestor as defined
   in Binary Authorization:

   ```
   ATTESTOR_NAME=ATTESTOR_NAME
   ```

   Replace <var translate="no">ATTESTOR_NAME</var> with the name of the attestor that you want
   to create (for example, `build-secure` or `prod-qa`).
2. Create the attestor resource in Binary Authorization:

   ```
   gcloud --project="${ATTESTOR_PROJECT_ID}" \
       container binauthz attestors create "${ATTESTOR_NAME}" \
       --attestation-authority-note="${NOTE_ID}" \
       --attestation-authority-note-project="${ATTESTOR_PROJECT_ID}"
   ```
3. Add an IAM role binding for the deployer project to the attestor. This is
   used by Binary Authorization when it evaluates a policy to determine whether
   the project has permissions to access any associated attestations.

   ```
   gcloud container binauthz attestors add-iam-policy-binding \
       "projects/${ATTESTOR_PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
       --member="serviceAccount:${DEPLOYER_SERVICE_ACCOUNT}" \
       --role=roles/binaryauthorization.attestorsVerifier
   ```
4. To add the public key to the attestor, do the following:

   ### PKIX (Cloud KMS)

   To add the public key from a Cloud KMS key pair to the
   attestor, run the following command:

   ```
   gcloud --project="${ATTESTOR_PROJECT_ID}" \
       container binauthz attestors public-keys add \
       --attestor="${ATTESTOR_NAME}" \
       --keyversion-project="${KMS_KEY_PROJECT_ID}" \
       --keyversion-location="${KMS_KEY_LOCATION}" \
       --keyversion-keyring="${KMS_KEYRING_NAME}" \
       --keyversion-key="${KMS_KEY_NAME}" \
       --keyversion="${KMS_KEY_VERSION}"
   ```

   ### PKIX (local key)

   To add a locally stored PKIX public key to an attestor, run the
   following command:

   ```
   gcloud --project="${ATTESTOR_PROJECT_ID}" \
       container binauthz attestors public-keys add \
       --attestor="${ATTESTOR_NAME}" \
       --pkix-public-key-file=${PUBLIC_KEY_FILE} \
       --pkix-public-key-algorithm=ecdsa-p256-sha256
   ```

   If you add a public key to an attestor and don't specify a key ID
   (which can be any string), it is automatically be given one in the
   RFC 6920 format: `ni:///sha-256;...`, where `...` is an encoded hash of
   the public key. This value is returned in the `id` field of the command
   output. The returned ID can be saved in `PUBLIC_KEY_ID` and
   used to create an attestation.

## Save the public key ID

To create an attestation, you need the public key ID.

To save the public key ID, you can copy it from the output of the preceding
`binauthz attestors public-keys add` command.

Alternatively, you can view your attestor's public key ID at any time using
the following command:

`gcloud container binauthz attestors describe ${ATTESTOR_NAME}`.

To save your public key ID in an environment variable, enter the following
command:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
    --format='value(userOwnedGrafeasNote.publicKeys[0].id)')

## Verify that the attestor was created

To verify that the attestor was created, run the following command:

```
gcloud container binauthz attestors list \
    --project="${ATTESTOR_PROJECT_ID}"

```

## What's next

- Learn how to [create attestations](https://docs.cloud.google.com/binary-authorization/docs/making-attestations) for your attestor.
- Update your Binary Authorization policy to require attestations using the [Google Cloud console](https://docs.cloud.google.com/binary-authorization/docs/configuring-policy-console), the [Google Cloud CLI](https://docs.cloud.google.com/binary-authorization/docs/configuring-policy-cli), and the [REST API](https://docs.cloud.google.com/binary-authorization/docs/configuring-policy-rest).