Skip to content

Commit

Permalink
Sketching Accept-Signature.
Browse files Browse the repository at this point in the history
This patch adds initial support for setting the `Accept-Signature`
header as we've been discussing in #21. It does not yet handle the
CORS-preflight side of things, which I'll handle in a subsequent
monkey-patch.
  • Loading branch information
mikewest committed Dec 17, 2024
1 parent cc0a47c commit fa700ab
Showing 1 changed file with 107 additions and 3 deletions.
110 changes: 107 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,13 @@ into the version of [[SRI#does-response-match-metadatalist]] altered by this
specification in order to enable signature-based checks that require information
from the request ([=request/integrity metadata=] on the one hand, request headers
and properties for signature components on the other) and the response (integrity
headers and the body):
headers and the body).

It would also require changes to [[Fetch#http-network-or-cache-fetch]] to support
setting the [:Accept-Signature:] header on outgoing requests based on their
[=request/integrity metadata=].

### Main Fetch ### {#monkey-patch-main-fetch}

[[Fetch#main-fetch]] step 22 will be updated as follows:

Expand Down Expand Up @@ -699,10 +705,109 @@ headers and the body):
</li>
</ol>

### Server-Initiated Integrity Checks ### {#server-initiated}

### HTTP-network-or-cache Fetch ### {#monkey-patch-http-network-or-cache-fetch}

[[Fetch#http-network-or-cache-fetch]] will be updated by injecting the following
step between the existing step 13 and 14:

<ol start=13 algorithm="monkey patching HTTP-network-or-cache fetch">
<li><p><a abstract-op lt="append the Fetch metadata headers for a request">Append the Fetch metadata headers for <var>httpRequest</var></a>. [[!FETCH-METADATA]]</p></li>

<li><ins>
<a lt="append the Accept-Signature header" abstract-op>Append the `Accept-Signature` header</a> for |httpRequest|.
</ins></li>

<li><p>If <var>httpRequest</var>'s <a for=request>initiator</a> is "<code>prefetch</code>", then
<a>set a structured field value</a> given (`<a http-header><code>Sec-Purpose</code></a>`,
the <a data-lt="structured field token">token</a> <code>prefetch</code>) in
<var>httpRequest</var>'s <a for=request>header list</a>.
</li>
</ol>

#### Append `Accept-Signature` #### {#append-accept-signature}

When a [=request=]'s [=request/integrity metadata=] contains signature-based assertions,
user agents will attach [:Accept-Signature:] headers to the request to inform servers
about the client's expectations. The header's value will match the grammar defined in
[[RFC9421]], and contain the expected public key(s) as <a>`keyid`</a> parameters.

<div class="example">
A request generated from the following HTML element:

```html
<script src="https://my.cdn/script.js"
crossorigin="anonymous"
integrity="ed25519-JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs="></script>
```

would contain the following header:

```http
Accept-Signature: sig0=("identity-digest";sf);keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";type="sri"
```

If multiple keys are acceptable (e.g. to support key rotation), the [:Accept-Signature:]
header will contain multiple acceptable signatures. That is, the following HTML:

```html
<script src="https://my.cdn/script.js"
crossorigin="anonymous"
integrity="ed25519-JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=
ed25519-xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE="></script>
```

would produce the following header in its request:

```http
NOTE: '\' line wrapping per RFC 8792

Accept-Signature: sig0=("identity-digest";sf);keyid="JrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs=";type="sri" \
sig1=("identity-digest";sf);keyid="xDnP380zcL4rJ76rXYjeHlfMyPZEOqpJYjsjEppbuXE=";type="sri"
```

</div>

<div algorithm="append `accept-signature`">

To <dfn abstract-op>append the `Accept-Signature` header</dfn> for a [=request=]
(|request|):

1. If |request|'s [=request/header list=] [=header list/contains=] [:Accept-Signature:], return.

Note: Developers can set an [:Accept-Signature:] header for use by their
own application. In this case, the user agent will not set additional
[:Accept-Signature:] headers, and may perform a [=CORS-preflight request=].

2. If |request|'s [=request/integrity metadata=] is [=string/empty=], return.

3. Let |parsed| be the result of executing [$Parse metadata$] on |request|'s
[=request/integrity metadata=].

4. If |parsed|["`signatures`"] is [=set/empty=], return.

6. Let |counter| be 0.

7. For each |signature| in |parsed|["`signatures`"]:

1. Let |value| be the [=string/concatenation=] of « \`<code>sig</code>\`, counter, \`<code>=("identity-digest";sf);keyid="</code>\`, |signature|["`val`"], \`<code>";type="sri"</code>\` ».
2. [=header list/Append=] (\`<code>Accept-Signature</code>\`, |value|) to |request|'s [=request/header list=].


</div>

ISSUE(21): To support this change, we also need to clean up the processing in
[=CORS-safelisted request-header=] to support this header, as discussed in



Server-Initiated Integrity Checks {#server-initiated}
---------------------------------

<div algorithm="server-initiated integrity checks">

Note: This set of algorithms could live either in [[Fetch]] or [[SRI]].

To <dfn abstract-op>perform server-initiated integrity checks</dfn> given a
[=byte sequence=] (|bytes|), a [=/request=] (|request|), and a [=/response=]
(|response|), execute the following steps. They return "`passed`" or
Expand Down Expand Up @@ -756,7 +861,6 @@ negotiation).
</div>



### `Signature` and `Signature-Input` Enforcement ### {#signature-enforcement}

<div algorithm="signature validation">
Expand Down

0 comments on commit fa700ab

Please sign in to comment.