Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Biscuit v5 #162

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions SPECIFICATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ _predicates_ over the following types:
- _byte array_
- _date_
- _boolean_
- _null_
- _set_ a deduplicated list of values of any type, except _variable_ or _set_

While a Biscuit token does not use a textual representation for storage, we
Expand Down Expand Up @@ -117,6 +118,7 @@ We will represent the various types as follows:
- byte array: `hex:01A2`
- date in RFC 3339 format: `1985-04-12T23:20:50.52Z`
- boolean: `true` or `false`
- null: `null`, supported since block version 5
- set: `[ "a", "b", "c"]`

As an example, assuming we have the following facts: `parent("a", "b")`,
Expand Down Expand Up @@ -154,6 +156,8 @@ not equal, set inclusion.
A _boolean_ is `true` or `false`. It supports the following operations:
`==`, `!=`, `||`, `&&`, set inclusion.

A _null_ is a default type indicating the absence of value. It supports the operations `==` and `!=` with any other type. _null_ is always equal to itself, and not equal to any other type

A _set_ is a deduplicated list of terms of the same type. It cannot contain
variables or other sets. It supports equal, not equal, , intersection, union,
set inclusion.
Expand Down Expand Up @@ -184,13 +188,14 @@ The logic language is described by the following EBNF grammar:

<predicate> ::= <name> "(" <sp>? <term> (<sp>? "," <sp>? <term> )* <sp>? ")"
<term> ::= <fact_term> | <variable>
<fact_term> ::= <boolean> | <string> | <number> | ("hex:" <bytes>) | <date> | <set>
<set_term> ::= <boolean> | <string> | <number> | <bytes> | <date>
<fact_term> ::= <boolean> | <string> | <number> | ("hex:" <bytes>) | <date> | <null> | <set>
<set_term> ::= <boolean> | <string> | <number> | <bytes> | <date> | <null>


<number> ::= "-"? [0-9]+
<bytes> ::= ([a-z] | [0-9])+
<boolean> ::= "true" | "false"
<null> ::= "null"
<date> ::= [0-9]* "-" [0-9] [0-9] "-" [0-9] [0-9] "T" [0-9] [0-9] ":" [0-9] [0-9] ":" [0-9] [0-9] ( "Z" | ( ("+" | "-") [0-9] [0-9] ":" [0-9] [0-9] ))
<set> ::= "[" <sp>? ( <set_term> ( <sp>? "," <sp>? <set_term>)* <sp>? )? "]"

Expand Down Expand Up @@ -291,23 +296,27 @@ To validate an operation, all of a token's checks must succeed.

One block can contain one or more checks.

Their text representation is `check if` or `check all` followed by the body of the query.
Their text representation is `check if`, `check all` or `reject if` followed by the body of the query.
There can be multiple queries inside of a check, it will succeed if any of them
succeeds. They are separated by a `or` token.
succeeds (in the case of `reject if`, the check will fail if any query matches). They are separated by a `or` token.

- a `check if` query succeeds if it finds one set of facts that matches the body and expressions
- a `check all` query succeeds if all the sets of facts that match the body also succeed the expression.
`check all` can only be used starting from block version 4
- a `reject if` query succeeds if no set of facts matches the body and expressions

`check all` can only be used starting from block version 4.
`reject if` can only be used starting from block version 5.

Here are some examples of writing checks:

#### Basic token

This first token defines a list of authority facts giving `read` and `write`
rights on `file1`, `read` on `file2`. The first caveat checks that the operation
rights on `file1`, `read` on `file2`. The first check ensures that the operation
is `read` (and will not allow any other `operation` fact), and then that we have
the `read` right over the resource.
The second caveat checks that the resource is `file1`.
the `read` right over the resource.
The second check ensures that the resource is either `file1` or `file2`.
The third check ensures that the resource is not `file1`.

```
authority:
Expand All @@ -323,20 +332,24 @@ check if
----------
Block 2:
check if
resource("file1") // restrict to file1 resource
resource("file1")
or resource("file2") // restrict to file1 or file2
----------
Block 3:
reject if
resource("file1") // forbid using the token on file1
```

The verifier side provides the `resource` and `operation` facts with information
from the request.

If the verifier provided the facts `resource("file2")` and
If the verifier provided the facts `resource("file1")` and
`operation("read")`, the rule application of the first check would see
`resource("file2"), operation("read"), right("file2", "read")`
with `X = "file2"`, so it would succeed, but the second check would fail
because it expects `resource("file1")`.
`resource("file1"), operation("read"), right("file1", "read")`
with `X = "file1"`, so it would succeed, the second check would also succeed because it expects `resource("file1")` or `resource("file2")`. The third check would then fail because it would match on `resource("file1")`.

If the verifier provided the facts `resource("file1")` and
`operation("read")`, both checks would succeed.
If the verifier provided the facts `resource("file2")` and
`operation("read")`, all checks would succeed.

#### Broad authority rules

Expand Down Expand Up @@ -659,7 +672,7 @@ each block must carry its own version.
when possible, especially for biscuit versions that are only additive in terms of features.

- The lowest supported biscuit version is `3`;
- The highest supported biscuit version is `4`;
- The highest supported biscuit version is `5`;

# Version 2

Expand Down
Loading