Hello API Council,
We would like to kindly hear if there are any current or future use cases that call for proxying unknown envelopes in a FIDL message, i.e. an unknown union variant, or an unknown table field. For example, a component may receive a FIDL table, optionally modify certain fields, then resend the same table object to another component.
A majority of FIDL bindings support this form of proxying today, by storing unknown bytes and handles within the generated domain objects. However, as we evolved the FIDL bindings and ecosystem, it turned out that preserving unknown fields (not simply ignoring unknowns) frequently come up as a complicating factor that are prompting us to revisit this support:
It makes the ABI of a component harder to reason about: a proxying component may send messages that it does not understand, but proxied from another component.
It complicates migrating the FIDL wire format itself: a sender cannot reasonably "upgrade" or "downgrade" the wire format of a FIDL message if it contains unknown data (one could upgrade the known bits but then get an inconsistent message that is a mixture of two wire format revisions). Certain wire format optimizations are also precluded by them.
Unknown fields introduce shadow APIs and hidden values into the generated domain objects: operations which update an object may inadvertently drop the unknown fields if not careful.
Perhaps a more minor point, other design aspects in the LLCPP bindings prevent proxying unknown fields, adding an inconsistency from the other bindings.
Experiences from gRPC/protobuf have some bearing, but FIDL is also in a different enough domain such that any user stories/use cases from our own FIDL APIs would much better inform our next steps :)
Thanks,
Yifei
--
You received this message because you are subscribed to the Google Groups "api-council" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-council...@fuchsia.dev.
To view this discussion on the web visit https://groups.google.com/a/fuchsia.dev/d/msgid/api-council/CANbn4XDw%3DMy6HJsMRnxKMPppmJTovJj3mhtKTTuTYPpmPH%3D%3Diw%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/fuchsia.dev/d/msgid/api-council/CAK0PkCEeEasUc2Td8h4xp0yVNyL5_V2yQvY10kHth%3D%3DZzV%3DHuQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/fuchsia.dev/d/msgid/api-council/CADNd37jeyXvbCqx6MB6sF%3DJ-kaiGynJ5cOVyNEBAPd1YJ7zyyw%40mail.gmail.com.
By gathering use cases for proxying unknown data, we're hoping to draw commonalities from which we could generalize this "opt-in" feature, if needed.A potential path we might end up taking is that FIDL doesn't support preserving unknowns by default, but we could offer the proxying feature via different APIs or libraries. We may end up re-trodding the same footsteps as protobuf and add back unknown proxying everywhere some years down the line, but that would be guided by concrete needs.Just adding my thoughts to the two use cases (more or less) proposed above:- Eliminate parsing/serialization code for unneeded fields from Shai: I wonder if this is solved by the partial update pattern. Specifically, instead of replacing the object on the server-side wholesale, the server would merge the object sent by the client with the one it has in storage. This way it's okay if any unknown data the client doesn't understand does not appear in the object sent by the client, since that does not overwrite/delete the corresponding unknown field on the server-side.- Represent privileged/sensitive data as unknown fields from Jaehoen: IIUC, the hypothetical "better FIDL design" involves sending privileged data to unprivileged clients, and assuming that they cannot do anything with it since they're not compiled with the necessary code to parse them. From a security perspective, is it a sound guarantee though? It seems that a malicious client could reverse engineer the schema to a certain extent from the unknown data, and thus sift out potentially sensitive information. IMO the only safe way to prevent leaking info to unprivileged clients is to never send those fields in the first place.
On Tue, Aug 3, 2021 at 3:05 PM Yifei Teng <yif...@google.com> wrote:By gathering use cases for proxying unknown data, we're hoping to draw commonalities from which we could generalize this "opt-in" feature, if needed.A potential path we might end up taking is that FIDL doesn't support preserving unknowns by default, but we could offer the proxying feature via different APIs or libraries. We may end up re-trodding the same footsteps as protobuf and add back unknown proxying everywhere some years down the line, but that would be guided by concrete needs.Just adding my thoughts to the two use cases (more or less) proposed above:- Eliminate parsing/serialization code for unneeded fields from Shai: I wonder if this is solved by the partial update pattern. Specifically, instead of replacing the object on the server-side wholesale, the server would merge the object sent by the client with the one it has in storage. This way it's okay if any unknown data the client doesn't understand does not appear in the object sent by the client, since that does not overwrite/delete the corresponding unknown field on the server-side.- Represent privileged/sensitive data as unknown fields from Jaehoen: IIUC, the hypothetical "better FIDL design" involves sending privileged data to unprivileged clients, and assuming that they cannot do anything with it since they're not compiled with the necessary code to parse them. From a security perspective, is it a sound guarantee though? It seems that a malicious client could reverse engineer the schema to a certain extent from the unknown data, and thus sift out potentially sensitive information. IMO the only safe way to prevent leaking info to unprivileged clients is to never send those fields in the first place.Correct, unprivileged clients would never receive privileged data, and the server would guarantee that. But more precisely, for each privilege P, only clients cleared for P would receive data defined in P.Here, the desire was to use one common table to define data carried to both unprivileged and privileged clients, where unprivileged clients would compile against a limited set of definitions, and would remain ignorant of the rest. But privileged clients (along N dimensions of privilege) can compile against an additional slice of the table. Then, it's very nice for auditing and evolution. When we update a privilege P, an unprivileged client (or a client with an unrelated privilege Q) do not need to be recompiled or managed through an API transition; only affected clients of P need to be dealt with.