Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegation documentation #728

Merged
merged 14 commits into from
Mar 24, 2023
96 changes: 68 additions & 28 deletions playbooks/ORCHESTRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Like mentioned in [Key configuration](#key-configuration), each root key corresp

### Adding a Root Key

Instruct any new root keyholder to follow [Registering a new root key](../KEYHOLDER.md#registering-a-new-root-key)
Instruct any new root keyholder to follow [Registering a new root key](keyholders/NEW_SIGNER.md#registration).

This will create the following structure.

Expand Down Expand Up @@ -127,9 +127,70 @@ Manually check for:

<!-- TODO: Add playbook for disaster/recovery steps. -->

### Hardware Key Signing
## Step 3: Add delegation (Optional)

This step will add a delegated role to the top-level targets that is
controlled by an external GitHub repository. Coordinate with the
delegation keyholder to run the `add-delegation` command (see
https://github.com/sigstore/root-signing/blob/main/cmd/tuf/app/add-delegation.go).
When creating the delegation with the command, a `target-meta`
file has to be provided that lists the targets, similar to adding
the top level targets, see
[here](ORCHESTRATION.md#targets-and-delegation-configuration) for an
example.
After the delegation metadata is added and signed, the delegation
keyholder should open a PR against the ceremony branch.
The name of the PR MUST be `feat/add-delegation for
<delegation-name>`.
Comment on lines +141 to +144
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we provide a snippet here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an example PR, i.e the updated targets.json and an example role metadata file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of the PR generation in this repo is automated, I'm wondering if we can do the same here? Maybe an enhancement in a future PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have tooling for this, that manages all the work but currently it's not OSS. I would like to make so pretty soon.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll file a follow-up issue with references to these comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


As part of running the `add-delegaton` command, a POP (proof of
possession) has to be generated too. The computed POP should be stored
in `${REPO}/staged/${FORK_POINT}.sig`, where the fork point is the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you say "should be stored in" does that mean the person following these instructions has to do something? if this is done automatically by one of the commands below, we might say "will be stored in ..."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently there is no automation done for this, but it's shown in the stanza below:

$ FORK_POINT=$(git merge-base --fork-point origin/main "${BRANCH}") \
      ./tuf key-pop-sign \
      -key ${KEY_REF} \
      -challenge ${DELEGATION_NAME} \
      -nonce ${FORK_POINT} > ${REPO}/staged/${FORK_POINT}.sig

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or there is, but none that's open source. Yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently there is no automation done for this, but it's shown in the stanza below:

This is probably sufficient for now, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example in the documentation should show all steps required to create a delegation, and then the delegate owner could open a PR with the change-set to have it merged. So there should be no uncertainties, if so let me know and I will update the doc 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fork point from `main` and the ceremony branch. This fork point is
also used as the nonce when computing the POP (via `tuf key-pop-sign`,
see below for an example).

The delegation keyholder would run these commands (on a branch based
on the ceremony branch):

Create the delegation metadata
```shell
$ ./tuf add-delegation -name ${DELEGATION_NAME} \
-public-key ${PUB_KEY_REF} \
-target-meta delegate-meta.yaml \
-repository repository
```

```shell
$ ./tuf sign \
-roles ${DELEGATION_NAME} \
-key ${KEY_REF} \
-repository ${REPO}
```

```shell
$ FORK_POINT=$(git merge-base origin/main "${BRANCH}") \
./tuf key-pop-sign \
-key ${KEY_REF} \
-challenge ${DELEGATION_NAME} \
-nonce ${FORK_POINT} > ${REPO}/staged/${FORK_POINT}.sig
kommendorkapten marked this conversation as resolved.
Show resolved Hide resolved
```
Here `BRANCH` is the ceremony branch, not the branch for the delegation.

Next, the root and targets file must be signed. Ask each root keyholder to follow [Signing root and targets](../KEYHOLDER.md#signing-root-and-targets).
When the PR is created, it will trigger the POP verify
[workflow](../.github/workflows/delegation-pop-verify.yml).

To manually verify the POP, run `./scripts/step-0.sh && ./scripts/dpop-verify.sh ${PR_NUM}
${DELEGATION_NAME}`. Don't forget to ensure that `./scripts/verify.sh
$PR` runs on the PR to validate the `targets.json` has a valid
format and that the delegation metadata is properly signed.
Assuming verification passes, merge the PR against the ceremony branch.

## Step 4: Hardware Key Signing

Next, the root and targets file must be signed. Ask each root
keyholder to follow [Signing root and
targets](keyholders/EXISTING_SIGNER.md#signing).

This will modify `root.json` and `targets.json` with an added signature.

Expand All @@ -149,28 +210,7 @@ After each of the root keyholder PRs are merged, run verification at the head of

and verify that the root and targets are fully signed.

<!--
TODO(https://github.com/sigstore/root-signing/issues/398):
Re-instate when delegation work is complete.

## Step 3: Delegations

After root and targets signing, the delegation files must be signed.

```bash
./scripts/step-3.sh
```

This will create a PR signing the delegations. Verify the PR with the PR number as the argument to the script:

```bash
./scripts/verify.sh $PR
```

and check that the delegation was successfully signed.
-->

## Step 3: Snapshotting and Timestamping
## Step 5: Snapshotting and Timestamping

Next, the metadata will need to be snapshotted and timestamped. Invoke the staging snapshot and timestamp GitHub workflow [staging-snapshot-timestamp.yml](../.github/workflows/staging-snapshot-timestamp.yml) with the following parameters:

Expand All @@ -187,7 +227,7 @@ Verify the expirations and the signatures:

Note: You cannot test this step locally against the current staged repository, since the snapshot and timestamp keys are only given permissions to the GitHub Workflows. However, under the hood, the workflow is running `./scripts/step-3.sh` and `./scripts/step-4.sh`. If you initialize a ceremony with local testing keys, this action will work.

## Step 4: Publication
## Step 6: Publication

Once the PR from [Step 3](#step-3-snapshotting-and-timestamping) is merged, a [workflow](../.github/workflows/sync-ceremony-to-main.yml) will automatically create a PR merging the changes on the completed ceremony branch to main.

Expand All @@ -213,7 +253,7 @@ In case there is a configuration mistake or a breakage that renders a ceremony i

1. Add an environment variable for the delegation key named `$DELEGATION_KEY` in [./scripts/step-1.5.sh].

2. Create a `./config/$DELEGATION-metadata`.yml file, see [Target and Delegation configuration](#targets-and-delegation-configuration).
2. Create a `./config/$DELEGATION-metadata`.yml file, see [Target and Delegation configuration](#targets-and-delegation-configuration).

3. Edit [./scripts/step-1.5.sh] to add the delegation after the root and targets are setup via `tuf init`, with a command like:

Expand All @@ -224,4 +264,4 @@ In case there is a configuration mistake or a breakage that renders a ceremony i

The optional `-path $PATH` specifies any [paths](https://theupdateframework.github.io/specification/latest/#delegation-role-paths) that describes paths the delegated role is trusted to provide.

4. Update the [../README.md] with the delegation information in [Repository Structure](../README.md#tuf-repository-structure).
4. Update the [../README.md] with the delegation information in [Repository Structure](../README.md#tuf-repository-structure).