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

PoC(tap13): User Selection of the Top-Level Target Files Through Mapping Metadata #1103

Closed
wants to merge 9 commits into from

Conversation

mnm678
Copy link
Contributor

@mnm678 mnm678 commented Aug 6, 2020

This pr adds support for TAP 13. It adds support for targets mapping metadata that is defined by the client. This mapping metadata allows the client to specify which targets metadata file on the repository they would like to use as top-level targets. This mechanism allows repository managers to split a repository into multiple namespaces and for clients to specify which of these namespaces to trust.

@mnm678 mnm678 marked this pull request as ready for review August 7, 2020 19:31
@mnm678 mnm678 requested a review from lukpueh August 10, 2020 16:51
Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

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

Thanks for taking a stab at TAP13, @mnm678! Could you please take a look why the tests fail>

Also, my review is mostly about programming- and code-style. I admit that I had a hard time to know if the patch indeed implements TAP 13. Would you mind adding a few more code comments to make the intentions clearer? More details in the commit message would also help. :)

One more style-nit: Please try to stay within 80 characters per line.

"scheme": "ed25519"
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Is there an agreement about the targets map metadata format? AFAIR TAP 12 still misses the definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There isn't. I based this format on a suggestion from the comments of the TAP 13 pr. It would probably be good to get some more consensus about this or a different format.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Some of the other metadata files refer to other metadata files as well: they use the full name "targets.json" so targets_filename should probably do that too

Copy link
Member

Choose a reason for hiding this comment

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

in the intervening 1 year we've discovered multiple reasons not to use the full filename.

tuf/keydb.py Outdated

else:
logger.warning('Root Metadata file contains a key with an invalid keytype.')

Copy link
Member

Choose a reason for hiding this comment

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

