there are two use cases for this:
- quickly loading verifier policies from a serialized state instead of
manually adding datalog elements one by one through the verifier API.
The policies could even be written in a different system then published
to running instances dynamically
- save the state of a verifier, including ambient data, facts, rules and
checks coming from a token, to later load it into another verifier and inspect
it
we generate unique revocation ids for each block of the token, that also
depend on the previous block. That way, when holding a token, we also
have valid revocation ids for each of its parent tokens.
Since they are generated from hashes of the token's data, revocation can
be added to an existing system even after tokens were created
this commit introduces a method-like syntax for these operations:
- .starts_with()
- .ends_with()
- .matches()
- .contains() (replacing the In operation)
There is no satisfying name to replace the "not in" operation, so it is
replaced by a "contains" and negation, like this: "!set.contains($var)".
The NotIn operation is removed from the V1 schema
the meaning of "caveat" was not clear enough for users (outside of those
already familiar with macaroons), while "check" is more obvious: in a
"checklist", all items must be validated.
Allow and deny policies can be added only in the verifier (not in
tokens so there's no format change here). They use rules under the hood
like checks, and are tested one by one until one of them matches.
A default policy should be added to the verifier, otherwise it will
return the NoMatchingPolicy error. To keep the current behaviour of
accepting the request once all checks have been validated, we use the
default policy "allow if true", that only contains the expression
"true".
At last, we introduce a new syntax for checks and policies:
caveat1($0) <- resource(#ambient, $0), operation(#ambient, #read), right(#authority, $0, #read)
is rewritten as:
check if resource(#ambient, $0), operation(#ambient, #read), right(#authority, $0, #read)
Similarly, allow and deny policies use "allow if" and "deny if"
prefixes. If a check contains multiple rules, they are separated with
"or". All of those keywords are case insensitive.
this changes the Protobuf format to add a version field to blocks, set
to 0 for now. This change will ship in the 0.9 version of the Rust
version.
When deserializing a token, we wil check the version field. if not
present, we assume the block is at version 0. A token can contain blocks
with different versions, so a token generated by an old library can be
attenuated by a newer one.
If the version is higher than the maximum one for the library, the token
will be rejected
the implementations of Biscuit 1.0 should try to maintain compatibility
with older versions, so tokens with the first format will be kept there
to test that compatibility
having only numbers as variable names was not making rules easy to
follow. Thanks to the symbol table, we have a mechanism to convert
between a string and a number, so we can use it to convert from a name
to an id when adding to the token, but also when printing it, so the
rule would be read the same way on both ends.
Since we're only adding more entries to the symbol table, and integer
ids are still used, tokens generated with the new variable names should
be usable directly with older implementations