symbols were a kind of strings with less available operations and some
specific optimizations: they store in index into a symbol table carried
by the token, to reduce size by avoiding repetitions.
They were too confusing for users, and now that #authority and #ambient
are gone, we can remove them completely.
The symbol table was useful though, so now the symbol table is used for
all predicate names and strings
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
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
before:
- rules in an authority block are authority facts generation rules
- rules in other blocks are caveats
now:
- rules in an authority block are authority facts generation rules
- rules in other block are facts generation rules for this block's validation
- caveats in the authority block are tested once at the beginning of
the validation
- caveats in an other block are specific to that block's validation