-
Notifications
You must be signed in to change notification settings - Fork 275
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
Conversation
There was a problem hiding this 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" | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.') | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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?
tuf/client/updater.py
Outdated
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. |
There was a problem hiding this comment.
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.
tuf/client/updater.py
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor style suggestion:
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 |
tuf/client/updater.py
Outdated
@@ -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): |
There was a problem hiding this comment.
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
Outdated
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
tuf/client/updater.py
Outdated
securesystemslib.formats.PATH_SCHEMA.check_match(targets_map_filename) | ||
|
||
try: | ||
self.targets_map_file = securesystemslib.util.load_json_file(\ |
There was a problem hiding this comment.
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" | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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())) |
There was a problem hiding this comment.
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.
5490e2d
to
fde296b
Compare
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
|
targets_map_filename) | ||
|
||
except (securesystemslib.exceptions.Error) as e: | ||
raise tuf.exceptions.Error('Cannot load the targets map file: ' + str(e)) |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 <[email protected]>
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 <[email protected]>
Signed-off-by: marinamoore <[email protected]>
…itories. This assumes that the targets map file will be the same on each repository listed in the map file. Signed-off-by: marinamoore <[email protected]>
Signed-off-by: marinamoore <[email protected]>
…quest. This commit also adds some additional comments. Signed-off-by: marinamoore <[email protected]>
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 <[email protected]>
If the targets map file cannot be loaded using load_json_file, a tuf.exceptions.Error exception will be raised. Signed-off-by: marinamoore <[email protected]>
I just force-pushed to update the commit messages. |
As this is a PoC for the TAP process I've converted it to a draft. |
There was a problem hiding this 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" | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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 <[email protected]>
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. |
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.