Skip to content

Instantly share code, notes, and snippets.

@lmars

lmars/tuf.md Secret

Last active August 29, 2015 14:12
Show Gist options
  • Save lmars/13e272b5bb4195ae24c8 to your computer and use it in GitHub Desktop.
Save lmars/13e272b5bb4195ae24c8 to your computer and use it in GitHub Desktop.
tuf repo management

tuf repo management

Directory layout

The tuf repo should have the following directory layout:

.
├── keys
├── repository
│   └── targets
└── staged
    └── targets

The directories have the following uses:

  • keys/ contains signing keys with filename pattern ROLE-KEYID.json
  • repository/ contains signed manifests
  • repository/targets/ contains hashed target files
  • staged/ contains either signed, unsigned or partially signed manifests
  • staged/targets/ contains unhashed target files

CLI

A list of commands the CLI should support.

Any command which makes changes to a manifest should stage that change by creating / updating files in the staged directory.

tuf gen-key ROLE

This generates a new signing key, serializes it to JSON and writes it to the keys directory. It also adds the given role's key ID to the root manifest.

tuf add PATH

This hashes a file at staged/targets/PATH and updates the targets manifest.

tuf remove PATH

This removes PATH from the targets manifest.

tuf snapshot [--compression=FORMAT]

This expects a staged, fully signed targets manifest and stages an appropriate snapshot manifest. It optionally compresses the targets manifest.

tuf timestamp

This stages an appropriate timestamp manifest. If a snapshot manifest is staged, it must be fully signed.

tuf sign ROLE

This signs the given role's staged manifest with all keys present in the keys directory for that role.

tuf commit

This verifies that all staged changes are signed to the correct threshold, then moves the staged files into the repository directory. It also removes any target files which are not in the targets manifest.

tuf regenerate

This recreates the targets manifest based on the files in repository/targets.

Examples

The following are example workflows for managing a tuf repository with the above proposed CLI.

The tree commands do not need to be run, but their output serve as an illustration of what files should exist after performing certain commands.

Although only two machines are referenced (i.e. the "root" and "repo" boxes), the workflows can be trivially extended to many signing machines by copying staged changes and signing on each machine in turn before finally committing.

Create signed root manifest

Generate a root key on the root box:

$ tuf gen-key root

$ tree .
.
├── keys
│   └── root-184b133f.json
├── repository
└── staged
    └── root.json

Copy staged/root.json from the root box to the repo box and generate targets, snapshot and timestamp keys on the repo box:

$ tree .
.
├── keys
├── repository
└── staged
    └── root.json

$ tuf gen-key targets

$ tuf gen-key snapshot

$ tuf gen-key timestamp

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
└── staged
    └── root.json

Copy staged/root.json from the repo box back to the root box and sign it:

$ tree .
.
├── keys
│   ├── root-184b133f.json
├── repository
└── staged
    └── root.json

$ tuf sign root

The staged root.json can now be copied back to the repo box ready to be committed alongside other manifests.

Add a target file

Assuming a staged, signed root manifest and the file to add exists at staged/targets/foo/bar/baz.txt:

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
└── staged
    ├── root.json
    └── targets
        └── foo
            └── bar
                └── baz.txt

$ tuf add foo/bar/baz.txt

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
└── staged
    ├── root.json
    ├── targets
    │   └── foo
    │       └── bar
    │           └── baz.txt
    └── targets.json

$ tuf sign targets

$ tuf snapshot

$ tuf sign snapshot

$ tuf timestamp

$ tuf sign timestamp

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
└── staged
    ├── root.json
    ├── snapshot.json
    ├── targets
    │   └── foo
    │       └── bar
    │           └── baz.txt
    ├── targets.json
    └── timestamp.json

$ tuf commit

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

Remove a target file

Assuming the file to remove is at repository/targets/foo/bar/baz.txt:

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

$ tuf remove foo/bar/baz.txt

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged
    └── targets.json

$ tuf sign targets

$ tuf snapshot

$ tuf sign snapshot

$ tuf timestamp

$ tuf sign timestamp

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged
    ├── snapshot.json
    ├── targets.json
    └── timestamp.json

$ tuf commit

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets.json
│   └── timestamp.json
└── staged

Regenerate manifests based on targets tree

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

$ tuf regenerate

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged
    └── targets.json

$ tuf sign targets

$ tuf snapshot

$ tuf sign snapshot

$ tuf timestamp

$ tuf sign timestamp

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged
    ├── snapshot.json
    ├── targets.json
    └── timestamp.json

$ tuf commit

$ tree .
.
├── keys
│   ├── snapshot-3e070e53.json
│   ├── targets-8cf4810c.json
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

Update timestamp.json

$ tree .
.
├── keys
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

$ tuf timestamp

$ tree .
.
├── keys
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged
    └── timestamp.json

$ tuf sign timestamp

$ tuf commit

$ tree .
.
├── keys
│   └── timestamp-a3768063.json
├── repository
│   ├── root.json
│   ├── snapshot.json
│   ├── targets
│   │   └── foo
│   │       └── bar
│   │           └── baz.txt
│   ├── targets.json
│   └── timestamp.json
└── staged

Modify key thresholds

TODO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment