Skip to content

Adopt TAP 3 multi-role delegations metadata format #57

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

Merged
merged 3 commits into from
May 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 72 additions & 54 deletions tuf-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,10 @@ repo](https://github.com/theupdateframework/specification/issues).
"version" : VERSION,
"expires" : EXPIRES,
"targets" : TARGETS,
("delegations" : DELEGATIONS)
("keys" : {
KEYID : KEY,
... },
"delegations" : [ DELEGATION, ... ])
}

TARGETS is an object whose format is the following:
Expand Down Expand Up @@ -824,27 +827,26 @@ repo](https://github.com/theupdateframework/specification/issues).
TARGETPATH. The application may use this information to guide download
decisions.

DELEGATIONS is an object whose format is the following:
"keys" lists the public keys to verify signatures of delegated targets
roles. Revocation and replacement of delegated targets roles keys is done by
changing the keys in this field in the delegating role's metadata.

{ "keys" : {
KEYID : KEY,
... },
"roles" : [{
"name": ROLENAME,
"keyids" : [ KEYID, ... ] ,
"threshold" : THRESHOLD,
("path_hash_prefixes" : [ HEX_DIGEST, ... ] |
"paths" : [ PATHPATTERN, ... ]),
"terminating": TERMINATING,
}, ... ]
}
"delegations" is a list of DELEGATION objects whose format is the following:

"keys" lists the public keys to verify signatures of delegated targets roles.
Revocation and replacement of delegated targets roles keys is done by
changing the keys in this field in the delegating role's metadata.
{
"name": DELEGATION_NAME,
("path_hash_prefixes" : [ HEX_DIGEST, ... ] |
"paths" : [ PATHPATTERN, ... ]),
Copy link
Member Author

Choose a reason for hiding this comment

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

TAP 3 only mentions paths, but I guess we still want to support path_hash_prefixes?

Copy link
Member

Choose a reason for hiding this comment

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

yes, especially for PEP 458

"terminating": TERMINATING,
"min_roles_in_agreement" : NUM_ROLES,
Copy link
Member Author

Choose a reason for hiding this comment

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

This was probably named min_roles_in_agreement to distinguish it from the signature threshold field. But I find it odd that one threshold field has such a specific name and the other one is generic.

Maybe the scope (delegation vs. role) is disambiguation enough and we can both call threshold?

Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe delegation_threshold?

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 field is a property of the delegation object. Addressing it as delegation.delegation_threshold seems like unnecessary redundancy.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree. Let's just call it threshold.

Copy link
Contributor

Choose a reason for hiding this comment

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

That was the reasoning, yes (distinguishing it from the other threshold). If you think it'll not be confused, then it's nice to set it to something simple.

Copy link
Member Author

@lukpueh lukpueh Nov 7, 2019

Choose a reason for hiding this comment

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

Thinking about it some more, it does make sense to distinguish it from the other threshold. Ideally, we'd have equally specific names for both, e.g. role.min_keys_in_agreement and delegation.min_roles_in_agreement or role.signature_threshold and delegation.role_threshold.

Is renaming the existing threshold field an option? Is it worthwhile? This will be is a breaking change anyway. :)

Until then I'll just leave it as threshold and min_roles_in_agreement.

"roles": [{
"rolename": ROLENAME,
"keyids": [ KEYID ],
"threshold": THRESHOLD,
}, ... ]
}

ROLENAME is the name of the delegated role. For example,
"projects".
DELEGATION_NAME is the name of the delegation.

TERMINATING is a boolean indicating whether subsequent delegations should be
considered.
Expand Down Expand Up @@ -887,18 +889,29 @@ repo](https://github.com/theupdateframework/specification/issues).
TARGETSPATH.


Prioritized delegations allow clients to resolve conflicts between delegated
roles that share responsibility for overlapping target paths. To resolve
conflicts, clients must consider metadata in order of appearance of delegations;
we treat the order of delegations such that the first delegation is trusted
over the second one, the second delegation is trusted more than the third
one, and so on. Likewise, the metadata of the first delegation will override that
of the second delegation, the metadata of the second delegation will override
that of the third one, etc. In order to accommodate prioritized
delegations, the "roles" key in the DELEGATIONS object above points to an array
of delegated roles, rather than to a hash table.

The metadata files for delegated target roles has the same format as the
NUM_ROLES is the minimum number of delegated targets roles that must be in
agreement about targets hashes and lengths entrusted by the delegation. The
delegated targets roles for a given delegation are listed in its "roles"
field.

ROLENAME is the name of the delegated targets role, e.g. "projects", KEYID
identifies a key that is authorized to sign for that role, and THRESHOLD
defines how many keys must sign for that role.

Prioritization exists both for delegations and delegated targets roles. That
is, if delegations handle overlapping targets paths, clients MUST consider
them in the order of their appearance in the "delegations" field. The
first delegation is trusted over the second one, the second delegation is
trusted over the third one, and so on. Likewise, in a multi-role delegation,
if NUM_ROLES is less than or equal to half the number of roles in the
"roles" field, different groups of roles may have different agreements
on targets hashes or lengths. Such conflicts must be
resolved by priorizing the first role in the list, that specifies target
metadata agreed to by at least NUM_ROLES.


The metadata files for delegated targets roles has the same format as the
top-level targets.json metadata file.

A targets.json example file:
Expand All @@ -914,29 +927,34 @@ repo](https://github.com/theupdateframework/specification/issues).
"signed": {
"_type": "targets",
"spec_version": "1.0.0",
"delegations": {
"keys": {
"f761033eb880143c52358d941d987ca5577675090e2215e856ba0099bc0ce4f6": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyval": {
"public": "b6e40fb71a6041212a3d84331336ecaa1f48a0c523f80ccc762a034c727606fa"
}
}
},
"roles": [
{
"keyids": [
"f761033eb880143c52358d941d987ca5577675090e2215e856ba0099bc0ce4f6"
],
"name": "project",
"paths": [
"project/file3.txt"
],
"threshold": 1
"keys": {
"f761033eb880143c52358d941d987ca5577675090e2215e856ba0099bc0ce4f6": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyval": {
"public": "b6e40fb71a6041212a3d84331336ecaa1f48a0c523f80ccc762a034c727606fa"
}
]
}
},
"delegations": [
{
"name": "project-delegation",
"paths": [
"project/file3.txt"
],
"terminating": true,
"min_roles_in_agreement" : 1,
"roles": [
{
"name": "project",
"keyids": [
"f761033eb880143c52358d941d987ca5577675090e2215e856ba0099bc0ce4f6"
],
"threshold": 1
}
]
}
],
"expires": "2030-01-01T00:00:00Z",
"targets": {
"file1.txt": {
Expand Down Expand Up @@ -1240,9 +1258,9 @@ non-volatile storage as FILENAME.EXT.
of appearance.

* **4.4.2.1**. If the current delegation is a multi-role delegation,
recursively visit each role, and check that each has signed exactly the
same non-custom metadata (i.e., length and hashes) about the target (or
the lack of any such metadata).
recursively visit each role, and check that a defined minimum number of
roles agrees about non-custom metadata, i.e. length and hashes of the
target (or the lack of any such metadata).

* **4.4.2.2**. If the current delegation is a terminating delegation,
then jump to step 5.
Expand Down