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

Document the caveat structure #6

Merged
merged 3 commits into from Jan 18, 2019
Merged

Document the caveat structure #6

merged 3 commits into from Jan 18, 2019

Conversation

KellerFuchs
Copy link
Collaborator

  • Add a first description of caveats
  • Document the algorithm for interpreting caveats

channel-binding value (like the TLS transcript hash).

Available attributes, and their type, are known ahead of time by the verifier.
Some of those attributes are *critical*, and all caveats must provide a *bound*
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Some of those attributes are *critical*, and all caveats must provide a *bound*
Some of those attributes are *critical*, and the first caveat must provide a *bound*

That's @tarcieri version. I would rather enforce the property for all caveats because it means we guard against the same kind of mistake in attenuation too:

  • the minting of new credentials may be done by a service which already has a caveat on its biscuit (for instance, an login system might get a biscuit with time-limited validity, but valid for all users, ressources, and operations);
  • there are other contexts than credential minting (such as delegation) where accidental authority in attenuation is a major issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding bounds for all those attributes might make a token that is too large (let's remember, it should fit in a cookie), especially for the first caveat that might have the largest access. How could we make that as small as possible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Geal How big would the representation of foo: Any be? That is the max. overhead, per caveat and per-critical property, and we can likely shrink it down to a handful of bytes.

The main thing is that you want to always provide bounds for critical properties (cf. the discussion in Slack. TL;DR: unbounded critical properties confer accidental authority when the property is added or the property gains new possible values), so it's not so much of an overhead rather than preventing people from accidentally issuing tokens missing those caveats.

I guess that, if biscuit size becomes an issue, we could support a compression scheme in settings where preceeding caveats are readable (i.e. in a public-key-signed token). For example, the representation of a predicate could refer to predicates in preceeding caveats when they share a (sub)term.
I'm not super sure that it makes a ton of sense to argue about size when the representation format isn't nailed down, as we can't yet measure the overhead (in bytes).

Caveats describe which operations are authorized by providing predicates over
the operation's attributes.

Attributes are data, associated with the operation,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed from (initially) properties.

Some of those attributes are *critical*, and all caveats must provide a *bound*
for each critical attribute.

Bounds are a subset of predicates, that only allow the following:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to allow non-bounds predicates at all?
If so, should it be possible to put an arbitrary predicate on a critical attribute in addition to a bound?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some predicates could add data. Specifically, I'm thinking of revocation ids. You put that in a caveat, and then if it gets compromised, you send that id to the revocation system (revocation lists, etc) to invalidate that token and all of its derivated ones

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Geal I didn't include anything about additional data in here, because that felt like an orthogonal issue, but I had a (short) discussion with @tarcieri about adding another append-only structure for identity data.

The use-cases I had in mind included revocation, but also authn and non-repudiability/audit, allowing the biscuit to carry the chain of delegations that it went through. For instance, if I have a biscuit for a service, that I attenuate, mark for delegation to you, and send to you, on every (mis)use, there is a clear indication that it was the biscuit I sent you (i.e. you cannot claim it wasn't your biscuit).

I think that really deserves its own issue, because there is a bunch of pretty-subtle things to take care of, there.

DESIGN.md Outdated

Bounds are a subset of predicates, that only allow the following:
- `any <property>`: all values match;
- `<property> in <subset>`: only elements in `subset` match; this can be an
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want specific syntax for none and only <value>?
They are equivalent to <property> in [] and <property> in [ <value> ] (empty set and singleton)

- if developers accidentally fail to provide a bound, the biscuit is invalid;
- biscuits issued before the attribute was defined are implicitely revoked.

For example, consider a data store, which initially only provides read access.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the example useful?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when an attribute is already critical, for which we provided a bound, yet it changed and got more general? The biscuit would still be valid, but still suddenly get more access.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(the example is useful, btw)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Geal That's the second part of the example: when new values (there, Create and Delete IIRC?) are added, no new access is granted (unless the bound was Any, in which case that was arguably on purpose?).

By requiring that all caveats provide a bound for each critical attribute, we
can guarantee that a biscuit does not gain unintended authority when new
attributes, or new values for them, are added in the system. (The use of `any`
is considered intentional.)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make a more precise statement?

Without any, we can precisely say that no change to critical attributes (or the values they can take) results in operations being allowed that weren't previously (for the same biscuit).

## Format

XXXTODO: Update for caveats
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just remove the wire-format spec for now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep the format and the rights management part for now, but maybe adding a comment indicating we're working on those.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK; keeping as-is then (“XXXTODO: Update for [...]” should convey clearly that the section is out-of-date).

Bounds are a subset of predicates, that only allow the following:
- `any`: all values match;
- `in <subset>`: only elements in `subset` match; this can be an explicit
enumeration, or a (non-infinite) range in the case of numeric types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trying to think of other things we might need here, but none coming right now

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Geal Disjunctions of bounds (or [<bound>; <bound>; ...]) bring more expressiveness, but I can't really think of a case where I would want that.

DESIGN.md Outdated Show resolved Hide resolved
@Geal Geal merged commit 5930f49 into master Jan 18, 2019
@KellerFuchs KellerFuchs deleted the proposal/caveat-structure branch January 19, 2019 12:12
@Geal Geal mentioned this pull request Feb 8, 2019
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.

None yet

2 participants