question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Metadata API: Provide a way to validate object when serializing to dictionary

See original GitHub issue

Description of issue or feature request:

This issue is discussed during a couple of conversations with @jku.

We can say we are almost done with Metadata API validation during the initialization of Signed objects as summarized here: https://github.com/theupdateframework/python-tuf/issues/1140#issuecomment-971588922.

What we didn’t focus on is validation when serializing the Signed objects to dictionaries through Signed.to_dict(). This could be useful for users of Metadata API that changed the signed portion

I imagine some of the requirements for such validation are:

  1. It’s optional. As pointed out by @jku in our conversation the client using Metadata API could provide its own validation on the metadata objects. Additionally, if this kind of validation is mandatory it could slow the work of a big python-tuf client such as Warehouse working on thousands of targets.
  2. It doesn’t duplicate validation code. It will be best if we find a way to use the same exact code as the mandatory validation during the initialization without duplicating it.

One thing to consider is doing we want to add a little more complex validation, additional to the one done during initialization. For example, for Root, it probably could be useful to validate that each of the set of keyids defined in the keys dictionary is all used inside a particular role in roles.

Current behavior: No validation is done when calling to_dict() from any of the Signed child classes.

Expected behavior: Provide a way to validate an object before calling to_dict() or when calling to_dict() with an explicit option set.

PS: I didn’t include the signatures part from the Metadata objects in this discussion as their validation is a little more complex as you need access to the delegator.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:17 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
lukpuehcommented, Jan 14, 2022

There are two options on how to call the validation through the JsonSerializer:

  1. pass a validate argument when creating a JsonSerializer object.
  2. pass a validate argument when calling JSONSerializer.serialize()

I think the first option makes more sense as once a JsonSerializer is created I see no use case when the user would want to change his behavior regarding the validation.

Oh right, I remember. The first option is also consistent with how we configure compact. We only have to ask ourselves, how we want to expose this feature in Metadata.to_bytes:

https://github.com/theupdateframework/python-tuf/blob/059bfda391893a7e502ed3da5a185ab174e977dc/tuf/api/metadata.py#L242-L249

Given the computational cost of validation I lean towards a default of validate=False and not changing to_bytes for the time being, so that in order to use the feature it a user would have to call e.g.

metadata.to_bytes(JSONSerializer(compact=True, validate=True))

We can discuss this more on the PR.

1reaction
MVrachevcommented, Jan 7, 2022

As a prototype that’s pretty much what I was imagining: definitely good enough to make some sort of a decision

  • not sure that validate can rely on from_dict/to_dict – how do you know the serializer will even call to_dict? Could be that this extra validation should be a Serializer.serialize() feature? Not sure about this as serializer would then have to know which Deserializer to use… I suppose that’s not out of the question: JSONSerializer could well know to use JSONDeserializer for validation purposes.

Even if we decide to leave it as a separate API call I think it could be useful. It’s hard for me to be sure about that where we don’t have actual interaction with users of Metadata API.

  • the __eq__() implementations are 119 LOC – not as bad as I feared but obviously makes metadata.py bigger without being useful to client code
  • Metadata.__eq__() seems complex, I don’t understand why

It’s becasue the Metadata.signatures is an OrderedDict and its values are securesytemslib Signature objects which doesn’t implement __eq__. I added a comment to clarify that.

Overall: looks like a reasonable direction to me but let’s discuss with others too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

json - How to serialize a model with all validation attributes ...
This will construct a dictionary with the validation attributes for a given property ... typeof(MyModel), "MyProperty"); var validationRules = metadata.
Read more >
Models, Serialization, and Codecs — Faust 1.9.0 documentation
Models are useful when data needs to be serialized/deserialized, or whenever you just want a quick way to define data. In Faust we...
Read more >
Serializers - Django REST framework
We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a...
Read more >
C# serialization with JsonSchema and System.Text.Json
Json -based APIs that shred, map, merge, filter, compose, and otherwise process and validate JSON data from various sources, using idiomatic ...
Read more >
Object validation and conversion with Marshmallow in Python
Learn how to validate and convert Python objects with ... Serializing and deserializing objects with Marshmallow ... virtualenv api-venv.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found