Skip to content

Refactor to keep serialized Datalog#19

Merged
divarvel merged 3 commits into
eclipse-biscuit:mainfrom
saoirse-a:keep-serialized-datalog
Jan 15, 2026
Merged

Refactor to keep serialized Datalog#19
divarvel merged 3 commits into
eclipse-biscuit:mainfrom
saoirse-a:keep-serialized-datalog

Conversation

@saoirse-a
Copy link
Copy Markdown
Contributor

@saoirse-a saoirse-a commented Jan 8, 2026

Currently, the Swift library does not keep a serialized representation of the Datalog contents of blocks, instead generating one on the fly when it is needed (for signature verification and to serialize the token). This is problematic because the serialization of a block is non-canonical and there are multiple valid serializations for the same block (which will not all pass signature verification). The current behavior is a mistake I made when implementing the library.

This PR changes the behavior so that the Biscuit.Block type contains a DatalogBlock (the logical representation of its Datalog contents), a binary serializedDatalog field which is a valid serialization of that DatalogBlock, and the signatures on that serialization. The constructors for Biscuit.Block maintain the invariant that the serialization is a valid representation of the DatalogBlock by deriving one from the other and not allowing either to change after construction.

This also enables other simplifications throughout the library. We no longer need to keep the internment tables for third party blocks around after serialization/deserialization, so we just keep the single, main internment table which will be used in attenuation. We don't need separate internment/serialization methods on the datalog types, because they are now always interned and serialized at the same time. Several (internal) functions that could previous throw errors now cannot.

@saoirse-a
Copy link
Copy Markdown
Contributor Author

Note this makes small breaking changes to the API, but #17 also was technically a breaking change. The next release should be 2.0.0.

Currently, the Swift library does not keep a serialized
representation of the Datalog contents of blocks, instead generating one
on the fly when it is needed (for signature verification and to
serialize the token). This is problematic because the serialization of
a block is non-canonical and there are multiple valid serializations for
the same block (which will not all pass signature verification). The
current behavior is a mistake I made when implementing the library.

This PR changes the behavior so that the `Biscuit.Block` type contains
a `DatalogBlock` (the logical representation of its Datalog contents), a
binary `serializedDatalog` field which is a valid serialization of that
DatalogBlock, and the signautres on that serialization. The constructors
for `Biscuit.Block` maintain the invariant that the serialization is a
valid representation of the DatalogBlock by deriving one from the other
and not allowing either to change after construction.

This also enables other simplifications throughout the library. We no
longer need to keep the internment tables for third party blocks around
after serialization/deserialization, so we just keep the single, main
internment table which will be used in attenuation. We don't need
separate internment/serialization methods on the datalog types, because
they are now always interned and serialized at the same time.
@saoirse-a saoirse-a force-pushed the keep-serialized-datalog branch from 35f8b49 to a982853 Compare January 8, 2026 15:28
@divarvel
Copy link
Copy Markdown
Contributor

divarvel commented Jan 9, 2026

Looks good, this is similar to how biscuit-haskell does things 👍

@divarvel divarvel merged commit d4b719d into eclipse-biscuit:main Jan 15, 2026
4 checks passed
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.

2 participants