Bring manual up to date and repair links
This commit is contained in:
parent
fd8e32d655
commit
3d9b377a62
|
@ -307,7 +307,7 @@ language, the Preserves concept of an *embedded value* is used in the SAM to rel
|
||||||
portions of a datum referring to SAM entities.
|
portions of a datum referring to SAM entities.
|
||||||
|
|
||||||
Concretely, in [Preserves text
|
Concretely, in [Preserves text
|
||||||
syntax](https://preserves.dev/preserves.html#textual-syntax), embedded values
|
syntax](https://preserves.dev/preserves-text.html), embedded values
|
||||||
appear prepended with `#!`. In messages transferred across links using the [Syndicate network
|
appear prepended with `#!`. In messages transferred across links using the [Syndicate network
|
||||||
protocol][], references might appear as `#![0 123]`, `#![1 555]`, etc. etc.
|
protocol][], references might appear as `#![0 123]`, `#![1 555]`, etc. etc.
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,11 @@ automatically, losslessly translatable from one syntax to another because Preser
|
||||||
are syntax-independent.
|
are syntax-independent.
|
||||||
|
|
||||||
The core Preserves specification defines a text-based, human-readable, JSON-like syntax, that
|
The core Preserves specification defines a text-based, human-readable, JSON-like syntax, that
|
||||||
is a syntactic superset of JSON, and a completely equivalent compact binary syntax, crucial to
|
is a syntactic superset of JSON, and a completely equivalent compact machine-oriented syntax,
|
||||||
the definition of [canonical form](#canonical-form) for Preserves values.[^syrup]
|
crucial to the definition of [canonical form](#canonical-form) for Preserves values.[^syrup]
|
||||||
|
|
||||||
Here are a few example values, written using the text syntax (see [the
|
Here are a few example values, written using the text syntax (see [the
|
||||||
specification](https://preserves.dev/preserves.html#textual-syntax) for the
|
specification](https://preserves.dev/preserves-text.html) for the
|
||||||
grammar):
|
grammar):
|
||||||
|
|
||||||
Boolean : #t #f
|
Boolean : #t #f
|
||||||
|
@ -84,10 +84,10 @@ Commas are optional in sequences, sets, and dictionaries.
|
||||||
|
|
||||||
### Canonical form
|
### Canonical form
|
||||||
|
|
||||||
Every Preserves value can be serialized into a *canonical form* using the [binary
|
Every Preserves value can be serialized into a *canonical form* using the [machine-oriented
|
||||||
syntax](https://preserves.dev/preserves.html#compact-binary-syntax) along with
|
syntax](https://preserves.dev/preserves-binary.html) along with [a few simple
|
||||||
[a few simple rules](https://preserves.dev/canonical-binary.html) about
|
rules](https://preserves.dev/canonical-binary.html) about serialization ordering of elements in
|
||||||
serialization ordering of elements in sets and keys in dictionaries.
|
sets and keys in dictionaries.
|
||||||
|
|
||||||
Having a canonical form means that, for example, a cryptographic hash of a value's canonical
|
Having a canonical form means that, for example, a cryptographic hash of a value's canonical
|
||||||
serialization can be used as a unique fingerprint for the value.
|
serialization can be used as a unique fingerprint for the value.
|
||||||
|
|
|
@ -39,15 +39,15 @@ The following definitions are taken from the
|
||||||
schema. For further detail, see the [reference](../../protocols/syndicate/gatekeeper.md).
|
schema. For further detail, see the [reference](../../protocols/syndicate/gatekeeper.md).
|
||||||
|
|
||||||
```preserves-schema
|
```preserves-schema
|
||||||
SturdyRef = <ref @oid any @caveatChain [Attenuation ...] @sig bytes>.
|
SturdyRef = <ref @oid any @caveatChain [Caveat ...] @sig bytes>.
|
||||||
```
|
```
|
||||||
|
|
||||||
Within a `ref` record, the `oid` field is a free-form value that the targeted service chooses
|
Within a `ref` record, the `oid` field is a free-form value that the targeted service chooses
|
||||||
to name itself. The `sig` is an iterated keyed-HMAC construction, just as in [macaroons][].
|
to name itself. The `sig` is an iterated keyed-HMAC construction, just as in [macaroons][].
|
||||||
First, the service's secret key is used to key an HMAC of the `oid`. Then, the result is used
|
First, the service's secret key is used to key an HMAC of the `oid`. Then, the result is used
|
||||||
to key an HMAC of the first `Attenuation` in `caveatChain`. Each `Attenuation`'s HMAC becomes
|
to key an HMAC of the ([canonical form](../../guide/preserves.md#canonical-form) of the) first
|
||||||
the key for the next in the `caveatChain`. The final result is equal to the `sig` field in a
|
`Caveat` in `caveatChain`. Each `Caveat`'s HMAC becomes the key for the next in the
|
||||||
valid sturdyref.
|
`caveatChain`. The final result is equal to the `sig` field in a valid sturdyref.
|
||||||
|
|
||||||
### Attenuation of authority
|
### Attenuation of authority
|
||||||
|
|
||||||
|
@ -56,19 +56,13 @@ sturdyref, the `caveatChain` is used to [attenuate](../../glossary.md#attenuatio
|
||||||
authority denoted by the sturdyref by filtering and/or rewriting assertion and message bodies.
|
authority denoted by the sturdyref by filtering and/or rewriting assertion and message bodies.
|
||||||
The `caveatChain` is run *right to left*, with newer rewrites-and-filters at the right-hand end
|
The `caveatChain` is run *right to left*, with newer rewrites-and-filters at the right-hand end
|
||||||
of the chain and older ones at the left-hand end. Of course, an empty `caveatChain` is an
|
of the chain and older ones at the left-hand end. Of course, an empty `caveatChain` is an
|
||||||
unattenuated reference.
|
unattenuated reference. The structure and interpretation of `Caveat`s is described fully in
|
||||||
|
[the relevant section of the Syndicate network protocol
|
||||||
|
specification](../../protocol.md#attenuation-of-authority).
|
||||||
|
|
||||||
```preserves-schema
|
The term "caveat" is shamelessly taken from [macaroons][], though our caveats presently embody
|
||||||
Attenuation = [Caveat ...].
|
only what in the Macaroons paper are called "first-party caveats" over assertion structure;
|
||||||
```
|
future versions of the server may add "third-party caveats" and other, richer, predicates over
|
||||||
|
assertions.
|
||||||
Each individual `Attenuation` in a `caveatChain` is a sequence of `Caveat`s. The term "caveat"
|
|
||||||
is shamelessly taken from [macaroons][], though our caveats presently embody only what in the
|
|
||||||
Macaroons paper are called "first-party caveats" over assertion structure; future versions of
|
|
||||||
the server may add "third-party caveats" and other, richer, predicates over assertions.
|
|
||||||
|
|
||||||
Each `Attenuation`'s `Caveat`s are run in *right to left* order. The structure and
|
|
||||||
interpretation of `Caveat`s is described fully in [the relevant section of the Syndicate
|
|
||||||
network protocol specification](../../protocol.md#attenuation-of-authority).
|
|
||||||
|
|
||||||
[Macaroons]: ../../glossary.md#macaroon
|
[Macaroons]: ../../glossary.md#macaroon
|
||||||
|
|
|
@ -31,13 +31,13 @@ name](#the-active-target).
|
||||||
*Program* = *Instruction* ...
|
*Program* = *Instruction* ...
|
||||||
|
|
||||||
A configuration source file is a file whose name ends in `.pr` that contains zero or more
|
A configuration source file is a file whose name ends in `.pr` that contains zero or more
|
||||||
Preserves [text-syntax](https://preserves.dev/preserves.html#textual-syntax)
|
Preserves [text-syntax](https://preserves.dev/preserves-text.html)
|
||||||
values, which are together interpreted as a sequence of *Instruction*s.
|
values, which are together interpreted as a sequence of *Instruction*s.
|
||||||
|
|
||||||
**Comments.** [Preserves
|
**Comments.** [Preserves
|
||||||
comments](https://preserves.dev/conventions.html#comments) are ignored. One
|
comments](https://preserves.dev/conventions.html#comments) are ignored. One
|
||||||
unfortunate wart is that because Preserves comments are really
|
unfortunate wart is that because Preserves comments are really
|
||||||
[annotations](https://preserves.dev/preserves.html#annotations), they are
|
[annotations](https://preserves.dev/preserves-text.html#annotations), they are
|
||||||
required by the Preserves data model to be attached to some other value. Syntactically, this
|
required by the Preserves data model to be attached to some other value. Syntactically, this
|
||||||
manifests as the need for *some non-comment following every comment*. In scripts written to
|
manifests as the need for *some non-comment following every comment*. In scripts written to
|
||||||
date, often an empty *SequencingInstruction* serves to anchor comments at the end of a file:
|
date, often an empty *SequencingInstruction* serves to anchor comments at the end of a file:
|
||||||
|
@ -182,7 +182,7 @@ facet terminates, *Instruction* is run.
|
||||||
`dataspace` |
|
`dataspace` |
|
||||||
`timestamp` |
|
`timestamp` |
|
||||||
`facet` |
|
`facet` |
|
||||||
`stringify` *ConvenienceExpr* |
|
`stringify` *ConvenienceExpr* |
|
||||||
*ValueExpr*
|
*ValueExpr*
|
||||||
|
|
||||||
Values can be destructured and new variables introduced into the environment with `let`, which
|
Values can be destructured and new variables introduced into the environment with `let`, which
|
||||||
|
@ -248,30 +248,47 @@ special syntax for *[attenuated](../glossary.md#attenuation) entity references*,
|
||||||
|
|
||||||
## Attenuation Expressions
|
## Attenuation Expressions
|
||||||
|
|
||||||
*AttenuationExpr* = `<* $`*var*` [`*Rewrite* ...`]>`
|
*AttenuationExpr* = `<* $`*var*` [`*Caveat* ...`]>`
|
||||||
|
|
||||||
|
*Caveat* =
|
||||||
|
`<or [`*Rewrite* ...`]>` |
|
||||||
|
`<reject `*PatternExpr*`>` |
|
||||||
|
*Rewrite*
|
||||||
|
|
||||||
*Rewrite* =
|
*Rewrite* =
|
||||||
`<filter `*PatternExpr*`>` |
|
`<accept `*PatternExpr*`>` |
|
||||||
`<rewrite `*PatternExpr*` `*TemplateExpr*`>`
|
`<rewrite `*PatternExpr*` `*TemplateExpr*`>`
|
||||||
|
|
||||||
An attenuation expression looks up *var* in the environment, asserts that it is an entity
|
An attenuation expression looks up *var* in the environment, asserts that it is an entity
|
||||||
reference *orig*, and returns a new entity reference *ref*, like *orig* but
|
reference *orig*, and returns a new entity reference *ref*, like *orig* but
|
||||||
[attenuated](../glossary.md#attenuation) with zero or more *Rewrite*s. The result of evaluation
|
[attenuated](../glossary.md#attenuation) with zero or more *Caveat*s. The result of evaluation
|
||||||
is *ref*, the new attenuated entity reference.
|
is *ref*, the new attenuated entity reference.
|
||||||
|
|
||||||
When an assertion is published or a message body arrives at *ref*, the sequence of *Rewrite*s
|
When an assertion is published or a message arrives at *ref*, the sequence of *Caveats*s is
|
||||||
is executed left-to-right. If a *Rewrite* succeeds, the value if produces is forwarded on to
|
executed **right-to-left**, transforming and possibly discarding the asserted value or message
|
||||||
*orig*. If all *Rewrite*s fail, the assertion or message is silently ignored.
|
body. If all *Caveat*s succeed, the final transformed value is forwarded on to *orig*. If any
|
||||||
|
*Caveat* fails, the assertion or message is silently ignored.
|
||||||
|
|
||||||
A `rewrite` *Rewrite* matches values with *PatternExpr*. If the match fails, the next *Rewrite*
|
A *Caveat* can be one of three possibilities:
|
||||||
is tried; if it succeeds, the resulting bindings are used along with the current environment to
|
|
||||||
evaluate *TemplateExpr*, and the resulting value is forwarded on to *orig*.
|
|
||||||
|
|
||||||
A `filter` *Rewrite* is the same as `<rewrite <?`*v*` `*PatternExpr*`> $`*v*`>`, for some fresh
|
- An `or` of multiple alternative *Rewrite*s. The first *Rewrite* to accept (and possibly
|
||||||
*v*.
|
transform) the input value causes the whole `or` *Caveat* to succeed. If all the *Rewrite*s
|
||||||
|
in the `or` fail, the `or` itself fails. Supplying a *Caveat* that is an `or` containing
|
||||||
|
zero *Rewrite*s will reject *all* assertions and messages.
|
||||||
|
|
||||||
Supplying zero *Rewrite*s will cause the new entity to reject *all* assertions and messages
|
- A `reject`, which allows all values through unchanged except those matching *PatternExpr*.
|
||||||
sent to it.
|
|
||||||
|
- A simple *Rewrite*.
|
||||||
|
|
||||||
|
A *Rewrite* can be one of two possibilities:
|
||||||
|
|
||||||
|
- A `rewrite`, which matches input values with *PatternExpr*. If the match fails, the
|
||||||
|
*Rewrite* fails. If it succeeds, the resulting bindings are used along with the current
|
||||||
|
environment to evaluate *TemplateExpr*, and the *Rewrite* succeeds, yielding the resulting
|
||||||
|
value.
|
||||||
|
|
||||||
|
- An `accept`, which is the same as `<rewrite <?`*v*` `*PatternExpr*`> $`*v*`>` for some fresh
|
||||||
|
*v*.
|
||||||
|
|
||||||
## Pattern Expressions
|
## Pattern Expressions
|
||||||
|
|
||||||
|
@ -348,10 +365,10 @@ binding the resulting capability to `$sys`. Any `require-service` record publish
|
||||||
rewritten into a `require-core-service` record; other assertions are forwarded unchanged.
|
rewritten into a `require-core-service` record; other assertions are forwarded unchanged.
|
||||||
|
|
||||||
```preserves
|
```preserves
|
||||||
let ?sys = <* $config [
|
let ?sys = <* $config [<or [
|
||||||
<rewrite <require-service ?s> <require-core-service $s>>
|
<rewrite <require-service ?s> <require-core-service $s>>
|
||||||
<filter _>
|
<accept _>
|
||||||
]>
|
]>]>
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, `$sys` is used to build the initial environment for a [configuration
|
Then, `$sys` is used to build the initial environment for a [configuration
|
||||||
|
|
|
@ -124,10 +124,10 @@ expression](./scripting.md#attenuation-expressions) rewrites `require-service` a
|
||||||
`require-core-service` assertions:
|
`require-core-service` assertions:
|
||||||
|
|
||||||
```preserves
|
```preserves
|
||||||
let ?sys = <* $config [
|
let ?sys = <* $config [<or [
|
||||||
<rewrite <require-service ?s> <require-core-service $s>>
|
<rewrite <require-service ?s> <require-core-service $s>>
|
||||||
<filter _>
|
<accept _>
|
||||||
]>
|
]>]>
|
||||||
|
|
||||||
<require-service <config-watcher "/etc/syndicate/core" {
|
<require-service <config-watcher "/etc/syndicate/core" {
|
||||||
config: $sys
|
config: $sys
|
||||||
|
|
|
@ -172,7 +172,7 @@ additional conditions on the receiver's use of its own capability, known as an
|
||||||
|
|
||||||
An attenuation is a chain of `Caveat`s.[^caveat-terminology-macaroon] A `Caveat` acts as a
|
An attenuation is a chain of `Caveat`s.[^caveat-terminology-macaroon] A `Caveat` acts as a
|
||||||
function that, given a Preserves value representing an assertion or message body, yields either
|
function that, given a Preserves value representing an assertion or message body, yields either
|
||||||
a possibly-rewritten value, or no value at all.[^zero-or-more] In the latter case, the value
|
a possibly-rewritten value, or no value at all.[^affine-caveats] In the latter case, the value
|
||||||
has been *rejected*. In the former case, the rewritten value is used as input to the next
|
has been *rejected*. In the former case, the rewritten value is used as input to the next
|
||||||
`Caveat` in the chain, or as the final assertion or message body for delivery to the entity
|
`Caveat` in the chain, or as the final assertion or message body for delivery to the entity
|
||||||
backing the capability.
|
backing the capability.
|
||||||
|
@ -183,17 +183,23 @@ leftward `Caveat` in the sequence. If no `Caveat`s are present, the capability i
|
||||||
and inputs are passed through to the backing capability unmodified.
|
and inputs are passed through to the backing capability unmodified.
|
||||||
|
|
||||||
```preserves-schema
|
```preserves-schema
|
||||||
Caveat = Rewrite / Alts .
|
Caveat = Rewrite / Alts / Reject / @unknown any .
|
||||||
|
Rewrite = <rewrite @pattern Pattern @template Template> .
|
||||||
Rewrite = <rewrite @pattern Pattern @template Template>.
|
Reject = <reject @pattern Pattern> .
|
||||||
Alts = <or @alternatives [Rewrite ...]>.
|
Alts = <or @alternatives [Rewrite ...]>.
|
||||||
```
|
```
|
||||||
|
|
||||||
A `Caveat` can be either a single `Rewrite` or a sequence of alternative possible rewrites,
|
A `Caveat` can be:
|
||||||
tried in left-to-right order until one of them accepts the input or there are none left to try.
|
|
||||||
(A single `Rewrite` *R* is equivalent to `<or [`*R*`]>`.)
|
|
||||||
|
|
||||||
A `Rewrite` applies its `Pattern` to the input to the `Caveat`. If it matches, the bindings
|
- a single `Rewrite`[^single-rewrite-meaning], or a sequence of alternative possible rewrites
|
||||||
|
`Alts`, to be tried in left-to-right order until one of them accepts the input or there are
|
||||||
|
none left to try;
|
||||||
|
|
||||||
|
- a `Reject`, which passes all inputs unmodified except those matching the contained pattern; or
|
||||||
|
|
||||||
|
- an `unknown` caveat, which rejects all inputs.
|
||||||
|
|
||||||
|
Each `Rewrite` applies its `Pattern` to its input. If the `Pattern` matches, the bindings
|
||||||
captured by the pattern are gathered together and used in instantiation of the `Rewrite`'s
|
captured by the pattern are gathered together and used in instantiation of the `Rewrite`'s
|
||||||
`Template`, yielding the output from the `Caveat`. If the pattern does not match, the `Rewrite`
|
`Template`, yielding the output from the `Caveat`. If the pattern does not match, the `Rewrite`
|
||||||
has rejected the input, and other `alternatives` are tried until none remain, at which point
|
has rejected the input, and other `alternatives` are tried until none remain, at which point
|
||||||
|
@ -518,6 +524,10 @@ The value is recursively traversed. As the relay comes across each embedded `Wir
|
||||||
- In each case, the `WireSymbol` associated with the OID has its reference count incremented
|
- In each case, the `WireSymbol` associated with the OID has its reference count incremented
|
||||||
(if an `Assert` is being processed).
|
(if an `Assert` is being processed).
|
||||||
|
|
||||||
|
In addition, for `Assert` events, the `WireSymbol` (necessarily in the export membrane)
|
||||||
|
associated with the OID to which the incoming `Assert` is targetted has its reference count
|
||||||
|
incremented.
|
||||||
|
|
||||||
### <span id="outbound-rewriting"></span>Rewriting embedded references for transmission
|
### <span id="outbound-rewriting"></span>Rewriting embedded references for transmission
|
||||||
|
|
||||||
When transmitting a `Value` *v* in an `Assert` or `Message` event, embedded references in *v*
|
When transmitting a `Value` *v* in an `Assert` or `Message` event, embedded references in *v*
|
||||||
|
@ -686,13 +696,13 @@ care should be taken in the case of non-cryptographic transport protocols like p
|
||||||
|
|
||||||
To use such a transport for this protocol, establish a connection and begin transmitting
|
To use such a transport for this protocol, establish a connection and begin transmitting
|
||||||
[`Packet`s](#packet-definitions) encoded as Preserves values using either the Preserves [text
|
[`Packet`s](#packet-definitions) encoded as Preserves values using either the Preserves [text
|
||||||
syntax](https://preserves.dev/preserves.html#textual-syntax) or the Preserves
|
syntax](https://preserves.dev/preserves-text.html) or the Preserves
|
||||||
[binary syntax](https://preserves.dev/preserves.html#compact-binary-syntax).
|
[machine-oriented syntax](https://preserves.dev/preserves-binary.html).
|
||||||
The session starts with the first packet and ends with transport disconnection. If either peer
|
The session starts with the first packet and ends with transport disconnection. If either peer
|
||||||
in a connection detects a syntax error, it MUST disconnect the transport. A responding server
|
in a connection detects a syntax error, it MUST disconnect the transport. A responding server
|
||||||
MUST support the binary syntax, and MAY also support the text syntax. It can autodetect the
|
MUST support the binary syntax, and MAY also support the text syntax. It can autodetect the
|
||||||
syntax variant by following [the rules in the
|
syntax variant by following [the rules in the
|
||||||
specification](https://preserves.dev/preserves.html#appendix-autodetection-of-textual-or-binary-syntax):
|
specification](https://preserves.dev/preserves-binary.html#appendix-autodetection-of-textual-or-binary-syntax):
|
||||||
the first byte of a valid binary-syntax Preserves document is guaranteed not to be
|
the first byte of a valid binary-syntax Preserves document is guaranteed not to be
|
||||||
interpretable as the start of a valid UTF-8 sequence.
|
interpretable as the start of a valid UTF-8 sequence.
|
||||||
|
|
||||||
|
@ -771,8 +781,9 @@ version 1 .
|
||||||
|
|
||||||
Attenuation = [Caveat ...].
|
Attenuation = [Caveat ...].
|
||||||
|
|
||||||
Caveat = Rewrite / Alts .
|
Caveat = Rewrite / Alts / Reject / @unknown any .
|
||||||
Rewrite = <rewrite @pattern Pattern @template Template>.
|
Rewrite = <rewrite @pattern Pattern @template Template> .
|
||||||
|
Reject = <reject @pattern Pattern> .
|
||||||
Alts = <or @alternatives [Rewrite ...]>.
|
Alts = <or @alternatives [Rewrite ...]>.
|
||||||
|
|
||||||
Oid = int .
|
Oid = int .
|
||||||
|
@ -793,7 +804,7 @@ PCompound =
|
||||||
/ @dict <dict @entries { any: Pattern ...:... }> .
|
/ @dict <dict @entries { any: Pattern ...:... }> .
|
||||||
|
|
||||||
Template = TAttenuate / TRef / Lit / TCompound .
|
Template = TAttenuate / TRef / Lit / TCompound .
|
||||||
TAttenuate = <attenuate @template Template @attenuation Attenuation>.
|
TAttenuate = <attenuate @template Template @attenuation [Caveat ...]>.
|
||||||
TRef = <ref @binding int>.
|
TRef = <ref @binding int>.
|
||||||
TCompound =
|
TCompound =
|
||||||
/ @rec <rec @label any @fields [Template ...]>
|
/ @rec <rec @label any @fields [Template ...]>
|
||||||
|
@ -806,8 +817,8 @@ TCompound =
|
||||||
### Attenuation
|
### Attenuation
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def attenuate(attenuation, value):
|
def attenuate(caveats, value):
|
||||||
for caveat in reversed(attenuation):
|
for caveat in reversed(caveats):
|
||||||
value = applyCaveat(caveat, value)
|
value = applyCaveat(caveat, value)
|
||||||
if value is None:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
@ -822,6 +833,13 @@ def applyCaveat(caveat, value):
|
||||||
return None
|
return None
|
||||||
if caveat is 'Rewrite' variant:
|
if caveat is 'Rewrite' variant:
|
||||||
return tryRewrite(caveat, value)
|
return tryRewrite(caveat, value)
|
||||||
|
if caveat is 'Reject' variant:
|
||||||
|
if applyPattern(caveat.pattern, value) is None:
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
if caveat is 'unknown' variant:
|
||||||
|
return None
|
||||||
|
|
||||||
def tryRewrite(rewrite, value):
|
def tryRewrite(rewrite, value):
|
||||||
bindings = applyPattern(rewrite.pattern, value)
|
bindings = applyPattern(rewrite.pattern, value)
|
||||||
|
@ -947,10 +965,6 @@ def instantiate(template, bindings):
|
||||||
mechanism. Future versions of this specification may opt to include some of this
|
mechanism. Future versions of this specification may opt to include some of this
|
||||||
generality.
|
generality.
|
||||||
|
|
||||||
[^zero-or-more]: TODO: It might be better to have a `Caveat` yield *zero or more* values? That
|
[^affine-caveats]: `Caveat`s are thus *affine*.
|
||||||
way they can act as filters. I've sometimes wanted the multiple-value case, though I've so
|
|
||||||
far been able to work around its lack. TODO: Perhaps it would also make sense to have a
|
[^single-rewrite-meaning]: A single `Rewrite` *R* is equivalent to `<or [`*R*`]>`.
|
||||||
`Caveat` map an *event* to zero or more *events*, rather than to values? Tricky corners
|
|
||||||
there include ensuring that carried authority isn't misused; macaroons are a very elegant
|
|
||||||
solution to this problem, of course, so maybe the macaroon design idea could be adapted to
|
|
||||||
this. For now, `Value`→`Option<Value>` is probably OK.
|
|
||||||
|
|
|
@ -25,16 +25,28 @@ an overview of `SturdyRef`s, see the [guide to the built-in gatekeeper
|
||||||
entity](../../operation/builtin/gatekeeper.md#sturdyrefs).
|
entity](../../operation/builtin/gatekeeper.md#sturdyrefs).
|
||||||
|
|
||||||
```
|
```
|
||||||
SturdyRef = <ref @oid any @caveatChain [Attenuation ...] @sig bytes>.
|
SturdyRef = <ref @oid any @caveatChain [Caveat ...] @sig bytes>.
|
||||||
```
|
```
|
||||||
|
|
||||||
For detail of the interpretation of `Attenuation`s, `Caveat`s, `Pattern`s, and `Template`s, see
|
The `sig` in a `SturdyRef` is an iterated keyed-HMAC construction, starting from an HMAC of the
|
||||||
the [Syndicate protocol specification](../../protocol.md#capabilities-on-the-wire).
|
ref's *secret key* and its `oid`, following [macaroons][]. The specific function chosen is
|
||||||
|
[HMAC](https://www.rfc-editor.org/rfc/rfc2104) using
|
||||||
|
[BLAKE2s-256](https://www.rfc-editor.org/rfc/rfc7693), truncating the output to the first 16
|
||||||
|
bytes. Let
|
||||||
|
|
||||||
|
- *f(k,d)* be `HMAC-BLAKE2s-256`*(k,d)*[0..16),
|
||||||
|
- *e(v)* yield the canonical machine-oriented serialization of some preserves value *v*, and
|
||||||
|
- *k* be the original secret key for the ref.
|
||||||
|
|
||||||
|
In a valid `SturdyRef`, then, the `sig` will be *f(...f(...f(f(k,e(*`oid`*)),...),e(*`Caveat`*)),...)*.
|
||||||
|
|
||||||
|
For detail of the interpretation of `Caveat`s, `Pattern`s, and `Template`s, see the [Syndicate
|
||||||
|
protocol specification](../../protocol.md#capabilities-on-the-wire).
|
||||||
|
|
||||||
```
|
```
|
||||||
Attenuation = [Caveat ...].
|
Caveat = Rewrite / Alts / Reject / @unknown any .
|
||||||
Caveat = Rewrite / Alts .
|
Rewrite = <rewrite @pattern Pattern @template Template> .
|
||||||
Rewrite = <rewrite @pattern Pattern @template Template>.
|
Reject = <reject @pattern Pattern> .
|
||||||
Alts = <or @alternatives [Rewrite ...]>.
|
Alts = <or @alternatives [Rewrite ...]>.
|
||||||
|
|
||||||
Lit = <lit @value any>.
|
Lit = <lit @value any>.
|
||||||
|
@ -52,10 +64,12 @@ PCompound =
|
||||||
/ @dict <dict @entries { any: Pattern ...:... }> .
|
/ @dict <dict @entries { any: Pattern ...:... }> .
|
||||||
|
|
||||||
Template = TAttenuate / TRef / Lit / TCompound .
|
Template = TAttenuate / TRef / Lit / TCompound .
|
||||||
TAttenuate = <attenuate @template Template @attenuation Attenuation>.
|
TAttenuate = <attenuate @template Template @attenuation [Caveat ...]>.
|
||||||
TRef = <ref @binding int>.
|
TRef = <ref @binding int>.
|
||||||
TCompound =
|
TCompound =
|
||||||
/ @rec <rec @label any @fields [Template ...]>
|
/ @rec <rec @label any @fields [Template ...]>
|
||||||
/ @arr <arr @items [Template ...]>
|
/ @arr <arr @items [Template ...]>
|
||||||
/ @dict <dict @entries { any: Template ...:... }> .
|
/ @dict <dict @entries { any: Template ...:... }> .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[Macaroons]: ../../glossary.md#macaroon
|
||||||
|
|
Loading…
Reference in New Issue