This document establishes a procedure for the procurement, provisioning, and signing of Docker’s production TUF root.
- Elect an agent to procure and ship devices to keyholders
- Purchase a total of seventeen (17) YubiKey 5C NFC FIPS hardware authenticator devices
- Purchase two (2) hardware authenticator devices per root keyholder
- At the time of writing there were five (5) root key holders listed in resulting in a total of ten (10)
- Purchase one (1) hardware authenticator device per secure artifacts team member
- At the time of writing there were seven (7) secure artifacts team members listed
- These groups add up to seventeen (17) devices
- Purchase two (2) hardware authenticator devices per root keyholder
- Ship the YubiKey devices directly to each individual key holder
- Each key holder will confirm the serial number of the device(s) they receive according to Device Serial Verification instructions
- Download and install YubiKey Manager
- Remove the device from the tamper-proof packaging
- Inspect the backside of the device for the 8-digit serial number
- Launch YubiKey Manager UI
- Insert device and record the serial number and firmware version (you will need this data during the signing ceremony)
- Verify that the device is genuine at https://www.yubico.com/genuine/
- Follow the instructions YUBIKEY-PIV-SETUP.md to provision the YubiKey with a PIV signing certificate with the following options:
- For
Set Management Key
- Generate the key on the device
- Use the
AES256
algorithm
- For
Generate Digital Signature Certificate
- Generate the certificate on the device using the self-signed certificate
- For the signing algorithm select
ECCP384
- For expiration date select one (1) year from today
- For
- Generate attestation certificates. This creates a certificate containing your newly created public key signed by Yubico’s built-in (and verifiable) keys. This proves that the Yubikey is genuine, as well as confirming the model, serial number etc.
- Download and install
yubico-piv-tool
https://developers.yubico.com/yubico-piv-tool/Releases/ - Create a new directory using your device serial number
mkdir -p ./keys/<serial_num>/ cd !$
- Read Yubikey PIV intermediate certificate in slot f9
yubico-piv-tool --action=read-certificate --slot=f9 > SlotF9Intermediate.pem
- Read PIV attestation certificate for Digital Signature certificate in slot 9c
yubico-piv-tool --action=attest --slot=9c > Slot9CAttestation.pem
- Save these files for archival after the signing ceremony (Collect Archival Signing Ceremony Data)
- Download and install
Before performing the production TUF root signing ceremony, perform a dry-run to ensure that every key holder has all of the prerequisites completed and clearly understands the process.
- Signing event will be created at https://github.com/docker/tuf-dev
- Follow instructions at Keyholder Root Signing
- Complete Device Serial Verification and Device Provisioning
- Clone the GitHub repository https://github.com/docker/tuf
- Complete the TUF-on-CI signer setup instructions
- Designate someone to act as root signing lead
- signing lead collects a comma separated list of all root key holder GitHub handles
- signing lead collects a comma separated list of all target key holder GitHub handles
- signing lead configures
~/.aws/config
for access to the Docker Image Signing - Production (654654578585) AWS account
Tip
When installing the TUF-on-CI CLI as part of the TUF-on-CI signer setup instructions, it may be helpful to create a Python virtual environment.
$ mkdir ~/.venv $ python3 -m venv ~/.venv/tuf $ . ~/.venv/tuf/bin/activate $ pip3 install tuf-on-ci-sign
You would need to source the activate
script in any shell where you want to run the tuf-on-ci-sign
command.
This section is to be completed by the root signing lead only. In other words, root and target signers do not have to execute any of the commands in this section.
- The lead signs into Docker Image Signing - Production (654654578585) AWS account
- The lead initializes the TUF signing ceremony by running the following command:
tuf-on-ci-delegate sign/init
- When prompted to configure root enter option 1 to configure signers
Signing event sign/init (commit 85c7fc2) Creating a new TUF-on-CI repository Configuring role root 1. Configure signers: [@mrjoelkamp], requiring 1 signatures 2. Configure expiry: Role expires in 365 days, re-signing starts 60 days before expiry Please choose an option or press enter to continue: 1 Please enter list of root signers [@mrjoelkamp]:
- Paste the list of root key holder GitHub handles and press enter to continue
- Enter the root threshold value of
3
and press enter - Press enter to continue again using the default settings for root expiration:
Please choose an option or press enter to continue: 1 Please enter list of root signers [@mrjoelkamp]: @mrjoelkamp, @kipz Please enter root threshold [1]: 3 1. Configure signers: [@mrjoelkamp, @kipz], requiring 3 signatures 2. Configure expiry: Role expires in 365 days, re-signing starts 60 days before expiry Please choose an option or press enter to continue
- When prompted to configure targets select option 1 and paste the list of target key holder GitHub handles
- Enter the targets threshold value of
2
and press enter - Press enter to continue again using the default settings for target expiration:
Configuring role targets 1. Configure signers: [@mrjoelkamp, @kipz], requiring 2 signatures 2. Configure expiry: Role expires in 365 days, re-signing starts 60 days before expiry Please choose an option or press enter to continue:
- When prompted to configure the online role, select option 1 to configure the online key
- Enter option
4
forAWS KMS
- Paste the production TUF AWS KMS online key id:
arn:aws:kms:us-east-1:654654578585:key/751429f1-0aea-4bd8-b450-bb1bce6b058f
- Select option
1
forECDSA_SHA_256
- Use defaults for timestamp and snapshot expiry:
1. Configure online key: arn:aws:kms:us-east-1:654654578585:key/751429f1-0aea-4bd8-b450-bb1bce6b058f 2. Configure timestamp: Expires in 2 days, re-signing starts 1 days before expiry 3. Configure snapshot: Expires in 365 days, re-signing starts 60 days before expiry Please choose an option or press enter to continue:
- Select
2
for Yubikey, insert Yubikey if not already inserted and enter PIN to sign:Configuring signing key 1. Sigstore (OpenID Connect) 2. Yubikey Please choose the type of signing key you would like to use [1]: 2 Please insert your Yubikey and press enter: Your signature is required for role(s) {'targets'}. targets v1 * Expiry period: 365 days, signing period: 60 days Enter pin to sign: Press enter to push changes to origin/sign/init:
- Press enter to push changes to origin and initiate TUF repo
This section is to be completed by all root key and targets key holders.
- Navigate to the directory containing the clone of the repository you are signing.
- Copy the command to accept invite to join root
tuf-on-ci-sign sign/init
- Select
2
for Yubikey, insert Yubikey if not already inserted and enter PIN to signSigning event sign/init (commit d28d253) Your signature is requested for role(s) {'root'}. root v1 * Expiry period: 365 days, signing period: 60 days * New delegation root * Signers: 2/1 of ['@mrjoelkamp'] * New delegation targets * Signers: 2/1 of ['@mrjoelkamp'] * New online delegations timestamp & snapshot * Signers: 1/1 of ['awskms'] Enter pin to sign: Press enter to push signature(s) to origin/sign/init:
- Press enter to push changes to origin and complete sign-off of root and targets roles
- Once every keyholder completes Keyholder Root Signing, merge the signing event PR to main
- The signing ceremony is now complete
- Create a signing ceremony folder at https://github.com/docker/tuf using the date of the signing ceremony (if one doesn't exist already):
mkdir ./ceremony/YYYY-MM-DD/
- Add each keyholder’s key data under a
keys/
directory using their device serial number using the data they generated in Device Provisioning./ceremony/YYYY-MM-DD/keys/<serial_num>/SlotF9Intermediate.pem ./ceremony/YYYY-MM-DD/keys/<serial_num>/Slot9CAttestation.pem
- Add a
README.md
with the device key data specifying the keyholder’s username:echo "held by: @username" > ./ceremony/YYYY-MM-DD/keys/<serial_num>/README.md
- Update repo’s root
README.md
with a table including the username of each keyholder, the serial number of the device they used for the signing ceremony and their role.
- Follow key verification instructions
- Using the output of verified digital signature key attestations, verify that the
keys
defined inroot.json
match the public key output from the archived ceremony data.