Please try not to copy-paste huge blocks like these (especially if they include dubious keyid_hash_algorithm-code that is prone to change .. see secure-systems-lab/securesystemslib#227). :)

Why not just merge the two dictionaries targets_map_file['keys'] and root_metadata['keys'] into a new dict and then iterate over that one? We need to be careful though and define (and implement) the desired behavior for when there are matching keyids in both dicts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the repeated block in the latest commit. When merging the dictionaries, I chose to prioritize keys from root metadata if there is a conflict. With the current implementation's use of sha2-256 for all keyids, this conflict should not occur, but it is something that might require some more thought.

tuf/roledb.py Outdated
@@ -76,7 +76,7 @@
TOP_LEVEL_ROLES = ['root', 'targets', 'snapshot', 'timestamp']


def create_roledb_from_root_metadata(root_metadata, repository_name='default'):
def create_roledb_from_root_metadata(root_metadata, repository_name='default', targets_map_file = None):
Copy link
Member

Choose a reason for hiding this comment

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

Style nit: Please remove space around operator.

tuf/keydb.py Outdated
@@ -60,7 +60,7 @@
_keydb_dict['default'] = {}


def create_keydb_from_root_metadata(root_metadata, repository_name='default'):
def create_keydb_from_root_metadata(root_metadata, repository_name='default', targets_map_file = None):
Copy link
Member

Choose a reason for hiding this comment

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

Style nit: Please remove space around operator.

tuf/roledb.py Outdated
@@ -140,6 +144,11 @@ def create_roledb_from_root_metadata(root_metadata, repository_name='default'):
roleinfo['previous_keyids'] = roleinfo['keyids']
roleinfo['previous_threshold'] = roleinfo['threshold']

if rolename == 'targets' and targets_map_file is not None:
Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: Could be an elif, right?

if targets_map_filename is not None:
# Is 'targets_map_file' a path? If not, raise
# 'securesystemslib.exceptions.FormatError'. The actual content of the map
# file is validated later on in this method.
Copy link
Member

Choose a reason for hiding this comment

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

Please don't copy those comments. They are already everywhere (not your fault) and IMO not particularly helpful.

Comment on lines 235 to 242
self.targets_map_filename = None

if targets_map_filename is not None:
# Is 'targets_map_file' a path? If not, raise
# 'securesystemslib.exceptions.FormatError'. The actual content of the map
# file is validated later on in this method.
securesystemslib.formats.PATH_SCHEMA.check_match(targets_map_filename)
self.targets_map_filename = targets_map_filename
Copy link
Member

Choose a reason for hiding this comment

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

Minor style suggestion:

Suggested change
self.targets_map_filename = None
if targets_map_filename is not None:
# Is 'targets_map_file' a path? If not, raise
# 'securesystemslib.exceptions.FormatError'. The actual content of the map
# file is validated later on in this method.
securesystemslib.formats.PATH_SCHEMA.check_match(targets_map_filename)
self.targets_map_filename = targets_map_filename
if targets_map_filename is not None:
securesystemslib.formats.PATH_SCHEMA.check_match(targets_map_filename)
self.targets_map_filename = targets_map_filename

@@ -626,7 +641,7 @@ class Updater(object):
http://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
"""

def __init__(self, repository_name, repository_mirrors):
def __init__(self, repository_name, repository_mirrors, targets_map_file = None):
Copy link
Member

Choose a reason for hiding this comment

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

Style nit: Please remove space around operator.

tuf/client/updater.py Show resolved Hide resolved
if targets_map_file is not None:
# Is 'targets_map_file' a path? If not, raise
# 'securesystemslib.exceptions.FormatError'. The actual content of the map
# file is validated later on in this method.
Copy link
Member

Choose a reason for hiding this comment

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

See comment about this comment block above.

Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

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

Thanks for quickly addressing my comments, @mnm678. The patch looks quite good to me (modulo some minor nits in my inline comments). I will need to take another look to say for sure that this fully implements TAP13. It would be nice if other TAP authors could take a look too (especially in regards to the metadata format).

Also, please git rid of the merge commit in the PRs commit history.

securesystemslib.formats.PATH_SCHEMA.check_match(targets_map_filename)

try:
self.targets_map_file = securesystemslib.util.load_json_file(\
Copy link
Member

Choose a reason for hiding this comment

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

No need to escape the newline, there is implied line continuation inside parentheses.

"scheme": "ed25519"
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

tuf/keydb.py Outdated
# If any keyids from root metadata match those from targets_map_metadata,
# only the root metadata keys will be added. Add all keys to root_metadata
keys_to_add = dict(list(targets_map_file['keys'].items()) +
list(root_metadata['keys'].items()))
Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: This technique is discouraged (see e.g. https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python-taking-union-o). I suggest to use the copy + update technique.

@mnm678 mnm678 force-pushed the tap13 branch 3 times, most recently from 5490e2d to fde296b Compare August 21, 2020 17:38
@mnm678
Copy link
Contributor Author

mnm678 commented Aug 21, 2020

Thanks @lukpueh . I force pushed to clean up the merge commit. It looks like the linter is failing due to #1115.

@jku
Copy link
Member

jku commented Sep 17, 2020

It would be great if commits (and the PR cover letter as well) answered the question "why?", even if the answer is just a single sentence.

I understand the TAP exists but

  1. Once this is committed and no longer part of a PR the context isn't as clear and
  2. Going from no explanation at all to the somewhat academic TAP is big jump

targets_map_filename)

except (securesystemslib.exceptions.Error) as e:
raise tuf.exceptions.Error('Cannot load the targets map file: ' + str(e))
Copy link
Member

Choose a reason for hiding this comment

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

Please avoid generic exceptions in public API if possible.

Also document the exception (alternatively remove the 'Exceptions' section from the docs if it's known to be outdated).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you think a FormatError would make more sense here (to indicate that the targets map file specified an invalid filename)? Or something else?

Copy link
Member

Choose a reason for hiding this comment

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

Good question: securesystemslib seems to have a wide variety of errors here (some of which clearly aren't formaterrors) so maybe you can't avoid a generic one. In that case at least document the exceptions that may be raised.

By the way, the check_match() call just before this seems to not be needed as securesystemslib does that (unless the point was to trigger the FormatError specifically before the try-except)

This commit adds support for TAP 13 to the Updater
class. TAP 13 allows a client to specify which targets
metadata on the repository they would like to use as the
top-level targets metadata. This mechanism allows
repository managers to split a repository into multiple
namespaces and for clients to specify which of these
namespaces to trust.

This commit implements this feature by reading the
targets map file and using the indicated metadata
as top-level targets metadata.

Signed-off-by: marinamoore <mnm678@gmail.com>
The pr adds test targets mapping metadata using
the existing delegated role from the test repository.
It also adds an initial test for TAP 13 functionality

Signed-off-by: marinamoore <mnm678@gmail.com>
Signed-off-by: marinamoore <mnm678@gmail.com>
…itories.

This assumes that the targets map file will be the same on each
repository listed in the map file.

Signed-off-by: marinamoore <mnm678@gmail.com>
Signed-off-by: marinamoore <mnm678@gmail.com>
…quest.

This commit also adds some additional comments.

Signed-off-by: marinamoore <mnm678@gmail.com>
If targets map is used, use the referenced metadata instead
of the top level metadata. This makes _update_metadata_if_changed
consistent with _update_metadata.

Signed-off-by: marinamoore <mnm678@gmail.com>
If the targets map file cannot be loaded using load_json_file,
a tuf.exceptions.Error exception will be raised.

Signed-off-by: marinamoore <mnm678@gmail.com>
@mnm678
Copy link
Contributor Author

mnm678 commented Sep 21, 2020

It would be great if commits (and the PR cover letter as well) answered the question "why?", even if the answer is just a single sentence.

I just force-pushed to update the commit messages.

@joshuagl joshuagl changed the title Tap13 PoC(tap13): User Selection of the Top-Level Target Files Through Mapping Metadata Nov 26, 2020
@joshuagl joshuagl marked this pull request as draft November 26, 2020 16:27
@joshuagl
Copy link
Member

As this is a PoC for the TAP process I've converted it to a draft.

Copy link
Member

@joshuagl joshuagl left a comment

Choose a reason for hiding this comment

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

I'd suggest "targets_filename" -> "targets_rolename" as we want to move away from being file-centric in the spec

"scheme": "ed25519"
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

in the intervening 1 year we've discovered multiple reasons not to use the full filename.

Signed-off-by: Marina Moore <mnm678@gmail.com>
@lukpueh
Copy link
Member

lukpueh commented Feb 17, 2022

Now with the legacy code gone this PR will need quite a re-write.

Since most of above review comments and discussion don't seem to be relevant anymore, I suggest to close here and submit a fresh PR for TAP13 ... it should be a lot easier to build on top of the new APIs.

@lukpueh lukpueh closed this Feb 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants