From c35d50e310db7099541275507f9d2ef64449dc0c Mon Sep 17 00:00:00 2001 From: SantiagoTorres Date: Fri, 4 Apr 2014 17:27:47 -0400 Subject: [PATCH 1/6] Update README-developer-tools.md Updated the document with mentions to project names and to fix general redaction issues. --- tuf/README-developer-tools.md | 133 ++++++++++++++++++++++++++++------ 1 file changed, 110 insertions(+), 23 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index f1d55065..802601b5 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -10,29 +10,37 @@ - [Managing keys](#managing_keys) - [Managing targets](#managing_targets) - [Delegations](#delegations) - - [Restricted paths](#restricted_paths) - - [Keys and thresholds](#keys_and_thresholds) ## Overview The TUF developer tool is a Python library that enables developers to create -and maintain the required metadata for files hosted in a TUF Repository. This -document has two parts. The first part walks through the creation of a +and maintain the required metadata for files hosted in a TUF Repository. The main +concern when generating metadata for a TUF repository is generating information +that matches the future location of the files in the repository. We use +the developer tools to generate valid information so that the project and it's +metadata can be applied to the TUF project transparently. + +This document has two parts. The first part walks through the creation of a prototypal TUF project. The second part demonstrates the full capabilities of -the TUF developer tool, which can be users to expand the project from the first -part to meet the developer''s needs. +the TUF developer tool, which can be used to expand the project from the first +part to meet the developer's needs. + + ## Creating a Simple project ## +The following section describes a very basic example usage of the developer tools with +a one-file project. + ### Generating a Key ### First, you will need to generate a key to sign the metadata. Keys are generated in pairs: one public and the other private. The private key is password-protected and is used to sign metadata. The public key can be shared freely, and is used to verify signatures made by the private key. -The generate_and_write_rsa_keypair function will create two key files in the -path (path/to/) and named "key.pub", which is the public key and "key" -which is the private key. +The generate\_and\_write\_rsa\_keypair function will create two key files +named "path/to/key.pub", which is the public key and "path/to/key", which +is the private key. ``` >>> from tuf.developer_tool import * @@ -43,9 +51,17 @@ Confirm: >>> ``` +We can also use the bits parameter to set a different key length (the default is +3072). We can also provide the password parameter in order to suppress the password +prompt. + +During this example we will be using rsa keys, but ed25519 keys are also supported. + +Now we have a key for our project, we can proceed to create our project. + ### The project class ### -TUF-dev is built around the Project class, which is used to organize groups of +The TUF developer tool is built around the Project class, which is used to organize groups of targets associated with a single set of metadata. Each Project instance keeps track of which target files are associated with a single set of metadata. Each Project instance keeps track of which target files are signed and which need @@ -54,22 +70,49 @@ roles, which are covered later. Before creating a project, you must know where it will be located in the TUF Repository. In the following example, we will create a project to be hosted as -"repo/example_project" within the repository, and store a local copy of the +"repo/unclaimed/example_project" within the repository, and store a local copy of the metadata at "path/to/metadata". The project will comprise a single target file, -"local/path/to/example_project/target_1" locally, and we will secure it with +"local/path/to/example\_project/target\_1" locally, and we will secure it with the key generated above. +First, we must import the generated keys. We can do that by issuing the following: + ``` >>> public_key = import_rsa_publickey_from_file("path/to/keys.pub") +``` ->>> project = create_new_project(metadata_directory="local/path/to/metadata/", -... targets_directory="local/path/to/example_project", -... location_in_repository="repo/example_project", key=public_key) +After importing the key, we can generate a new project with the following command +``` +>>> project = create_new_project(name="example_project", +... metadata_directory="local/path/to/metadata/", +... targets_directory="local/path/to/example_project", +... location_in_repository="repo/unclaimed", key=public_key) +``` +Let's list the arguments and make sense out of this rather long function call: + +- create a project named example_project: the name of the metadata file will match this name +- the metadata will be located in "local/path/to/metadata", this means all of the generated files +for this project will be located here +- the targets are located in local/path/to/example project. If your targets are located in some other +place, you can point the targets directory there. Files must reside under the path local/path/to/example_project or else it won't be possible to add them. +- location\_in\_repository points to repo/unclaimed, this will be prepended to the paths in the generated metadata so the signatures all match. + +Now the project is in memory and we can do different operations on it such as adding and +removing targets, delegating files, changing signatures and keys, etc. For the moment we are +interested in adding our one and only target inside the project. + +To add a target, we issue the following method: +``` >>> project.add_target("target_1") ``` +Have in mind the file "target\_1" should be located in "local/path/to/example\_project" +or else the adding procedure will throw an error. + At this point, the metadata is not valid. We have assigned a key to the project, -but we have not *signed* it with that key. +but we have not *signed* it with that key. Signing is the process of generating +a signature with our private key so it can be verified with the public key by the +server (upon uploading) and by the clients (when updating). ### Signing and writing the metadata ### @@ -85,11 +128,15 @@ Enter password for the RSA key: ``` When all changes to a project have been written, the Project instance can safely -be deleted. +be deleted. + +The project can be loaded later to update changes to the project. The metadata +contains checksums that have to match the actual files or else it won't be accepted +by the upstream repository. To make changes to existing metadata, we will need the Project again. We can -restore it with the load_project() function. +restore it with the load_project() function. ``` >>> from tuf.developer_tool import * @@ -108,8 +155,16 @@ Enter a password for the RSA key: >>> project.write() ``` +Now we have a project properly setup. The rest of this guide contains a more +in-depth description of the functions of the developer\_tool. +=== + ## Managing keys +This section describes the key-related functions and parameters that weren't +mentioned inside the example: + +### Additional parameters for key generation When generating keys, it is possible to specify the length of the key in bits and its password as parameters: @@ -119,9 +174,37 @@ and its password as parameters: The bits parameter defaults to 3072, and values below 2048 will raise an error. The password parameter is only intended to be used in scripts. +### Removing a key from a project/delegation +Removing a verification key is really simple, we should only issue the following +command: + +``` +>>> project.remove_verification_key(key) +>>> +``` + +### Adding a key to a project/delegation +Likewise, it is possible to add a key to a project by issuing the following command: +``` +>>> project.add_verification_key(pubkey) +>>> +``` +Remember that a project can only have one key, so this method will return an error +if there is already a key assigned to it. In order to replace a key we must first +delete the existing one and then add the new one. It is possible to +ommit the key parameter in the create\_new\_project function, and add the key +later. + ## Managing Targets +There are supporting functions of the targets library to make the project +maintenance easier. These functions are described in this section. + +### get\_filepaths\_in\_directory() +This function is specially useful when creating a new project to add all the files +contained in the targets directory. The following code block illustrates the usage +of this function: ``` >>> list_of_targets = \ @@ -130,18 +213,24 @@ The password parameter is only intended to be used in scripts. ... project.add_targets(list_of_targets) ``` + +### deleting targets from a project +It is possible that we want to delete existing targets inside our project. In order +to stop the developer tool to track this file we must issue the following command: ``` >>> project.remove_target(“target_1”) ``` +Now the target file won't be part of the metadata. + ## Delegations The project we created above is secured entirely by one key. If you want to allow someone else to update part of your project independently, you will need -to delegate a new role for them. For example, we can +to delegate a new role for them. For example, we can do the following: ``` ->>> other_key = import_rsa_publickey_from_file(“sombodys_public_key.pub”) +>>> other_key = import_rsa_publickey_from_file(“another_public_key.pub”) >>> project.delegate(“newrole”, [other_key], targets) ``` @@ -155,9 +244,7 @@ methods as Project. For example, we can add targets in the same way as before: ``` - - Recall that we input the other person’s key as part of a list. That list can contain any number of public keys. You can also add keys to the role after -creating it using the add_signing_key() method. +creating it using the add\_verification\_key() method. From 69c88e2328b8ea7e0b89382dd82986d51d9a0b84 Mon Sep 17 00:00:00 2001 From: zanefisher Date: Thu, 17 Apr 2014 15:43:43 -0400 Subject: [PATCH 2/6] fixes to headers and links --- tuf/README-developer-tools.md | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index 802601b5..e06db4ec 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -2,13 +2,13 @@ ## Table of Contents ## - [Overview](#overview) -- [Creating a simple project](#creating_a_simple_project) - - [Generating a key](#generating_a_key) - - [The Project class](#the_project_class) - - [Signing and writing metadata](#signing_and_writing_metadata) -- [Loading an Existing project](#Loading_an_existing_project) -- [Managing keys](#managing_keys) -- [Managing targets](#managing_targets) +- [Creating a Simple Project](#creating_a_simple_project) + - [Generating a Key](#generating_a_key) + - [The Project Class](#the_project_class) + - [Signing and Writing the Metadata](#signing_and_writing_the_metadata) +- [Loading an Existing Project](#loading_an_existing_project) +- [Managing Keys](#managing_keys) +- [Managing Targets](#managing_targets) - [Delegations](#delegations) @@ -28,11 +28,12 @@ part to meet the developer's needs. -## Creating a Simple project ## +## Creating a Simple project The following section describes a very basic example usage of the developer tools with a one-file project. -### Generating a Key ### + +### Generating a Key First, you will need to generate a key to sign the metadata. Keys are generated in pairs: one public and the other private. The private key is password-protected and is used to sign metadata. The public key can be shared freely, and is used @@ -60,7 +61,7 @@ During this example we will be using rsa keys, but ed25519 keys are also support Now we have a key for our project, we can proceed to create our project. -### The project class ### +### The Project Class The TUF developer tool is built around the Project class, which is used to organize groups of targets associated with a single set of metadata. Each Project instance keeps track of which target files are associated with a single set of metadata. Each @@ -115,7 +116,7 @@ a signature with our private key so it can be verified with the public key by th server (upon uploading) and by the clients (when updating). -### Signing and writing the metadata ### +### Signing and Writing the Metadata ### In order to sign the metadata, we need to import the private key corresponding to the public key we added to the project. One the key is loaded to the project, it will automatically be used to sign the metadata whenever it is written. @@ -135,6 +136,7 @@ contains checksums that have to match the actual files or else it won't be accep by the upstream repository. +## Loading an Existing Project To make changes to existing metadata, we will need the Project again. We can restore it with the load_project() function. @@ -157,14 +159,13 @@ Enter a password for the RSA key: Now we have a project properly setup. The rest of this guide contains a more in-depth description of the functions of the developer\_tool. -=== -## Managing keys +## Managing Keys This section describes the key-related functions and parameters that weren't mentioned inside the example: -### Additional parameters for key generation +### Additional Parameters for Key Generation When generating keys, it is possible to specify the length of the key in bits and its password as parameters: @@ -174,7 +175,7 @@ and its password as parameters: The bits parameter defaults to 3072, and values below 2048 will raise an error. The password parameter is only intended to be used in scripts. -### Removing a key from a project/delegation +### Removing a Key from a Project or Delegation Removing a verification key is really simple, we should only issue the following command: @@ -183,7 +184,7 @@ command: >>> ``` -### Adding a key to a project/delegation +### Adding a Key to a Project or Delegation Likewise, it is possible to add a key to a project by issuing the following command: ``` >>> project.add_verification_key(pubkey) @@ -195,7 +196,7 @@ delete the existing one and then add the new one. It is possible to ommit the key parameter in the create\_new\_project function, and add the key later. - + ## Managing Targets There are supporting functions of the targets library to make the project maintenance easier. These functions are described in this section. From b89bb02730c99f9e6fd262271da7a3a3f5a33792 Mon Sep 17 00:00:00 2001 From: zanefisher Date: Thu, 17 Apr 2014 15:51:26 -0400 Subject: [PATCH 3/6] remove whitespace and empty lines from examples --- tuf/README-developer-tools.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index e06db4ec..2fca8131 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -45,7 +45,6 @@ is the private key. ``` >>> from tuf.developer_tool import * - >>> generate_and_write_rsa_keypair("path/to/key") Enter a password for the RSA key: Confirm: @@ -143,7 +142,6 @@ restore it with the load_project() function. ``` >>> from tuf.developer_tool import * >>> project = load_project("local/path/to/metadata") ->>> ``` Each time the project is loaded anew, the necessary private keys must also be loaded in order to sign metadata. @@ -151,9 +149,7 @@ loaded in order to sign metadata. ``` >>> private_key = import_rsa_privatekey_from_file("path/to/key") Enter a password for the RSA key: - >>> project.load_signing_key(private_key) - >>> project.write() ``` @@ -181,14 +177,12 @@ command: ``` >>> project.remove_verification_key(key) ->>> ``` ### Adding a Key to a Project or Delegation Likewise, it is possible to add a key to a project by issuing the following command: ``` >>> project.add_verification_key(pubkey) ->>> ``` Remember that a project can only have one key, so this method will return an error if there is already a key assigned to it. In order to replace a key we must first @@ -232,7 +226,6 @@ to delegate a new role for them. For example, we can do the following: ``` >>> other_key = import_rsa_publickey_from_file(“another_public_key.pub”) - >>> project.delegate(“newrole”, [other_key], targets) ``` @@ -240,9 +233,7 @@ The new role is now an attribute of the Project instance, and contains the same methods as Project. For example, we can add targets in the same way as before: ``` - >>> project(“newrole”).add_target(“delegated_1”) - ``` Recall that we input the other person’s key as part of a list. That list can From a4c483f5c67cc12cfb417876cd99a52bec43043a Mon Sep 17 00:00:00 2001 From: zanefisher Date: Thu, 17 Apr 2014 16:19:20 -0400 Subject: [PATCH 4/6] Add headers for sections to be added. --- tuf/README-developer-tools.md | 137 ++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index 2fca8131..d949e95e 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -7,9 +7,9 @@ - [The Project Class](#the_project_class) - [Signing and Writing the Metadata](#signing_and_writing_the_metadata) - [Loading an Existing Project](#loading_an_existing_project) +- [Delegations](#delegations) - [Managing Keys](#managing_keys) - [Managing Targets](#managing_targets) -- [Delegations](#delegations) ## Overview @@ -156,68 +156,7 @@ Enter a password for the RSA key: Now we have a project properly setup. The rest of this guide contains a more in-depth description of the functions of the developer\_tool. - -## Managing Keys -This section describes the key-related functions and parameters that weren't -mentioned inside the example: - -### Additional Parameters for Key Generation -When generating keys, it is possible to specify the length of the key in bits -and its password as parameters: - -``` ->>> generate_and_write_rsa_keypair("path/to/key",bits=2048, password="pw") -``` -The bits parameter defaults to 3072, and values below 2048 will raise an error. -The password parameter is only intended to be used in scripts. - -### Removing a Key from a Project or Delegation -Removing a verification key is really simple, we should only issue the following -command: - -``` ->>> project.remove_verification_key(key) -``` - -### Adding a Key to a Project or Delegation -Likewise, it is possible to add a key to a project by issuing the following command: -``` ->>> project.add_verification_key(pubkey) -``` -Remember that a project can only have one key, so this method will return an error -if there is already a key assigned to it. In order to replace a key we must first -delete the existing one and then add the new one. It is possible to -ommit the key parameter in the create\_new\_project function, and add the key -later. - - -## Managing Targets -There are supporting functions of the targets library to make the project -maintenance easier. These functions are described in this section. - - -### get\_filepaths\_in\_directory() -This function is specially useful when creating a new project to add all the files -contained in the targets directory. The following code block illustrates the usage -of this function: -``` - ->>> list_of_targets = \ -... project.get_filepaths_in_directory(“path/within/targets/folder”, -... recursive_walk=False, follow_links=False) -... project.add_targets(list_of_targets) -``` - - -### deleting targets from a project -It is possible that we want to delete existing targets inside our project. In order -to stop the developer tool to track this file we must issue the following command: -``` ->>> project.remove_target(“target_1”) -``` -Now the target file won't be part of the metadata. - - + ## Delegations The project we created above is secured entirely by one key. If you want to @@ -240,3 +179,75 @@ Recall that we input the other person’s key as part of a list. That list can contain any number of public keys. You can also add keys to the role after creating it using the add\_verification\_key() method. +### Restricted Paths + +### Nested Delegations + +### Revoking Delegations + + +## Managing Keys +This section describes the key-related functions and parameters that weren't +mentioned inside the example: + +### Additional Parameters for Key Generation +When generating keys, it is possible to specify the length of the key in bits +and its password as parameters: + +``` +>>> generate_and_write_rsa_keypair("path/to/key",bits=2048, password="pw") +``` +The bits parameter defaults to 3072, and values below 2048 will raise an error. +The password parameter is only intended to be used in scripts. + +### Adding a Key to a Delegation +Likewise, it is possible to add a key to a project by issuing the following command: +``` +>>> project.add_verification_key(pubkey) +``` + +### Removing a Key from a Delegation +Removing a verification key is really simple, we should only issue the following +command: + +``` +>>> project.remove_verification_key(key) +``` + +Remember that a project can only have one key, so this method will return an error +if there is already a key assigned to it. In order to replace a key we must first +delete the existing one and then add the new one. It is possible to +ommit the key parameter in the create\_new\_project function, and add the key +later. + +### Changing the Project Key + +### Delegation Thresholds + + +## Managing Targets +There are supporting functions of the targets library to make the project +maintenance easier. These functions are described in this section. + + +### Adding Targets by Directory +This function is specially useful when creating a new project to add all the files +contained in the targets directory. The following code block illustrates the usage +of this function: +``` + +>>> list_of_targets = \ +... project.get_filepaths_in_directory(“path/within/targets/folder”, +... recursive_walk=False, follow_links=False) +>>> project.add_targets(list_of_targets) +``` + + +### Deleting Targets from a Project +It is possible that we want to delete existing targets inside our project. In order +to stop the developer tool to track this file we must issue the following command: +``` +>>> project.remove_target(“target_1”) +``` +Now the target file won't be part of the metadata. + From be320acf300a031d06d6f6fa81a629c489093111 Mon Sep 17 00:00:00 2001 From: zanefisher Date: Wed, 30 Apr 2014 16:44:15 -0400 Subject: [PATCH 5/6] Expand Delegations section. --- tuf/README-developer-tools.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index d949e95e..c8020baa 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -25,8 +25,6 @@ prototypal TUF project. The second part demonstrates the full capabilities of the TUF developer tool, which can be used to expand the project from the first part to meet the developer's needs. - - ## Creating a Simple project The following section describes a very basic example usage of the developer tools with @@ -177,12 +175,30 @@ methods as Project. For example, we can add targets in the same way as before: Recall that we input the other person’s key as part of a list. That list can contain any number of public keys. You can also add keys to the role after -creating it using the add\_verification\_key() method. +creating it using the [add\_verification\_key()](#adding_a_key_to_a_delegation) method. ### Restricted Paths +By default, a delegated role is permitted to add and modify targets anywhere in the +Project's targets directory. We can assign restricted paths to a delegated role to +limit this permission. + +``` +>>> project.add_restricted_paths(["restricted/filepath"], "newrole") +``` + +This will prevent the delegated role from signing targets whose local filepaths do not +begin with "restricted/filepath". We can assign several restricted filepaths to a role +by adding them to the list in the first parameter, or by invoking the method again. A +role with multiple restricted paths can add targets to any of them. + +Note that this method is invoked the parent role (in this case, the project) and takes +the delegated role name as an argument. + ### Nested Delegations + + ### Revoking Delegations @@ -200,6 +216,7 @@ and its password as parameters: The bits parameter defaults to 3072, and values below 2048 will raise an error. The password parameter is only intended to be used in scripts. + ### Adding a Key to a Delegation Likewise, it is possible to add a key to a project by issuing the following command: ``` @@ -229,7 +246,6 @@ later. There are supporting functions of the targets library to make the project maintenance easier. These functions are described in this section. - ### Adding Targets by Directory This function is specially useful when creating a new project to add all the files contained in the targets directory. The following code block illustrates the usage @@ -242,7 +258,6 @@ of this function: >>> project.add_targets(list_of_targets) ``` - ### Deleting Targets from a Project It is possible that we want to delete existing targets inside our project. In order to stop the developer tool to track this file we must issue the following command: From 89b1b54f46171ba6cfd9e83828878a6a272917af Mon Sep 17 00:00:00 2001 From: zanefisher Date: Tue, 3 Jun 2014 15:23:25 -0400 Subject: [PATCH 6/6] complete first draft to developer tool document --- tuf/README-developer-tools.md | 214 +++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 78 deletions(-) diff --git a/tuf/README-developer-tools.md b/tuf/README-developer-tools.md index c8020baa..43d9c493 100644 --- a/tuf/README-developer-tools.md +++ b/tuf/README-developer-tools.md @@ -13,32 +13,32 @@ ## Overview -The TUF developer tool is a Python library that enables developers to create -and maintain the required metadata for files hosted in a TUF Repository. The main -concern when generating metadata for a TUF repository is generating information -that matches the future location of the files in the repository. We use -the developer tools to generate valid information so that the project and it's -metadata can be applied to the TUF project transparently. +The TUF developer tool is a Python library that enables developers to create +and maintain the required metadata for files hosted in a TUF Repository. The +main concern when generating metadata for a TUF repository is generating +information that matches the future location of the files in the repository. We +use the developer tools to generate valid information so that the project and +its metadata can be applied to the TUF project transparently. This document has two parts. The first part walks through the creation of a -prototypal TUF project. The second part demonstrates the full capabilities of +prototypal TUF project. The second part demonstrates the full capabilities of the TUF developer tool, which can be used to expand the project from the first part to meet the developer's needs. ## Creating a Simple project -The following section describes a very basic example usage of the developer tools with -a one-file project. +The following section describes a very basic example usage of the developer +tools with a one-file project. ### Generating a Key -First, you will need to generate a key to sign the metadata. Keys are generated -in pairs: one public and the other private. The private key is password-protected -and is used to sign metadata. The public key can be shared freely, and is used -to verify signatures made by the private key. +First, we will need to generate a key to sign the metadata. Keys are generated +in pairs: one public and the other private. The private key is +password-protected and is used to sign metadata. The public key can be shared +freely, and is used to verify signatures made by the private key. -The generate\_and\_write\_rsa\_keypair function will create two key files -named "path/to/key.pub", which is the public key and "path/to/key", which +The generate\_and\_write\_rsa\_keypair function will create two key files named +"path/to/key.pub", which is the public key and "path/to/key", which is the private key. ``` @@ -49,43 +49,47 @@ Confirm: >>> ``` -We can also use the bits parameter to set a different key length (the default is -3072). We can also provide the password parameter in order to suppress the password -prompt. +We can also use the bits parameter to set a different key length (the default +is 3072). We can also provide the password parameter in order to suppress the +password prompt. -During this example we will be using rsa keys, but ed25519 keys are also supported. +In this example we will be using rsa keys, but ed25519 keys are also supported. -Now we have a key for our project, we can proceed to create our project. +Now we have a key for our project, we can proceed to create our project. ### The Project Class -The TUF developer tool is built around the Project class, which is used to organize groups of -targets associated with a single set of metadata. Each Project instance keeps -track of which target files are associated with a single set of metadata. Each -Project instance keeps track of which target files are signed and which need -signing, which keys are used to sign metadata. It also keeps track of delegated -roles, which are covered later. +The TUF developer tool is built around the Project class, which is used to +organize groups of targets associated with a single set of metadata. Each +Project instance keeps track of which target files are associated with a single +set of metadata. Each Project instance keeps track of which target files are +signed and which need signing, which keys are used to sign metadata. It also +keeps track of delegated roles, which are covered later. -Before creating a project, you must know where it will be located in the TUF +Before creating a project, you must know where it will be located in the TUF Repository. In the following example, we will create a project to be hosted as -"repo/unclaimed/example_project" within the repository, and store a local copy of the -metadata at "path/to/metadata". The project will comprise a single target file, -"local/path/to/example\_project/target\_1" locally, and we will secure it with -the key generated above. +"repo/unclaimed/example_project" within the repository, and store a local copy +of the metadata at "path/to/metadata". The project will comprise a single +target file, "local/path/to/example\_project/target\_1" locally, and we will +secure it with the key generated above. -First, we must import the generated keys. We can do that by issuing the following: +First, we must import the generated keys. We can do that by issuing the +following: ``` >>> public_key = import_rsa_publickey_from_file("path/to/keys.pub") ``` -After importing the key, we can generate a new project with the following command +After importing the key, we can generate a new project with the following +command: + ``` >>> project = create_new_project(name="example_project", ... metadata_directory="local/path/to/metadata/", ... targets_directory="local/path/to/example_project", ... location_in_repository="repo/unclaimed", key=public_key) ``` + Let's list the arguments and make sense out of this rather long function call: - create a project named example_project: the name of the metadata file will match this name @@ -95,22 +99,25 @@ for this project will be located here place, you can point the targets directory there. Files must reside under the path local/path/to/example_project or else it won't be possible to add them. - location\_in\_repository points to repo/unclaimed, this will be prepended to the paths in the generated metadata so the signatures all match. -Now the project is in memory and we can do different operations on it such as adding and -removing targets, delegating files, changing signatures and keys, etc. For the moment we are -interested in adding our one and only target inside the project. +Now the project is in memory and we can do different operations on it such as +adding and removing targets, delegating files, changing signatures and keys, +etc. For the moment we are interested in adding our one and only target inside +the project. To add a target, we issue the following method: + ``` >>> project.add_target("target_1") ``` -Have in mind the file "target\_1" should be located in "local/path/to/example\_project" -or else the adding procedure will throw an error. +Have in mind the file "target\_1" should be located in +"local/path/to/example\_project" or else the adding procedure will throw an +error. -At this point, the metadata is not valid. We have assigned a key to the project, -but we have not *signed* it with that key. Signing is the process of generating -a signature with our private key so it can be verified with the public key by the -server (upon uploading) and by the clients (when updating). +At this point, the metadata is not valid. We have assigned a key to the +project, but we have not *signed* it with that key. Signing is the process of +generating a signature with our private key so it can be verified with the +public key by the server (upon uploading) and by the clients (when updating). ### Signing and Writing the Metadata ### @@ -125,12 +132,20 @@ Enter password for the RSA key: >>> project.write() ``` -When all changes to a project have been written, the Project instance can safely -be deleted. +When all changes to a project have been written, the Project instance can +safely be deleted. The project can be loaded later to update changes to the project. The metadata -contains checksums that have to match the actual files or else it won't be accepted -by the upstream repository. +contains checksums that have to match the actual files or else it won't be +accepted by the upstream repository. + +At this point, if you have followed all the steps in this document so far +(substituting appropriate names and filepaths) you will have created a basic +TUF project, which can be expanded as needed. The simplest way to get your +project secured is to add all your files using add\_target() (or see [Managing +Keys](#managing_keys) on how to add whole directories). If your project has +several contributors, you may want to consider adding +[delegations](#delegations) to your project. ## Loading an Existing Project @@ -151,9 +166,6 @@ Enter a password for the RSA key: >>> project.write() ``` -Now we have a project properly setup. The rest of this guide contains a more -in-depth description of the functions of the developer\_tool. - ## Delegations @@ -174,37 +186,56 @@ methods as Project. For example, we can add targets in the same way as before: ``` Recall that we input the other person’s key as part of a list. That list can -contain any number of public keys. You can also add keys to the role after -creating it using the [add\_verification\_key()](#adding_a_key_to_a_delegation) method. +contain any number of public keys. We can also add keys to the role after +creating it using the [add\_verification\_key()](#adding_a_key_to_a_delegation) +method. ### Restricted Paths -By default, a delegated role is permitted to add and modify targets anywhere in the -Project's targets directory. We can assign restricted paths to a delegated role to -limit this permission. +By default, a delegated role is permitted to add and modify targets anywhere in +the Project's targets directory. We can assign restricted paths to a delegated +role to limit this permission. ``` >>> project.add_restricted_paths(["restricted/filepath"], "newrole") ``` -This will prevent the delegated role from signing targets whose local filepaths do not -begin with "restricted/filepath". We can assign several restricted filepaths to a role -by adding them to the list in the first parameter, or by invoking the method again. A -role with multiple restricted paths can add targets to any of them. +This will prevent the delegated role from signing targets whose local filepaths +do not begin with "restricted/filepath". We can assign several restricted +filepaths to a role by adding them to the list in the first parameter, or by +invoking the method again. A role with multiple restricted paths can add +targets to any of them. -Note that this method is invoked the parent role (in this case, the project) and takes -the delegated role name as an argument. +Note that this method is invoked the parent role (in this case, the Project) +and takes the delegated role name as an argument. ### Nested Delegations +It is possible for a delegated role to have delegations of its own. We can do +this by calling delegate() on a delegated role: +``` +>>> project("newrole").delegate(“nestedrole”, [key], targets) +``` + +Nested delegations function no differently than first-order delegations. to +demonstrate, adding a target to nested delegation looks like this: + +``` +>>> project("newrole")("nestedrole").add_target("foo") +``` ### Revoking Delegations +Delegations can be revoked, removing the delegated role from the project. + +``` +>>> project.revoke("newrole") +``` ## Managing Keys -This section describes the key-related functions and parameters that weren't -mentioned inside the example: +This section describes the key-related functions and parameters not covered in +the [Creating a Simple Project](#creating_a_simple_project) section. ### Additional Parameters for Key Generation When generating keys, it is possible to specify the length of the key in bits @@ -218,40 +249,65 @@ The password parameter is only intended to be used in scripts. ### Adding a Key to a Delegation -Likewise, it is possible to add a key to a project by issuing the following command: +New verifications keys can be added to an existing delegation using +add\_verification\_key(): + ``` ->>> project.add_verification_key(pubkey) +>>> project("rolename").add_verification_key(pubkey) ``` +A delegation can have several verification keys at once. By default, a +delegated role with multiple keys can be written using any one of their +corresponding signing keys. To modify this behavior, you can change the +delegated role's [threshold](#delegation_thrsholds). + ### Removing a Key from a Delegation -Removing a verification key is really simple, we should only issue the following -command: +Verification keys can also be removed, like this: ``` ->>> project.remove_verification_key(key) +>>> project("rolename").remove_verification_key(pubkey) ``` -Remember that a project can only have one key, so this method will return an error -if there is already a key assigned to it. In order to replace a key we must first -delete the existing one and then add the new one. It is possible to -ommit the key parameter in the create\_new\_project function, and add the key +Remember that a project can only have one key, so this method will return an +error if there is already a key assigned to it. In order to replace a key we +must first delete the existing one and then add the new one. It is possible to +omit the key parameter in the create\_new\_project() function, and add the key later. ### Changing the Project Key +Each Project instance can only have one verification key. This key can be +replaced by removing it and adding a new key, in that order. +``` +>>> project.remove_verification_key(oldkey) +>>> project.add_verification_key(new) +``` + + ### Delegation Thresholds +Every delegated role has a threshold, which determines how many of its signing +keys need to be loaded to write the role. The threshold defaults to 1, and +should not exceed the number of verification keys assigned to the role. The +threshold can be accessed as a property of a delegated role. + +``` +>>> project("rolename").threshold = 2 +``` + +The above line will set the "rolename" role's threshold to 2. + ## Managing Targets There are supporting functions of the targets library to make the project maintenance easier. These functions are described in this section. ### Adding Targets by Directory -This function is specially useful when creating a new project to add all the files -contained in the targets directory. The following code block illustrates the usage -of this function: -``` +This function is especially useful when creating a new project to add all the +files contained in the targets directory. The following code block illustrates +the usage of this function: +``` >>> list_of_targets = \ ... project.get_filepaths_in_directory(“path/within/targets/folder”, ... recursive_walk=False, follow_links=False) @@ -259,10 +315,12 @@ of this function: ``` ### Deleting Targets from a Project -It is possible that we want to delete existing targets inside our project. In order -to stop the developer tool to track this file we must issue the following command: +It is possible that we want to delete existing targets inside our project. To +stop the developer tool from tracking this file we can issue the following +command: + ``` >>> project.remove_target(“target_1”) ``` -Now the target file won't be part of the metadata. +Now the target file won't be part of the metadata.