-
Notifications
You must be signed in to change notification settings - Fork 24
/
spec.bs
716 lines (608 loc) · 28.8 KB
/
spec.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
<pre class="metadata">
Title: Device Bound Session Credentials
Shortname: dbsc
Level: 1
Indent: 2
Status: CG-DRAFT
Group: WICG
URL: https://wicg.github.io/dbsc/
Editor: Kristian Monsen 76841, Google, [email protected]
Editor: Daniel Rubery, Google, [email protected]
Abstract: The Device Bound Sessions Credentials (DBSC) aims to prevent hijacking via cookie theft by building a protocol and infrastructure that allows a user agent to assert possession of a securely-stored private key. DBSC is a Web API and a protocol between user agents and servers to achieve this binding.
Repository: https://github.com/WICG/dbsc/
Markup Shorthands: css no, markdown yes
Mailing List:
</pre>
<pre class="link-defaults">
spec:dom; type:interface; for:/; text:Document
spec:dom; type:dfn; for:/; text:element
spec:url; type:dfn; for:/; text:url
spec:fetch; type:dfn; for:Response; text:response
spec:fetch; type:dfn; for:Request; text:request
spec:html; type:element; text:script
spec:html; type:element; text:link
spec:fetch; type:dfn; text:name
spec:fetch; type:dfn; text:value
spec:infra; type:dfn; text:list
spec:permissions; type:dfn; text:feature
</pre>
<pre class="anchors">
spec: RFC8941;urlPrefix:https://datatracker.ietf.org/doc/html/rfc8941#;type:dfn
text: sf-dictionary; url: dictionary
text: sf-inner-list; url: inner-list
text: sf-item; url: item
text: sf-list; url: list
text: sf-string; url: string
text: sf-token; url: token
url:text-parse;text:parsing structured fields
</pre>
# Introduction # {#intro}
<em>This section is not normative.</em><br/>
<em>Note this is a very early drafting for writing collaboration only</em>
The web is built on a stateless protocol. To provide required functionality, Web
applications store data locally on a user's computer. This is used for logged in
user sessions that can last for a long time.
In general user agents do not have a secure way of storing data supporting these
activities across commonly used operating systems, and actions authenticated by
this data may have serious consequences, for example transferring money from a
bank account.
This document defines a new API, Device Bound Sessions Credentials (DBSC), that
enables the server to verify that a session cannot be exported from a device by
using commonly available TPMs, or similar APIs, that are designed for this
purpose.
The goal is to provide users with a safe and secure experience, while offering
the use cases users are already used to. At the same time we want to ensure that
the users privacy is respected with no new privacy identifiers being leaked by
this protocol.
## Examples ## {#examples}
Device Bound Session Credentials are designed to make users more secure in
different situations. Some of the use cases of DBSC are:
### Signed in session ### {#example-signin}
<div class="example" id="signin-example">
A user logs in to his social account. To protect the user's private data the
site protects his logged in session wwith a DBSC session. If the user tries to
log in with the same cookie file on a different device, the site can detect and
refuse this as an unauthorized user.
</div>
### Device integrity ### {#example-device-integrity}
<div class="example" id="device-integrity-example">
A commercial site has different ways of detecting unauthorized login attempts.
A DBSC session on device could be used to see which users have logged on to
this device before.
</div>
### Device reputation ### {#example-device-reputation}
<div class="example" id="device-reputation-example">
A payment company hosted at site `payment.example.com` could create a session
bound to when users visit commercial site `shopping.example.com`. It could
track the reliability of the device over time to decide how likely a
transaction is legitimate.
</div>
# Security Considerations # {#privacy}
The goal of DBSC is to reduce session theft by offering an alternative to
long-lived cookie bearer tokens, that allows session authentication that is
bound to the user's device. This makes the internet safer for users in that it
is less likely their identity is abused, as malware is forced to act locally and
thus becomes easier to detect and mitigate. At the same time the goal is to
disrupt the cookie theft ecosystem and force it to adapt to new protections long
term.
As long as the session is valid a host can know with cryptographic certainty
that it is on the same device as the session was originally bound to if the
session was registered to a secure device.
## Non-goals ## {#non-goals}
DBSC will not prevent temporary access to the browser session while the attacker
is resident on the user's device. The private key should be stored as safely as
modern operating systems allow, preventing exfiltration of the session private
key, but the signing capability will still be available for any program running
as the user on the user's device.
DBSC will also not prevent an attack if the attacker is replacing or injecting
into the user agent at the time of session registration as the attacker can bind
the session either to keys that are not TPM bound, or to a TPM that the attacker
controls permanently.
DBSC is not designed to give hosts any sort of guarantee about the device a
session is registered to, or the state of this device.
# Privacy Considerations # {#privacy-considerations}
The goal of the DBSC protocol is to introduce no additional surface for user
tracking: implementing this API (for a browser) or enabling it (for a website)
should not entail any significant user privacy tradeoffs.
Some of the consideration taken to ensure this:
- Lifetime of a session/key material: This should provide no additional client
data storage (i.e., a pseudo-cookie). As such, we require that browsers MUST
clear sessions and keys when clearing other site data (like cookies).
- Implementing this API should not meaningfully increase the entropy of
heuristic device fingerprinting signals. Unless allowed by user policy, DBSC
should not leak any stable TPM-based device identifier.
- As this API MAY allow background "pings" for performance, this must not enable
long-term tracking of a user when they have navigated away from the connected
site.
- Each session has a separate new key created, and it should not be possible to
detect that different sessions are from the same device unless the user allows
this by policy.
## Cookies considerations ## {#privacy-cookies}
Cross-site/cross-origin data leakage: It should be impossible for a site to use
this API to circumvent the same origin policy, 3P cookie policies, etc.
Due to the complexity of current and changing cookie behavior and the
interaction between DBSC and cookies the current solution is that each user
agent should use the same policy for DBSC as it uses for cookies. If the DBSC
cookie credential would not apply to a network request, based on user settings,
applied policies or user agent implementation details, neither would any of the
DBSC heuristics. This ensures no new privacy behavior due to implementing DBSC.
## Timing side channel leak ## {#privacy-side-channel-leak}
If third party cookies are enabled it is possible for an attacker to leak
whether or not a user is authenticated by measuring how long the request takes
as the refresh is quite slow, partially due to the latency of TPM operations.
This only applies if the site to be leaked about has enabled third party
cookies, if an attacker does have third-party cookie access there are often
attackes and leaks.
This is not a very reliable leak as the user needs to have a session on the site
that is currently out of date and would need to be refreshed. The leak cannot be
trivially repeated as the first request will renew the session that would likely
not expire again for some time.
It is important websites think about this privacy leak before adopting DBSC,
even more so if the plan is to use sessions with third party cookies.
# Alternatives considered # {#alternatives}
## WebAuthn and silent mediation ## {#alternatives-webauthn}
# Framework # {#framework}
This document uses ABNF grammar to specify syntax, as defined in [[!RFC5234]]
and updated in [[!RFC7405]], along with the `#rule` extension defined in
<a href="https://tools.ietf.org/html/rfc7230#section-7">Section 7</a> of
[[!RFC9112]], and the `quoted-string` rule defined in
<a href="https://tools.ietf.org/html/rfc7230#section-3.2.6">Section 3.2.6</a>
of the same document.
This document depends on the Infra Standard for a number of foundational
concepts used in its algorithms and prose [[!INFRA]].
## Sessions by registrable domain ## {#framework-sessions-origin}
A <dfn>sessions by registrable domain</dfn> is an [=ordered map=] from
[=host/registrable domain=] to [=session by id=].
## Sessions by id ## {#framework-sessions-id}
A <dfn>session by id</dfn> is an [=ordered map=] from
[=device bound session/session identifier=] to [=device bound session=]s for a
given [=host/registrable domain=].
## Device bound session ## {#framework-session}
A <dfn>device bound session</dfn> is a [=struct=] with the following
[=struct/items=]:
<dl dfn-for="device bound session">
: <dfn>session identifier</dfn>
:: a [=string=] that is a unique identifier of a session on an
[=host/registrable domain=]
: <dfn>refresh url</dfn>
:: a [=string=] that is representing the [=url=] to be used to refresh the
session
: <dfn>defer requests</dfn>
:: an OPTIONAL [=boolean=] defining if the browser should defer other
requests while refreshing a session
: <dfn>cached challenge</dfn>
:: a [=string=] that is to be used as the next challenge for this session
: [=session scope=]
:: a [=struct=] defining which [=url=]'s' are in scope for this session
: [=session credential=]
:: a [=list=] of [=session credential=] used by the session
</dl>
## Session scope ## {#framework-scope}
The <dfn>session scope</dfn> is a [=struct=] with the following
[=struct/items=]:
<dl dfn-for="session scope">
: <dfn>include site</dfn>
:: a [=boolean=] that indicates if all subdomains of are included by
default.
: [=scope specification=]
:: a [=list=] of [=scope specification=] used by the session
</dl>
## Scope specification ## {#framework-scope-specification}
The <dfn>scope specification</dfn> is a [=struct=] with the following
[=struct/items=]:
<dl dfn-for="scope specification">
: <dfn>type</dfn>
:: a [=string=] to be either "include" or "exclude", defining if the item
defined in this struct should be added or removed from the scope
: <dfn>path</dfn>
:: a [=string=] that defines the path part of this scope item
</dl>
## Session credential ## {#framework-session-credential}
The <dfn>session credential</dfn> is a [=struct=] with the following
[=struct/items=]:
<dl dfn-for="session credential">
: <dfn>name</dfn>
:: a [=string=] that defines the name of the credential cookie
: <dfn>attributes</dfn>
:: a [=string=] that defines the other attributes of the credential cookie
</dl>
# Algorithms # {#algorithms}
## Identify session ## {#algo-identify-session}
<div class="algorithm" data-algorithm="identify-session">
This algorithm describes how to
<dfn export dfn-for="algorithms">identify a session</dfn> out of all the
sessions that exist on a user agent. The
[=device bound session/session identifier=] is unique within a
[=host/registrable domain=].
Given a [=url=] and [=device bound session/session identifier=]
(|session identifier|), this algorithm returns a [=device bound session=] or
null if no such session exists.
1. Let |site| be the [=host/registrable domain=] of the [=url=]
1. Let |domain sessions| be [=sessions by registrable domain=][|site|] as a
[=/session by id=]
1. Return |domain sessions|[|session identifier|]
</div>
## Process challenge ## {#algo-process-challenge}
<div class="algorithm" data-algorithm="process-challenge">
This algorithm describes how to
<dfn export dfn-for="algorithms">process a challenge</dfn> received in an HTTP
header.
Given a [=response=] (|response|) and a [=sessions by registrable domain=], this
algorithm updates the [=device bound session/cached challenge=] for a
[=device bound session=], or immediately resends the [=DBSC proof=] signed with
the new challenge if the [=response/status=] is 401.
1. Let |header name| be "<code>Sec-Session-Challenge</code>".
1. Let |challenge list| be the result of executing <a>get a structured
field value</a> given |header name| and "list" from |response|’s
[=response/header list=].
1. [=list/For each=] |challenge entry| of |challenge list|:
1. Parse |challenge entry| according to <a>parsing structured fields</a>.
1. If the type of |challenge entry| is not an <a>sf-string</a>,
[=iteration/continue=].
1. Let |challenge| be the parsed item.
1. Let |session id| be null.
1. If params["id"] exists and is a <a>sf-string</a>, Set |session id| to
params["id"].
1. If [=response/status=] is 401, resend this request as is with updated
|challenge| in [=DBSC proof=] and [=iteration/continue=].
1. If |session id| is null, [=iteration/continue=].
1. Identify session as described in [=identify a session=] given
|response| and |session id| and store as |session object|.
1. If |session object| is null, [=iteration/continue=].
1. Store |challenge| in |session object| to be used next time a
[=DBSC proof=] is to be sent from this [=device bound session=].
</div>
## Session refresh ## {#algo-session-refresh}
To <dfn export id="refresh-session">Refreshing an existing session</dfn>
## Send request ## {#algo-session-request}
## Create session ## {#algo-create-session}
To <dfn export id="create-session">Create a new session</dfn>, start with
parsing the registration structured header defined in
[:Sec-Session-Registration:]:
<div class="algorithm" data-algorithm="process-registration">
1. Let |header name| be "<code>Sec-Session-Registration</code>".
1. Let |registration list| be the result of executing <a>get a structured
field value</a> given |header name| and "list" from |response|’s
[=response/header list=].
1. [=list/For each=] |registration entry|, |params| → |registration list|:
1. Parse |registration entry| according to <a>parsing structured fields</a>.
1. If |registration entry| is not an <a>sf-inner-list</a>,
[=iteration/continue=].
1. Let |algorithm list| be an empty [=list=].
1. [=list/For each=] |algorithm| → |registration entry|
1. If |algorithm| is not a <a>sf-token</a>, [=iteration/continue=].
1. If |algorithm| represents a crypto algorithm supported in
[:Sec-Session-Registration:], and is supported on this client, add
|algorithm| to |algorithm list|
1. If |algorithm list| is empty, [=iteration/continue=].
1. If |params|["path"] does not exist, or is not of type <a>sf-string</a>,
[=iteration/continue=].
1. Let |path| be |params|["path"].
1. Let |challenge| be null, and Let |authorization| be null.
1. If |params|["challenge"] exists and is of type <a>sf-string</a>
Set |challenge| to |params|["challenge"].
1. If |params|["authorization"] exists and is a string Set |authorization|
to |params|["authorization"].
1. Call [[#algo-session-request]] with |algorithm list|, |path|,
|challenge| and |authorization| parameters.
</div>
## Closing session ## {#algo-close-session}
To <dfn export id="close-session">close a session</dfn>
## Fetch Integration ## {#algo-fetch-integration}
To <dfn export id="fetch-integration">fetch Integration</dfn>
# DBSC Formats # {#format}
## \``Sec-Session-Registration`\` HTTP header field ## {#header-sec-session-registration}
The \`<dfn export http-header id="sec-session-registration-header">
<code>Sec-Session-Registration</code></dfn>\` header field can be used in a
[=response=] by the server to start a new [=/device bound session=] on the
client.
[:Sec-Session-Registration:] is a List Structured Header [[RFC8941]]. Its ABNF
is:
<pre class="abnf">Sec-Session-Registration = <a>sf-list</a></pre>
Each item in the list must be an inner list, and each item in the inner list
MUST be a <a>sf-token</a> representing a supported algorithm (ES256, RS256).
Only these two values are currently supported.
The following parameters are defined:
- A parameter whose key is "path", and whose value is a String (Section 3.3.3 of
[[RFC8941]]), conveying the path to the registration endpoint. This may be
relative to the current [=url=], or a full [=url=]. Entries without this
parameter will be ignored in [=Create a new session=].
- A parameter whose key is "challenge", and whose value is a String (Section
3.3.3 of [[RFC8941]]), conveying the challenge to be used in the session
registration.
- A parameter whose key is "authorization", and whose value is a String (Section
3.3.3 of [[RFC8941]]), this parameter will be copied into the registration
JWT.
<div class="example" id="sec-session-registration-example">
Some examples of [:Sec-Session-Registration:] from
https://example.com/login.html:
```html
HTTP/1.1 200 OK
Sec-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
```
```html
HTTP/1.1 200 OK
Sec-Session-Registration: (ES256 RS256);path="reg";challenge="cv"
```
```html
HTTP/1.1 200 OK
Sec-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a"
Sec-Session-Registration: (RS256);path="reg2";challenge="cv2";authorization="b"
```
```html
HTTP/1.1 200 OK
Sec-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a", (RS256);path="reg2";challenge="cv2";authorization="b"
```
</div>
## \``Sec-Session-Challenge`\` HTTP Header Field ## {#header-sec-session-challenge}
The \`<dfn export http-header id="sec-session-challenge-header">
<code>Sec-Session-Challenge</code></dfn>\` header field can be used in a
[=response=] by the server to send a challenge to the client that it expects to
be used in future Sec-Session-Response headers inside the [=DBSC proof=], or to
request a newly signed [=DBSC proof=] right away if the [=response/status=] is
401.
[:Sec-Session-Challenge:] is a structured header. Its value must be a string.
Its ABNF is: <pre class="abnf">SecSessionChallenge = <a>sf-string</a></pre>
The semantics of the item are defined in
[[#challenge-structured-header-serialization]].
The processing steps are defined in [[#algo-process-challenge]].
### Sec-Session-Challenge structured header serialization ### {#challenge-structured-header-serialization}
The [:Sec-Session-Challenge:] is represented as a Structured Field.[[!RFC8941]]
In this representation, a challenge is represented by a string.
Challenges MAY have a Parameter named `"id"`, whose value MUST be a String
representing a [=device bound session/session identifier=]. Any other
parameters SHOULD be ignored.
Note: The server might need to use this header to request the [=DBSC proof=] to
be signed with a new challenge before a session id has been assigned. In this
case the session ID is optional.
<div class="example" id="sec-session-challenge-example">
Some examples of [:Sec-Session-Challenge:] from
https://example.com/login.html:
```html
HTTP/1.1 401 OK
Sec-Session-Challenge: "new challenge"
```
```html
HTTP/1.1 401 OK
Sec-Session-Challenge: "new challenge";id="my session"
```
```html
HTTP/1.1 200 OK
Sec-Session-Challenge: "new challenge";id="my session"
```
```html
HTTP/1.1 200 OK
Sec-Session-Challenge: "new challenge";id="my session 1"
Sec-Session-Challenge: "another challenge";id="my session 2"
```
```html
HTTP/1.1 200 OK
Sec-Session-Challenge: "c1";id="session 1", "c2";id="session 2"
```
</div>
## `Sec-Session-Response` HTTP Header Field ## {#header-sec-session-response}
The \`<dfn export http-header id="sec-session-response-header">
<code>Sec-Session-Response</code></dfn>\` header field can be used in the
[=request=] by the user agent to send a [=DBSC proof=] to the server to prove
that the client is still in possesion of the private key of the session key.
\`<a http-header><code>Sec-Session-Response</code></a>\` is a structured
header. Its value must be a string. It's ABNF is:
<pre class="abnf">SecSessionChallenge = <a>sf-string</a></pre>
This string MUST only contain the [=DBSC proof=] JWT. Any parameters SHOULD be
ignored.
<div class="example" id="sec-session-response-example">
```html
POST example.com/refresh
Sec-Session-Response: "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRic2Mrand0In0.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL3JlZyIsImp0aSI6ImN2IiwiaWF0IjoiMTcyNTU3OTA1NSIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZfR0Iydm9RMHFyb01oNk9sREZDRlNfU0pyaVFpMVBUdnZCT2hHWjNiSEkiLCJ5IjoiSWVnT0pVTHlFN1N4SF9DZDFLQ0VSN2xXQnZHRkhRLWgweHlqelVqRUlXRSJ9LCJhdXRob3JpemF0aW9uIjoiYWMifQ.6Fb_vVBDmfNghQiBmIGe8o7tBfYPbPCywhQruP0vIhxgmcJmuNTaMHeVn_M8ZnOm1_bzIitbZqCWEn-1Qzmtyw"
```
</div>
## `Sec-Session-Id` HTTP Header Field ## {#header-sec-session-id}
The \`<dfn export http-header id="sec-session-id-header">
<code>Sec-Session-Id</code></dfn>\` header field can be used in the
[=request=] by the user agent to request the current session is refreshed,
with the current session identifier as a string argument.
\`<a http-header><code>Sec-Session-Id</code></a>\` is a structured header.
Its value must be a string. It's ABNF is:
<pre class="abnf">SecSessionChallenge = <a>sf-string</a></pre>
This string MUST only contain the session identifier. Any paramters SHOULD be
ignored.
<div class="example" id="sec-session-id-example">
```html
POST example.com/refresh
Sec-Session-Id: "session-id"
```
</div>
## DBSC Session Instruction Format ## {#format-session-instructions}
The server sends <dfn>session instructions</dfn> during session registration and
optionally during session refresh. If the response contains session instructions
it MUST be in JSON format.
At the root of the JSON object the following keys can exist:
<dl dfn-for="session instructions">
: <dfn>session identifier</dfn>
:: a [=string=] representing a [=device bound session/session identifier=].
If this [=session instructions=] is sent during a refresh request this MUST be
the [=device bound session/session identifier=] for the current session. If
not these instructions SHOULD be ignored.
If this [=session instructions=] is sent during a registration it MUST either
be a unique iditifier for this [=host/registrable domain=], or it will
overwrite the current [=device bound session=] with this identifier for the
current [=host/registrable domain=].
This key MUST be present.
: <dfn>refresh_url</dfn>
:: a [=string=] representing the [=url=] used for future refresh requests.
This can be a full url, or relative to the current [=request=].
This key is OPTIONAL, if not present the registration url will be used for
future refresh requests.
: <dfn>continue</dfn>
:: a [=boolean=] representing if the current session should continue, or be
closed on the client. This key is OPTIONAL, and if not present the default
value will be true.
: <dfn>defer_requests</dfn>
:: a [=boolean=] describing the wanted session behavior during a session
refresh. If this value is true all requests related to this session will be
deferred while the session is refreshed. If instead the value is false every
request will instead be sent as normal, but with a [:Sec-Session-Response:]
header containing the [=DBSC proof=].
This key is OPTIONAL, and if not present a value of true is default.
</dl>
<div class="example" id="sec-session-instruction-example">
```json
{
"session_identifier": "session_id",
"refresh_url": "/RefreshEndpoint",
"scope": {
// Origin-scoped by default (i.e. https://example.com)
// Specifies to include https://*.example.com except excluded subdomains.
// This can only be true if the origin's host is the root eTLD+1.
"origin": "example.com",
"include_site": true,
"continue": false,
"defer_requests": true, // optional and true by default
"scope_specification" : [
{ "type": "include", "domain": "trusted.example.com", "path": "/only_trusted_path" },
{ "type": "exclude", "domain": "untrusted.example.com", "path": "/" },
{ "type": "exclude", "domain": "*.example.com", "path": "/static" }
]
},
"credentials": [{
"type": "cookie",
// This specifies the exact cookie that this config applies to. Attributes
// match the cookie attributes in RFC 6265bis and are parsed similarly to
// a normal Set-Cookie line, using the same default values.
// These SHOULD be equivalent to the Set-Cookie line accompanying this
// response.
"name": "auth_cookie",
"attributes": "Domain=example.com; Path=/; Secure; SameSite=None"
// Attributes Max-Age, Expires and HttpOnly are ignored
}]
}
```
</div>
## DBSC Proof JWT Syntax ## {#format-jwt}
A <dfn>DBSC proof</dfn> proof is a JWT that is signed (using JSON Web Signature
(JWS)), with a private key chosen by the client. The header of a [=DBSC proof=]
MUST contain at least the following parameters:
<dl dfn-for="DBSC proof">
: <dfn>typ</dfn>
:: a [=string=] MUST be "dbsc+jwt"
: <dfn>alg</dfn>
:: a [=string=] defining the algorithm used to sign this JWT. It MUST be
either "RS256" or "ES256" from [IANA.JOSE.ALGS].
</dl>
The payload of [=DBSC proof=] MUST contain at least the following claims:
<dl dfn-for="DBSC proof">
: <dfn>aud</dfn>
:: a [=string=], MUST be the [=url=] this JWT was originally sent to.
Example: "https://example.com/refresh.html"
: <dfn>jti</dfn>
:: a [=string=], a copy of the challenge value sent in the registration
header.
: <dfn>iat</dfn>
:: a [=string=], this claim identifies the time at which the JWT was
issued. This claim can be used to determine the age of the JWT. Its
value MUST be a number containing a NumericDate value.
: <dfn>jwk</dfn>
:: a [=string=] defining a JWK as specified in [rfc7517].
</dl>
In addition the following claims MUST be present if present in
[:Sec-Session-Registration:]:
<dl dfn-for="DBSC proof">
: <dfn>authorization</dfn>
:: a [=string=], direct copy of the string from
[:Sec-Session-Registration:], if set there. Note that this string is
OPTIONAL to include in the header, but if it is present it is
MANDATORY for clients to add the claim in the [=DBSC proof=].
</dl>
<div class="example" id="dbsc-proof-example">
An example [=DBSC proof=] sent to https://example.com/reg:
```json
// Header
{
"alg": "ES256",
"typ": "dbsc+jwt"
}
// Payload
{
"aud": "https://example.com/reg",
"jti": "cv",
"iat": "1725579055",
"jwk": {
"kty": "EC",
"crv": "P-256",
"x": "6_GB2voQ0qroMh6OlDFCFS_SJriQi1PTvvBOhGZ3bHI",
"y": "IegOJULyE7SxH_Cd1KCER7lWBvGFHQ-h0xyjzUjEIWE"
},
"authorization": "ac"
}
```
Based on this response header from the server:
```html
HTTP/1.1 200 OK
Sec-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
```
recieved on a response from ```http://example.com/page.html```
</div>
# Changes to other specifications # {#changes-to-other-specifications}
## Changes to the Fetch specification ## {#changes-to-fetch}
--> Check if session should be refreshed before sending request
- Alternatively add proof with Sec-Session-Response
## Changes to the HTML specification ## {#changes-to-html}
--> Clear Site Data: Clear the session if this is received
# IANA Considerations # {#iana-considerations}
The permanent message header field registry should be updated with the following
registrations: [[!RFC3864]]
## Sec-Session-Challenge ## {#iana-ses-session-challenge}
<dl>
<dt>Header field name</dt>
<dd>Sec-Session-Challenge</dd>
<dt>Applicable protocol</dt>
<dd>http</dd>
<dt>Status</dt>
<dd>draft</dd>
<dt>Author/Change controller</dt>
<dd>W3C</dd>
<dt>Specification document</dt>
<dd>This specification (See [[#header-sec-session-challenge]])</dd>
</dl>
## Sec-Session-Id ## {#iana-ses-session-id}
<dl>
<dt>Header field name</dt>
<dd>Sec-Session-Id</dd>
<dt>Applicable protocol</dt>
<dd>http</dd>
<dt>Status</dt>
<dd>draft</dd>
<dt>Author/Change controller</dt>
<dd>W3C</dd>
<dt>Specification document</dt>
<dd>This specification (See [[#header-sec-session-id]])</dd>
</dl>
## Sec-Session-Registration ## {#iana-sec-session-registration}
<dl>
<dt>Header field name</dt>
<dd>Sec-Session-Registration</dd>
<dt>Applicable protocol</dt>
<dd>http</dd>
<dt>Status</dt>
<dd>draft</dd>
<dt>Author/Change controller</dt>
<dd>W3C</dd>
<dt>Specification document</dt>
<dd>This specification (See [[#header-sec-session-registration]])</dd>
</dl>
## Sec-Session-Response ## {#iana-ses-session-response}
<dl>
<dt>Header field name</dt>
<dd>Sec-Session-Response</dd>
<dt>Applicable protocol</dt>
<dd>http</dd>
<dt>Status</dt>
<dd>draft</dd>
<dt>Author/Change controller</dt>
<dd>W3C</dd>
<dt>Specification document</dt>
<dd>This specification (See [[#header-sec-session-response]])</dd>
</dl>
# Changelog # {#changelog}
This is an early draft of the spec.
# Acknowledgements # {#acknowledgements}