기기 바인딩 세션 자격 증명

W3C 최초 공개 작업 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2025/WD-dbsc-1-20250821/
최신 게시 버전:
https://www.w3.org/TR/dbsc/
편집자 초안:
https://w3c.github.io/webappsec-dbsc/
이력:
https://www.w3.org/standards/history/dbsc-1/
피드백:
public-webappsec@w3.org 제목 줄은 “[dbsc] … 메시지 주제 …”로 합니다(아카이브)
GitHub
편집자:
(Google)
(Google)
(Google)

초록

기기 바인딩 세션 자격 증명(DBSC)은 사용자 에이전트가 안전하게 저장된 개인 키의 소유를 증명할 수 있도록 하는 프로토콜과 인프라를 구축하여 쿠키 탈취를 통한 하이재킹을 방지하는 것을 목표로 한다. DBSC는 이 바인딩을 달성하기 위한 사용자 에이전트와 서버 간의 Web API 및 프로토콜이다.

이 문서의 상태

이 절은 이 문서가 게시된 시점의 상태를 설명한다. 현재 W3C 간행물과 이 기술 보고서의 최신 개정판 목록은 W3C 표준 및 초안 색인에서 확인할 수 있다.

이 문서는 Web Application Security Working Group권고안 트랙을 사용하여 최초 공개 작업 초안으로 게시했다. 이 문서는 W3C 권고안이 되는 것을 목표로 한다.

(보관된) 공개 메일링 리스트 public-webappsec@w3.org (지침 참조)가 이 명세에 대한 논의에 선호된다. 이메일을 보낼 때에는 제목에 “dbsc”라는 텍스트를 넣고, 가능하면 다음과 같이 작성한다: “[dbsc] …의견 요약…

이 문서는 최초 공개 작업 초안이다.

최초 공개 작업 초안으로 게시되었다고 해서 W3C 및 그 회원들의 승인을 의미하지는 않는다. 이는 초안 문서이며, 언제든지 다른 문서로 업데이트, 대체 또는 폐기될 수 있다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않다.

이 문서는 Web Application Security Working Group이 작성했다.

이 문서는 W3C Patent Policy에 따라 운영되는 그룹이 작성했다. W3C는 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지한다. 해당 페이지에는 특허를 공개하기 위한 지침도 포함되어 있다. 개인이 자신이 알고 있는 특허가 Essential Claim(s)을 포함한다고 실제로 알고 있는 경우, 그 개인은 W3C Patent Policy 제6절에 따라 해당 정보를 공개해야 한다.

이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받는다.

1. 소개

이 절은 규범적이지 않다.
이는 작성 협업만을 위한 매우 초기 초안임에 유의한다

웹은 상태를 갖지 않는 프로토콜을 기반으로 구축되어 있다. 특정 기능을 위해 상태를 유지하려면, 웹 애플리케이션은 사용자 기기에 데이터를 로컬로 저장한다. 이 저장소는 오랫동안 지속될 수 있으며, 로그인한 사용자 세션의 자격 증명과 같은 보안에 민감한 데이터에 사용된다.

일반적으로 사용자 에이전트는 일반적인 운영 체제에서 사용자 에이전트 자체와 동일한 권한을 가진 소프트웨어에 대해 안전하게 이러한 종류의 데이터를 저장할 방법이 없다. 동시에 이러한 데이터로 인증된 동작은 은행 계좌에서 돈을 이체하는 것과 같은 심각한 결과를 초래할 수 있다. 이 모델에 대한 일반적이고 확장 가능한 위협은 이러한 자격 증명을 유출하고 다른 곳에서 악용을 수행하여 탐지를 회피하는 악성코드이다.

이 문서는 서버가 세션 자격 증명이 기기에서 내보내지지 않았음을 검증할 수 있게 하는 새로운 API인 Device Bound Sessions Credentials(DBSC)를 정의한다. 이러한 자격 증명은 개인 키이므로, 사용자 에이전트는 TPM 또는 유사한 API와 같은 기능을 사용하여, 동일 권한의 악성코드로부터도 유출되지 않도록 보호할 수 있다.

목표는 사용자에게 안전하고 보안성 있는 경험을 제공하면서, 사용자가 이미 익숙한 사용 사례를 제공하는 것이다. 동시에 이 프로토콜로 인해 새로운 개인정보 식별자가 누출되지 않도록 하여 사용자 개인정보가 존중되도록 하고자 한다. 이 API는 기존 서버 측 인증 스택과 쉽게 통합되도록 특별히 주의를 기울이며, 웹 소프트웨어 스택의 큰 부분을 다시 작성하지 않아도 이러한 보호로 나아갈 수 있는 점진적 경로를 제공한다.

2. 보안 고려 사항

DBSC의 목표는 오래 지속되는 쿠키 bearer 토큰에 대한 대안을 제공하여 세션 탈취를 줄이고, 유출로부터 더 잘 보호될 수 있는 개인 키에 기반하여 세션 인증이 이루어지도록 하는 것이다. 이는 악성코드가 로컬에서 동작하도록 강제되어 더 쉽게 탐지하고 완화할 수 있으므로, 사용자의 신원이 악용될 가능성을 낮춰 인터넷을 사용자에게 더 안전하게 만든다.

사용자 에이전트 구현은 서로 다른 플랫폼에 존재하는 악성코드 위협의 유형과 존재하는 보호 메커니즘을 고려하여 이러한 개인 키를 유출로부터 보호하는 최선의 방법을 선택할 책임이 있다. 여기에는 TPM 또는 보안 요소 같은 보안 하드웨어, 안전한 키 생성 및 관리를 위한 OS 제공 API, 또는 로컬에서 실행되는 악성코드에 대해 합리적인 보호를 제공하는 프로세스 격리 메커니즘이 포함되지만 이에 한정되지는 않는다.

세션이 유효하고 손상되지 않은 기기에 등록되어 있는 한, 호스트는 암호학적으로 확실하게 세션 키가 다른 기기로의 악의적 유출로부터 보호된다는 것을 알 수 있다.

2.1. 비목표

DBSC는 공격자가 사용자 기기에 상주하는 동안 브라우저 세션에 일시적으로 접근하는 것을 방지하지 않는다. 개인 키는 현대 운영 체제가 허용하는 만큼 안전하게 저장되어 세션 개인 키의 유출을 방지해야 하지만, 서명 기능은 사용자 기기에서 사용자로 실행되는 모든 프로그램에 여전히 사용 가능할 가능성이 높다.

또한 세션 등록 시점에 공격자가 사용자 에이전트를 교체하거나 주입하고 있다면, 공격자가 세션을 TPM에 바인딩되지 않은 키 또는 공격자가 영구적으로 제어하는 TPM에 바인딩할 수 있으므로 DBSC는 공격을 방지하지 못한다.

DBSC는 세션이 등록된 특정 기기나 그 기기의 상태에 대해 호스트에게 어떠한 보장도 제공하도록 설계되지 않았다.

3. 개인정보 보호 고려 사항

DBSC 프로토콜의 개인정보 보호 목표는 사용자 추적을 위한 추가 표면을 도입하지 않는 것이다. 이 API를 구현하는 것(브라우저의 경우) 또는 활성화하는 것(웹사이트의 경우)은 유의미한 사용자 개인정보 보호 절충을 수반해서는 안 된다.

이를 보장하기 위해 고려한 사항은 다음과 같다:

3.1. 쿠키 고려 사항

사이트가 이 API를 사용하여 동일 출처 정책, 3P 쿠키 정책 등을 우회하는 것은 불가능해야 한다. 현재 및 변화하는 쿠키 동작의 복잡성과 DBSC와 쿠키 사이의 긴밀한 통합으로 인해, 현재 해결책은 각 사용자 에이전트가 쿠키에 사용하는 것과 동일한 정책을 DBSC에도 사용하는 것이다. 사용자 설정, 적용된 정책 또는 사용자 에이전트 구현 세부 사항에 따라 DBSC 쿠키 자격 증명이 네트워크 요청에 적용되지 않는다면, 추가 DBSC 동작도 적용되지 않는다. 이는 DBSC 구현으로 인해 새로운 개인정보 보호 동작이 생기지 않도록 보장한다.

3.2. 타이밍 사이드 채널 누출

서드파티 쿠키가 활성화되어 있으면, 공격자는 요청에 걸리는 시간을 측정하여 사용자가 인증되었는지 여부를 판단할 수 있다. 이는 특히 새로 고침이 키 보호를 위한 느린 하위 기능(예: TPM)에 의존하는 경우 상당히 느릴 수 있기 때문이다.

이는 세션 구성의 allowed_refresh_initiators 키로 완화되며, DBSC 새로 고침을 트리거할 수 있는 사이트를 엄격하게 제한하는 데 사용할 수 있다. 기존 해결책 (예: X-Frame-Options)으로 이를 대체할 수 없는 이유는 기존 해결책이 요청이 완료된 뒤에만 적용되는 반면, DBSC는 요청이 시작되기 전에 새로 고침 여부를 선택해야 하기 때문이다.

3.3. 연합 세션

많은 사이트는 브라우저 관여 없이 연합 로그인 메커니즘을 사용하며, 흔히 링크 장식(예: OIDC)에 의존한다. DBSC의 쉬운 도입성이라는 목표를 달성하기 위해, 이러한 사이트가 인증 흐름을 완전히 다시 작성하지 않고도 쿠키 탈취로부터 자신을 보호할 수 있기를 원한다. 이상적으로는 Relying Parties(RP)가 Identity Provider(IdP)와 독립적으로 DBSC 세션을 수립할 수 있어야 한다. 안타깝게도 대부분의 IdP는 사용자가 이미 로그인되어 있으면 비밀번호를 요구하지 않는다. 사용자 상호작용이 필요하지 않다면, 악성코드는 사용자 기기에 대한 일시적 접근을 사용해 로그인 흐름을 모방하고 악성코드가 생성하고 유출할 수 있는 새 개인 키로 DBSC 세션을 수립할 수 있다. 이는 DBSC의 보안 목표를 위반한다.

DBSC는 로그인이나 신원에 본질적으로 묶여 있지 않으므로, Identity Provider는 가장 정확한 용어가 아니다. 대신 Session Provider(SP)라는 용어를 사용하지만, 대상 사용 사례에서는 SP와 IdP가 같은 당사자일 것으로 예상한다.

RP의 세션을 보호하려면 RP와 SP 세션을 어떤 방식으로든 연결해야 한다. 이를 수행하는 가장 간단한 방법은 SP와 RP가 동일한 세션 키 쌍을 사용하는 것이다. SP의 세션은 악성코드가 기기를 손상시키기 전에 수립되었다고 가정하므로, 개인 키가 안전하게 저장되어 있다고 신뢰한다. 그러나 사이트 간 키 공유는 복잡한 개인정보 보호 속성을 갖는다. 고엔트로피 식별자 공유의 개인정보 위험을 완화하기 위해, RP가 이미 SP 세션의 공개 키와 세션 식별자를 알고 있어야 한다고 요구한다. RP는 SP URL, 세션 식별자, base64로 인코딩된 JWK thumbprint ([RFC4648][RFC7638] 참조)를 `Secure-Session-Registration` 헤더에 포함한다. 키가 올바르면 사용자 에이전트는 SP와 동일한 키로 RP에 세션을 생성한다.

또한 RP와 SP가 이미 정보를 공유할 수 없는 경우(예: 핑거프린팅 또는 링크 장식에 대한 보호가 있는 경우), 악의적인 RP와 SP가 협력하여 사용자를 식별하려는 잠재적 위험도 있다. RP는 일치하는 키를 찾을 때까지 많은 공개 키를 추측해 사용자에 대한 고유 식별자를 얻을 수 있다. 이는 협력하는 RP와 SP가 교차 사이트 신원 연결을 위한 의도된 메커니즘 밖에서 사용자의 신원을 사이트 간에 공유할 수 있게 한다. 이를 방지하기 위해 사용자 에이전트는 등록 시도에 대해 상당한 backoff 또는 quota를 포함해야 한다 (이는 TPM에 대한 서비스 거부를 피하기 위해서도 권장된다). DBSC의 보안 속성은 동일한 키 쌍을 가진 두 사용자를 얻기 어렵다는 암호학적 가정에 의존하므로, 사용자가 SP에 특정 DBSC 공개 키를 가지고 있는지 질의하는 것은 1비트보다 훨씬 적은 엔트로피라는 점에 유의한다.

사용자를 성공적으로 드러내는 가치를 추가로 제한하기 위해, SP가 .well-known을 통해 opt-in하도록 요구한다. 브라우저는 해당 목록의 RP 출처 수를 제한해야 한다. 또한 RP가 여러 SP를 사용하고 그런 방식으로 신원을 집계하는 것을 방지해야 한다. 이를 위해 RP도 .well-known에서 자신의 SP를 선언하도록 요구한다. 이 둘을 함께 사용하면, 사용자가 웹을 탐색할 때 많은 사이트 그룹이 협력하여 한 명의 고가치 사용자를 드러내는 일을 방지할 수 있다.

example.com의 소유자가 example.co.uk도 운영한다고 가정하자. 로그인은 항상 example.com에서 발생하며 링크 장식을 통해 example.co.uk로 전파된다. 두 사이트를 모두 DBSC 세션으로 보호하려면 example.com은 기존 `Secure-Session-Registration` 헤더를 계속 사용해야 한다:
Secure-Session-Registration: (ES256);path="/register";challenge="challenge"

DBSC 세션을 example.com.uk로 확장할 때, 사이트는 `Secure-Session-Registration` 헤더에 새 매개변수를 추가해야 한다:

Secure-Session-Registration: (ES256);path="/register";challenge="challenge";provider_key="abc";provider_id="example.com id";provider_url="https://example.com"

example.comexample.co.uk에 적절한 .well-known 항목이 있다고 가정하면, 이는 example.co.ukexample.com의 세션과 동일한 키를 사용하여 새 DBSC 세션을 등록하게 한다. 이를 통해 로그인 시 사용자가 example.com에서 다시 인증하지 않아도 DBSC가 example.co.uk를 보호할 수 있다.

4. 검토한 대안

4.1. WebAuthn과 무음 중재

WebAuthn은 사이트에 특정 키 관리 기능을 제공하므로, DBSC와 같은 목표를 충족하도록 확장할 수 있을지도 모른다. 그러나 WebAuthn은 상호작용형 사용자 로그인에 중점을 두기 때문에, DBSC와 같은 기능의 목표와 상반되는 API 속성이 여러 가지 발생하므로 이 접근 방식을 취하지 않는다. 예를 들어 WebAuthn 자격 증명은 특정 세션에 묶여 있지 않다. 이는 오래 지속되도록 의도되어 있으며 사이트 데이터와 함께 지워지지 않는다. 이는 세션 키에 필요한 개인정보 보호 속성과 잘 맞지 않는다. 마찬가지로 WebAuthn 자격 증명은 명시적인 사용자 의도로 사용되도록 설계되어 있다. DBSC가 제공하는 기능을 WebAuthn이 포괄하도록 확장하려면 WebAuthn이 무음으로 사용할 수 있는 다른 종류의 키를 수립해야 한다. 이는 WebAuthn과 DBSC 모두에 추가 복잡성을 도입한다. 대신, WebAuthn은 안전한 로그인을 제공하는 것을 목표로 하고 DBSC는 로그인 후 사용자를 보호하는 보완적 기능이라는 입장을 취한다.

5. 서버 고려 사항

DBSC를 사용하려면 사이트 소유자는 두 개의 새 엔드포인트, 즉 등록 엔드포인트와 새로 고침 엔드포인트를 수립해야 한다.

등록 엔드포인트는 브라우저가 `Secure-Session-Registration` 헤더를 받은 뒤 비동기적으로 접촉된다. 이 엔드포인트는 다음을 수행해야 한다:

새로 고침 엔드포인트는 훨씬 더 민감하다. 이 엔드포인트는 만료된 바인딩 쿠키가 포함된 요청이 만들어질 때마다 접촉되며, 그 응답은 원래 요청을 차단한다. 응답하지 못하거나 바인딩 쿠키를 복원하지 못하면 브라우저 에이전트가 서비스 거부 방지 메커니즘을 시작하거나 세션을 종료할 수도 있다. 둘 다 향후 요청이 바인딩 쿠키 없이 이루어지는 결과를 낳을 수 있다. 이 엔드포인트의 예상 동작은 다음과 같다:

브라우저는 DBSC를 도입한 사이트의 지연 시간 비용을 최소화하려고 세션을 사전에 새로 고칠 수 있다. 사이트는 바인딩 쿠키가 만료되었을 때에만 새로 고침이 발생한다고 가정해서는 안 된다.

새로 고침 엔드포인트는 교차 사이트 fetch가 허용될 경우 타이밍 사이드 채널을 통해 로그인 상태를 직접 누출할 가능성이 높다. 서버는 유효한 `Sec-Secure-Session-Id` 헤더를 확인하여 들어오는 요청이 사용자 에이전트에 의해 시작된 것이며 교차 사이트 요청이 아님을 보장할 수 있다. 또한 이 엔드포인트에 좁은 CORS 정책을 설정하고, 교차 사이트 출처가 자격 증명이 있는 요청을 하도록 허용하지 않는 것이 권장된다. DBSC의 CORS 통합은 지연된 요청이 자격 증명을 포함할 때 암시적으로 자격 증명을 포함하도록 설계되어 이를 가능하게 한다. 유사한 이유로, 새로 고침 엔드포인트가 X-Frame-Options 또는 Cross-Origin-Resource-Policy 헤더를 통해 임베드되는 것을 거부하는 것도 권장된다.

example.com에 두 엔드포인트가 있다고 가정하자:

사이트는 DBSC가 /authenticated에 대한 교차 사이트 요청을 보호하기를 원하며, 이 하나의 엔드포인트에 대한 타이밍 사이드 채널의 위험이 미미하다고 생각한다. 사용자 에이전트가 트리거한 새로 고침 요청에 대해 자격 증명을 암시적으로 허용하지 않는다면, /refresh는 모든 요청 출처에 대해 Access-Control-Allow-Credentials를 반환해야 한다. 그러면 공격자는 /refresh를 직접 fetch하여 로그인 상태를 누출할 수 있다.

DBSC의 /refresh 호출은 자격 증명을 암시적으로 허용하므로, /refresh 엔드포인트는 Access-Control-Allow-Credentials를 절대 반환하지 않도록 거부할 수 있다. 이는 DBSC 새로 고침의 맥락에서 자격 증명이 있는 요청을 여전히 받는다. 다른 사이트는 자격 증명과 함께 엔드포인트를 직접 fetch할 수 없으므로, 로그인 상태의 쉬운 교차 사이트 누출을 방지한다.

DBSC와 함께 연합 로그인을 사용하는 사이트(§ 3.3 연합 세션 참조)는 연합 키를 가진 세션만 허용되도록 해야 한다. 연합 세션의 보안은 Session Provider(SP) 로그인 시점에 기기가 손상되지 않았다는 점에 의존한다. 악성코드는 기기에 대한 일시적 접근을 사용해 Relying Party(RP)에 새 키로 세션을 등록할 수 있기 때문이다. 따라서 RP는 SP로부터 받은 적절한 공개 키로 등록된 세션만 허용해야 한다.

6. 사용자 에이전트 고려 사항

DBSC는 브라우저가 쿠키 새로 고침을 예약할 수 있는 많은 유연성을 제공한다. 이는 DBSC의 지연 시간을 완화하고 TPM 및 서버의 부하를 낮출 수 있다. 사용자 에이전트가 다음과 같은 방식으로 쿠키 새로 고침을 예약할 것을 권장한다:

7. 프레임워크

이 문서는 [RFC5234]에 정의되고 [RFC7405]에서 업데이트된 ABNF 문법을 사용하여 구문을 지정하며, Section 7 of [RFC9112]에 정의된 #rule 확장 및 같은 문서의 Section 3.2.6에 정의된 quoted-string 규칙도 함께 사용한다.

이 문서는 알고리즘과 설명에서 사용하는 여러 기반 개념에 대해 Infra Standard에 의존한다 [INFRA].

7.1. 세션 저장소

사용자 에이전트는 세션 저장소를 유지한다. 이는 ordered map이며, registrable domain에서 id별 세션 맵으로 매핑한다. 세션은 사용자 에이전트 재시작 후에도 지속되어야 한다.

7.2. id별 세션

id별 세션 맵은 특정 registrable domain에 대해 세션 식별자에서 기기 바인딩 세션으로 매핑하는 ordered map이다.

7.3. 기기 바인딩 세션

기기 바인딩 세션은 다음 items를 갖는 struct이다:
세션 식별자

registrable domain의 세션에 대한 고유 식별자인 string

새로 고침 URL

세션을 새로 고치는 데 사용할 URL을 나타내는 string

캐시된 challenge

이 세션의 다음 challenge로 사용할 string 또는 null

세션 범위

이 세션의 범위에 포함되는 URLs를 정의하는 세션 범위

세션 자격 증명

세션에서 사용되는 세션 자격 증명list. 이는 JSON 세션 자격 증명에서 파생된다.

만료 타임스탬프

이 세션이 제거되어야 하는 moment

세션 키 쌍

세션에서 사용하는 키 쌍. 개인 키는 안전한 방식으로 저장되어야 한다 (§ 2 보안 고려 사항 참조).

허용된 새로 고침 개시자

어떤 호스트가 DBSC 새로 고침을 시작할 수 있는지 설명하는 stringslist. 자세한 내용은 § 8.3 요청이 새로 고침을 허용하는지 식별을 참조한다.

7.4. 세션 범위

세션 범위는 다음 items를 갖는 struct이다:
origin

이 세션이 등록된 origin

include site

세션이 전체 사이트에 적용되는지 또는 origin에만 적용되는지 나타내는 boolean

범위 명세

세션에서 사용하는 범위 명세list

7.5. 범위 명세

범위 명세는 다음 items를 갖는 struct이다:
type

"include" 또는 "exclude" 중 하나인 string. 이 struct에 정의된 항목이 범위에 추가되는지 제거되는지를 정의한다.

host

이 범위 명세가 적용되기 위해 일치해야 하는 도메인 또는 도메인 패턴을 정의하는 string

path

이 범위 명세의 경로 부분을 정의하는 string

7.6. 세션 자격 증명

세션 자격 증명은 다음 items를 갖는 struct이다:
name

자격 증명 쿠키의 이름을 정의하는 string

attributes

자격 증명 쿠키의 다른 속성을 정의하는 string. 사용자 에이전트는 쿠키에 대해 제공하는 것과 동일한 기본값을 여기에도 제공해야 한다.

7.7. 등록 가능 origin 레이블

domain등록 가능 origin 레이블domainregistrable domain의 첫 번째 domain label이거나, registrable domain이 null이면 null이다. 예를 들어, co.ukde가 모두 public suffixes라면, example.co.ukwww.example.de등록 가능 origin 레이블은 모두 example이다.

8. 알고리즘

8.1. 세션 식별

이 알고리즘은 사용자 에이전트에 존재하는 모든 세션 중에서 세션을 식별하는 방법을 설명한다. 세션 식별자registrable domain 내에서 고유하다.

URL (url)과 세션 식별자 (session identifier)가 주어지면, 이 알고리즘은 기기 바인딩 세션을 반환하거나, 그러한 세션이 없으면 null을 반환한다.

  1. domainurlhostregistrable domain으로 둔다.

  2. 사용자 에이전트의 세션 저장소domaincontain 하지 않으면 null을 반환한다.

  3. domain sessions을 사용자 에이전트의 세션 저장소[domain]로 두고, 이를 id별 세션 맵으로 간주한다.

  4. domain sessions[session identifier]를 null을 기본값으로 하여 with default 반환한다.

8.2. URL이 세션 범위에 있는지 식별

이 알고리즘은 기기 바인딩 세션의 범위에 URL이 있는지 결정하는 방법을 설명한다. URL (URL)과 기기 바인딩 세션 (session)이 주어지면, URL이 범위에 있으면 "include"를 반환하고, 그렇지 않으면 "exclude"를 반환한다.
  1. scopesession세션 범위로 둔다.

  2. scopeinclude site가 true이면, URLoriginscopeoriginsame site가 아니면 "exclude"를 반환한다.

  3. scopeinclude site가 false이면, URLoriginscopeoriginsame origin이 아니면 "exclude"를 반환한다.

  4. URLsession새로 고침 URL과 일치하면 "exclude"를 반환한다.

  5. scope범위 명세의 각 scope specification에 대해 For each:

    1. host patternscope specificationhost로, path patternscope specificationpath로 둔다.

    2. URLhosthost pattern에 대해 § 8.4 호스트가 패턴과 일치하는지 식별을 실행한 결과가 false이면, continue한다.

    3. 다음 중 하나라도 성립하면 scope specificationtype을 반환한다:

      1. URLpathpath pattern과 정확히 같다.

      2. path pattern이 '/'로 끝나고 URLpathpath pattern으로 시작한다.

      3. URLpathpath pattern 다음에 '/'가 오는 문자열로 시작한다.

  6. "include"를 반환한다.

8.3. 요청이 새로 고침을 허용하는지 식별

이 알고리즘은 기기 바인딩 세션에 대해 요청이 새로 고침을 트리거할 수 있는지 결정하는 방법을 설명한다. request (request)와 기기 바인딩 세션 (session)이 주어지면, request가 새로 고침을 트리거할 수 있으면 "allowed"를 반환하고 그렇지 않으면 "disallowed"를 반환한다.
  1. session세션 범위include site가 true이고, requestoriginsession세션 범위 originsame site이면 "allowed"를 반환한다.

  2. session세션 범위include site가 false이고, requestoriginsession세션 범위 originsame origin이면 "allowed"를 반환한다.

  3. session허용된 새로 고침 개시자의 각 initiator pattern에 대해 For each:

    1. requestoriginhostinitiator pattern에 대해 § 8.4 호스트가 패턴과 일치하는지 식별을 실행한 결과가 true이면 "allowed"를 반환한다.

  4. "disallowed"를 반환한다.

8.4. 호스트가 패턴과 일치하는지 식별

이 알고리즘은 호스트가 패턴과 일치하는지 결정하는 방법을 설명한다. 입력으로 host (host)와 string (pattern)을 받는다. patternhost를 포함하면 true를 반환한다.
  1. pattern이 '*'와 같으면 true를 반환한다.

  2. host string을 직렬화된 host로 둔다.

  3. pattern이 '*'로 시작하고 hostdomain이면:

    1. pattern이 '*.'로 시작하지 않으면 false를 반환한다.

    2. host stringpattern의 첫 글자를 제외한 나머지로 끝나면 true를 반환한다.

  4. host stringpattern과 같으면 true를 반환한다.

패턴 일치의 몇 가지 예:
  • example.com*와 일치한다

  • example.comexample.com과 일치한다

  • example.com*.example.com과 일치하지 않는다

  • subdomain.example.com*.example.com과 일치한다

8.5. 새로 고침이 필요한 세션 식별

request (request)가 주어지면, 이 알고리즘은 새로 고침이 필요한 세션 식별 방법을 설명한다. 그러한 세션이 존재하면 request가 진행되는 것을 차단해야 한다.
  1. domainrequesturlhostregistrable domain으로 둔다.

  2. 사용자 에이전트의 세션 저장소domaincontain 하지 않으면 null을 반환한다.

  3. domain sessions을 사용자 에이전트의 세션 저장소[domain]로 두고, 이를 id별 세션 맵으로 간주한다.

  4. domain sessions의 각 session에 대해 For each:

    1. session만료 타임스탬프가 현재보다 이전이면, domain sessions에서 session을 제거하고 continue한다.

    2. idsession세션 식별자로 둔다.

    3. tuple (domain, id)이 request지연된 기기 바인딩 세션 ids에 있으면, continue한다.

    4. requestURLsession에 대해 § 8.2 URL이 세션 범위에 있는지 식별의 단계를 실행한다. 결과가 "include"가 아니면 continue한다.

    5. requestsession에 대해 § 8.3 요청이 새로 고침을 허용하는지 식별의 단계를 실행한다. 결과가 "allowed"가 아니면 continue한다.

    6. requestsession세션 자격 증명에 대해 § 8.6 세션 자격 증명이 누락되었는지 식별의 단계를 실행한다. 결과가 false이면 continue한다.

    7. (domain, id)를 request지연된 기기 바인딩 세션 ids에 추가한다.

    8. session만료 타임스탬프를 미래 타임스탬프로 설정한다. 만료 타임스탬프의 정확한 선택은 사용자 에이전트에 맡긴다. 최대 쿠키 수명에 맞추는 것이 권장된다.

    9. session을 반환한다.

  5. null을 반환한다.

8.6. 세션 자격 증명이 누락되었는지 식별

이 알고리즘은 요청에 세션 자격 증명이 누락되었는지 식별하는 방법을 설명한다. request (request)와 세션 자격 증명list (credentials)가 주어지면, credentials의 어떤 credential이라도 request에 누락되어 있는지를 나타내는 boolean을 반환한다.
  1. credentials의 각 credential에 대해 For each:

    1. credentialattributes를 가진 쿠키가 request에 첨부되지 않을 경우(section 5.4 of [COOKIES] 참조), continue한다.

    2. requestheader list가 다음 조건을 모두 만족하는 cookie를 포함하면 continue한다:

      1. cookie의 name이 credentialname과 일치한다.

      2. cookie의 다음 모든 속성이 credentialattributes에 있는 것과 일치한다: Domain, Path, Secure, HttpOnly, SameSite.

    3. true를 반환한다.

  2. false를 반환한다.

8.7. challenge 캐시

이 알고리즘은 HTTP 헤더에서 받은 challenge를 처리하는 방법을 설명한다.

response (response)가 주어지면, 이 알고리즘은 기기 바인딩 세션캐시된 challenge를 업데이트한다.

  1. header name을 "Secure-Session-Challenge"로 둔다.

  2. challenge listresponseheader list에서 header name과 "list"를 사용해 get a structured field value를 실행한 결과로 둔다.

  3. challenge list가 null이면 반환한다.

  4. challenge list의 각 (challenge, params)에 대해 For each:

    1. challenge의 type이 sf-string이 아니면, continue한다.

    2. session id를 null로 둔다.

    3. params["id"]가 존재하고 sf-string이면, session idparams["id"]로 설정한다.

    4. session id가 null이면 continue한다.

    5. sessionresponseURLsession id가 주어졌을 때 § 8.1 세션 식별을 실행한 결과로 둔다.

    6. session이 null이면 continue한다.

    7. session세션 자격 증명의 각 credential에 대해 For each:

      1. credentialattributes를 가진 쿠키를 response로 설정할 수 없으면(section 5.3 of [COOKIES] 참조), continue한다.

      2. 다음에 이 기기 바인딩 세션에서 DBSC proof를 보낼 때 사용할 수 있도록, challengesession캐시된 challenge로 저장한다.

      3. Break한다.

8.8. 요청 보내기

이 알고리즘은 기기 바인딩 세션 등록 또는 새로 고침을 위한 요청을 보내는 방법을 설명한다. 입력으로 request (originating request), key pair, URL (destination), 그리고 선택적 strings session id, challenge, authorization을 받는다.

사용자 에이전트는 바인딩 자격 증명이 누락될 때마다 이 단계를 수행하지만, 언제든지 수행할 수 있다. 바인딩 자격 증명이 만료되기 전에 사전에 요청을 보내면 DBSC의 지연 시간 비용을 최소화할 수 있다.

  1. 사용자 에이전트는 사용자나 사이트에 대한 서비스 거부를 방지하기 위해 이 요청을 건너뛸 수 있다. 예를 들어 이 세션이 과도한 TPM 작업을 요청하거나(사용자에게 해를 끼침), 새로 고침 엔드포인트가 최근 도달할 수 없었던 경우(사이트에 대한 서비스 거부 위험) 이러한 일이 발생할 수 있다. 사용자 에이전트가 이를 선택하면, 사이트에 이를 알리기 위해 originating request, 적절한 토큰(§ 9.5 `Secure-Session-Skipped` HTTP 헤더 필드의 옵션 참조), session id§ 8.12 디버그 헤더 추가의 단계를 수행해야 한다.

  2. terminate the session을 다음 단계가 있는 알고리즘으로 둔다:

    1. session id가 null이면 반환한다.

    2. destinationhostregistrable domain과 식별자 session id를 가진 세션이 있다면, 사용자 에이전트의 세션 저장소에서 제거한다.

  3. originating requestURLorigindestinationoriginsame site가 아니면 반환한다.

  4. signed challenge를 null로 둔다. challenge 또는 authorization이 non-null이면, DBSC proof를 생성하고, key pair로 서명한 뒤, 그 결과를 signed challenge에 저장한다.

  5. HTTP fetch에서 사용할 request를 생성한다.

  6. requestmethod를 "POST"로 설정한다.

  7. requestURLdestination으로 설정한다.

  8. requestredirect mode를 "follow"로 설정한다.

  9. signed challenge가 non-null이면, ("Secure-Session-Response", signed challenge) 헤더를 requestheader listappend한다.

  10. session id가 non-null이면, ("Sec-Secure-Session-Id", session id) 헤더를 requestheader listappend한다.

  11. authorization이 non-null이면, ("Authorization", authorization) 헤더를 requestheader listappend한다.

  12. requestinitiatororiginating requestinitiator로 설정한다.

  13. requestoriginoriginating requestorigin으로 설정한다.

  14. responserequest에 대해 HTTP fetch를 실행한 결과로 둔다.

  15. responsenetwork error이거나, responsestatus가 407 또는 429이면 반환한다.

  16. responsestatus가 300 이상 400 미만이면 반환한다.

  17. responsestatus가 403이면:

    1. session id가 null이면 반환한다.

    2. sessiondestinationsession id에 대해 § 8.1 세션 식별의 단계를 실행한 결과로 둔다.

    3. session이 null이면 반환한다.

    4. 그렇지 않으면, 원래 입력을 사용하되 challengesession캐시된 challenge로 대체하여 이 알고리즘을 다시 시작한다.

  18. responsestatus가 400 이상 500 미만이면, terminate the session하고 반환한다.

  19. responsestatus가 500 이상이면 반환한다. 사용자 에이전트는 새로 고침 엔드포인트의 일시적 장애로 인한 피해를 제한하기 위해, 이 세션의 후속 새로 고침 요청에 대해 backoff 메커니즘을 트리거하도록 선택할 수 있다.

  20. session id가 non-null이고 responsebody가 비어 있으면 반환한다.

  21. response, destination, session id, key pair에 대해 § 8.9 세션 생성을 호출한다.

8.9. 세션 생성

destination (URL)에 대한 등록 요청의 response (response)로 인해, session id (string 또는 null)와 key pair세션을 생성하려면, 다음 단계를 수행한다:
  1. terminate the session을 다음 단계가 있는 알고리즘으로 둔다:

    1. session id가 null이면 반환한다.

    2. destinationhostregistrable domain과 식별자 session id를 가진 세션이 있다면, 사용자 에이전트의 세션 저장소에서 제거한다.

  2. JSON sessionresponsebodyJSON 세션 지시로 파싱한 결과로 둔다. 파싱이 실패하면 terminate the session하고 반환한다. 여기에는 모든 필수 키가 존재하는지 검증하는 것도 포함된다.

  3. JSON sessioncontinue가 false이면, terminate the session하고 반환한다.

  4. session identifierJSON sessionsession_identifier로 둔다.

  5. JSON scopeJSON sessionscope로 둔다.

  6. originJSON scopeorigin이 있으면 그 값에서, 없으면 destination의 origin에서 구성한 origin으로 둔다.

  7. JSON sessionrefresh_url에 값이 없으면, refresh URLdestination으로 둔다.

  8. 그렇지 않으면, refresh URLdestinationJSON sessionrefresh_url 값으로 resolve한 결과로 둔다.

  9. 다음 검증을 수행한다. 하나라도 실패하면 terminate the session하고 반환한다.

    1. session id가 non-null이면, session identifier와 일치해야 한다.

    2. origin은 유효한 non-opaque origin이어야 한다.

    3. origindestinationoriginsame site이어야 한다.

    4. refresh URL은 HTTPS scheme을 가져야 하거나 localhost여야 한다.

    5. refresh URLorigindestinationoriginsame site이어야 한다.

    6. 모든 JSON 세션 자격 증명은 "Partitioned" 속성을 가져서는 안 된다.

  10. destination domaindestinationhostregistrable domain으로 둔다.

  11. JSON scopeinclude_site가 true이면, 다음 검증을 수행한다. 하나라도 실패하면 terminate the session하고 반환한다.

    1. originhostdestination domain과 같아야 한다.

    2. destination domaindestinationhost와 같으면, 이 단계 안의 나머지 모든 검증을 건너뛴다.

    3. session id가 non-null이면, 이 단계 안의 나머지 모든 검증을 건너뛴다.

    4. 그렇지 않으면, well known URLdestination의 사본으로 두되, hostdestination domain으로 바꾸고, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.

    5. well known responsewell known URL을 fetch한 결과로 둔다.

    6. well known responsestatus는 200이어야 한다.

    7. well known responsebody는 JSON으로 인코딩된 dictionary여야 한다.

    8. well known responsebody는 "registering_origins" 키를 포함해야 한다.

    9. "registering_origins" 키의 값은 destination의 origin을 포함해야 한다.

  12. session을 새 세션으로 둔다.

  13. session세션 식별자session identifier로 설정한다.

  14. session새로 고침 URLrefresh URL로 설정한다.

  15. session세션 범위originorigin이고, include siteJSON scopeinclude_site 값인 새 범위로 설정한다.

  16. JSON scopescope_specification에 있는 각 JSON scope rule에 대해 For each:

    1. scope rule을 새 범위 명세로 둔다.

    2. scope ruletypeJSON scope ruletype으로 설정한다.

    3. scope rulehostJSON scope ruledomain으로 설정한다.

    4. scope rulepathJSON scope rulepath로 설정한다.

    5. scope rulesession세션 범위범위 명세에 append한다.

  17. JSON sessioncredentials에 있는 각 JSON session credential에 대해 For each:

    1. session credential을 새 세션 자격 증명으로 둔다.

    2. JSON session credentialtype이 "cookie"가 아니면, terminate the session하고 반환한다.

    3. session credentialnameJSON session credentialname으로 설정한다.

    4. session credentialattributesJSON session credentialattributes로 설정한다.

    5. session credentialsession세션 자격 증명에 append한다.

  18. session세션 키 쌍key pair로 설정한다.

  19. session허용된 새로 고침 개시자JSON sessionallowed_refresh_initiators로 설정한다.

  20. session만료 타임스탬프를 미래 타임스탬프로 설정한다. 만료 타임스탬프의 정확한 선택은 사용자 에이전트에 맡긴다. 최대 쿠키 수명에 맞추는 것이 권장된다.

  21. session세션 자격 증명에 있는 각 credential에 대해 For each:

    1. credentialattributes를 가진 쿠키를 response로 설정할 수 없으면(section 5.3 of [COOKIES] 참조), continue한다.

    2. 기존 세션을 제거하기 위해 terminate the session을 호출한다.

    3. 사용자 에이전트의 세션 저장소[destination domain][session identifier]를 session으로 설정한다.

    4. Break한다.

8.10. 세션 등록 처리

request (request)에 대한 response (response)로 인해 세션 등록을 처리하려면, 다음 단계를 수행한다:
  1. header name을 "Secure-Session-Registration"로 둔다.

  2. registration listresponseheader list에서 header name과 "list"를 사용해 get a structured field value를 실행한 결과로 둔다.

  3. registration list가 null이면 반환한다.

  4. registration list의 각 (registration entry, params)에 대해 For each:

    1. registration entrysf-inner-list가 아니면, continue한다.

    2. params["path"]가 존재하지 않거나 sf-string type이 아니면, continue한다.

    3. pathparams["path"]로 둔다.

    4. challenge를 null로 두고, authorization을 null로 둔다.

    5. params["challenge"] 또는 params["authorization"] 중 하나가 존재하지만 sf-string type이 아니면, continue한다.

    6. params["challenge"]가 존재하면 challengeparams["challenge"]로 설정한다.

    7. params["authorization"]이 존재하면 authorizationparams["authorization"]으로 설정한다.

    8. endpointresponse의 URL을 기준으로 path를 resolve한 결과로 둔다.

    9. key pairregistration entry, params, endpoint에 대해 § 8.11 세션 키 쌍 생성을 실행한 결과로 둔다.

    10. key pair가 null이면 반환한다.

    11. request, key pair, endpoint, 세션 식별자 null, challenge, authorization으로 § 8.8 요청 보내기를 호출한다.

8.11. 세션 키 쌍 생성

이 알고리즘은 Relying Party와 Session Provider 사이의 키 공유를 포함하여 세션 키 쌍을 생성하는 방법을 설명한다. 입력으로 `Secure-Session-Registration` 헤더의 registration entryparams, 그리고 등록 엔드포인트의 URL (registration URL)을 받는다. 세션에서 사용할 키 쌍을 반환하거나, 가능한 키가 없으면 null을 반환한다.
  1. algorithm list를 빈 list로 둔다.

  2. registration entry의 각 algorithm에 대해 For each:

    1. algorithmsf-token이 아니면, continue한다.

    2. algorithm이 `Secure-Session-Registration` 에서 지원되는 crypto algorithm을 나타내며 이 클라이언트에서 지원되면, algorithmalgorithm list에 추가한다.

  3. algorithm list가 비어 있으면 null을 반환한다.

  4. params["provider_key"], params["provider_id"], 또는 params["provider_url"] 중 하나라도 존재하면:

    1. 세 키 중 하나라도 없으면 null을 반환한다.

    2. permission을 "device-bound-session-key-sharing"에 대해 request permission to use를 수행한 결과로 둔다.

    3. permission"denied"이면, null을 반환한다.

    4. provider URLparams["provider_url"]에서 구성한 URL로 둔다.

    5. provider originprovider URLorigin으로 둔다.

    6. provider origin이 opaque이면 null을 반환한다.

    7. provider domainprovider URLhostregistrable domain으로 둔다.

    8. provider identifierparams["provider_id"]로 둔다.

    9. provider session을 사용자 에이전트의 세션 저장소[provider domain][provider identifier]에 있는 세션으로 둔다.

    10. provider session이 null이면 null을 반환한다.

    11. provider session세션 범위 originprovider originsame origin이 아니면 null을 반환한다.

    12. provider session세션 키 쌍의 JWK thumbprint([RFC7638] 참조)가 base64로 인코딩되었을 때([RFC4648] 참조) params["provider_key"]와 일치하지 않으면 null을 반환한다.

    13. provider well known URLprovider URL의 사본으로 두되, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.

    14. provider well known responseprovider well known URL을 fetch한 결과로 둔다. 다음 중 하나라도 성립하면 null을 반환한다:

      1. provider well known responsestatus가 200이 아니다.

      2. provider well known responsebody가 JSON으로 인코딩된 dictionary가 아니다.

      3. provider well known responsebody가 "provider_origin" 키를 포함한다.

      4. provider well known responsebody가 "relying_origins" 키를 포함하지 않는다.

      5. "relying_origins" 키의 값이 registration URLorigin을 포함하지 않는다.

    15. 사용자 에이전트는 남용을 방지하기 위해 "relying_origins"의 등록 가능 origin 레이블 수에 상한을 두어야 한다.

    16. relying well known URLregistration URL의 사본으로 두되, path를 "/.well-known/device-bound-sessions"로 바꾼 것으로 둔다.

    17. relying well known responserelying well known URL을 fetch한 결과로 둔다. 다음 중 하나라도 성립하면 null을 반환한다:

      1. relying well known responsestatus가 200이 아니다.

      2. relying well known responsebody가 JSON으로 인코딩된 dictionary가 아니다.

      3. relying well known responsebody가 "relying_origins" 키를 포함한다.

      4. relying well known responsebody가 "provider_origin" 키를 포함하지 않는다.

      5. "provider_origin" 키의 값이 provider URLorigin이 아니다.

    18. provider session세션 키 쌍을 반환한다.

  5. algorithm list에 대해 생성된 새 키 쌍을 반환한다.

8.12. 디버그 헤더 추가

사이트가 사용자 에이전트가 세션을 적용하지 않기로 선택한 시점을 이해할 수 있도록, 사용자 에이전트는 request (request)에 sf-token (token) 및 string (session id)과 함께 디버그 헤더를 추가해야 한다.
  1. valuetoken 값을 가진 sf-token으로 둔다.

  2. valuesf-parameter "session_identifier"를 session id로 설정한다.

  3. skipped header valuerequestheader list에 대해, header name "Secure-Session-Skipped", type "list"로 get a structured field value의 단계를 실행한 결과로 둔다.

  4. skipped header value가 null이면, 이를 빈 sf-list로 설정한다.

  5. valueskipped header value에 append한다.

  6. requestheader list에 ("Secure-Session-Skipped", skipped header value)를 주어 set a structured field value의 단계를 실행한다.

9. DBSC 형식

9.1. `Secure-Session-Registration` HTTP 헤더 필드

Secure-Session-Registration 헤더 필드는 서버가 클라이언트에서 새 기기 바인딩 세션을 시작하기 위해 response에서 사용할 수 있다.

`Secure-Session-Registration` 은 List Structured Header [RFC9651]이다. 그 ABNF는 다음과 같다:

SecureSessionRegistration = sf-list

목록의 각 item은 inner list여야 하며, inner list의 각 item은 지원되는 알고리즘(ES256, RS256)을 나타내는 sf-token이어야 한다. 현재는 이 두 값만 지원된다.

다음 sf-parameter가 정의된다:

https://example.com/login.html에서 온 `Secure-Session-Registration` 의 몇 가지 예:
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256 RS256);path="reg";challenge="cv"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a"
Secure-Session-Registration: (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a", (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";provider_key="abc";provider_id="idp_id";provider_url="https://id_origin.example.com"

9.2. `Secure-Session-Challenge` HTTP 헤더 필드

Secure-Session-Challenge 헤더 필드는 서버가 클라이언트에 challenge를 보내기 위해 response에서 사용할 수 있다. 서버는 해당 challenge가 향후 `Secure-Session-Response` 헤더 내부의 DBSC proof에서 사용되기를 기대하거나, status가 403인 경우 쿠키 새로 고침 중에 새로 서명된 DBSC proof를 즉시 요청한다.

`Secure-Session-Challenge` 는 structured header이다. 그 값은 string이어야 한다. 그 ABNF는 다음과 같다:

SecureSessionChallenge = sf-string
항목의 의미는 § 9.2.1 `Secure-Session-Challenge` structured header serialization에서 정의된다.

처리 단계는 § 8.7 challenge 캐시에 정의된다.

9.2.1. `Secure-Session-Challenge` structured header 직렬화

`Secure-Session-Challenge` 는 Structured Field로 표현된다.[RFC9651]

이 표현에서 challenge는 string으로 표현된다.

Challenges는 "id"라는 이름의 sf-parameter를 가져야 하며, 그 값은 세션 식별자를 나타내는 string이어야 한다. 다른 모든 sf-parameter는 무시해야 한다.

https://example.com/login.html에서 온 `Secure-Session-Challenge` 의 몇 가지 예:
HTTP/1.1 403 Forbidden
Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK
Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK
Secure-Session-Challenge: "new challenge";id="my session 1"
Secure-Session-Challenge: "another challenge";id="my session 2"
HTTP/1.1 200 OK
Secure-Session-Challenge: "c1";id="session 1", "c2";id="session 2"

9.3. `Secure-Session-Response` HTTP 헤더 필드

Secure-Session-Response 헤더 필드는 사용자 에이전트가 세션 키 쌍의 개인 키를 클라이언트가 여전히 소유하고 있음을 증명하기 위해 DBSC proof를 서버에 보내는 데 request에서 사용할 수 있다.

Secure-Session-Response는 structured header이다. 그 값은 string이어야 한다. 그 ABNF는 다음과 같다:

SecureSessionResponse = sf-string

이 string은 DBSC proof JWT만 포함해야 한다. 모든 sf-parameter는 무시해야 한다.

POST example.com/refresh
Secure-Session-Response: "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRic2Mrand0In0.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL3JlZyIsImp0aSI6ImN2IiwiaWF0IjoiMTcyNTU3OTA1NSIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZfR0Iydm9RMHFyb01oNk9sREZDRlNfU0pyaVFpMVBUdnZCT2hHWjNiSEkiLCJ5IjoiSWVnT0pVTHlFN1N4SF9DZDFLQ0VSN2xXQnZHRkhRLWgweHlqelVqRUlXRSJ9LCJhdXRob3JpemF0aW9uIjoiYWMifQ.6Fb_vVBDmfNghQiBmIGe8o7tBfYPbPCywhQruP0vIhxgmcJmuNTaMHeVn_M8ZnOm1_bzIitbZqCWEn-1Qzmtyw"

9.4. `Sec-Secure-Session-Id` HTTP 헤더 필드

Sec-Secure-Session-Id 헤더 필드는 사용자 에이전트가 현재 세션 식별자를 string 인수로 하여 현재 세션이 새로 고쳐지도록 요청하기 위해 request에서 사용할 수 있다.

`Sec-Secure-Session-Id` 는 structured header이다. 그 값은 string이어야 한다. 그 ABNF는 다음과 같다:

SecSecureSessionId = sf-string

이 string은 세션 식별자만 포함해야 한다. 모든 매개변수는 무시해야 한다.

POST example.com/refresh
Sec-Secure-Session-Id: "session-id"

9.5. `Secure-Session-Skipped` HTTP 헤더 필드

Secure-Session-Skipped 헤더 필드는 요청이 사용자 에이전트 정책으로 인해 의도적으로 바인딩 자격 증명을 누락하고 있음을 나타내기 위해 request에서 사용할 수 있다.

`Secure-Session-Skipped` 는 List Structured Header [RFC9651]이다. 그 ABNF는 다음과 같다:

SecureSessionSkipped = sf-list

목록의 각 item은 쿠키 새로 고침을 건너뛴 대략적인 이유를 나타내는 sf-token이어야 한다. 지원되는 유일한 값은 "unreachable", "server_error", "quota_exceeded"이다. 이러한 토큰은 다음 상황에서 사용해야 한다:

하나의 sf-parameter가 정의된다:

GET example.com/requires_bound_cookie
Secure-Session-Skipped: unreachable;session_identifier=123, quota_exceeded;session_identifier=456

9.6. JSON 세션 지시 형식

서버는 세션 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시를 보낸다. 응답이 세션 지시를 포함한다면, 이는 JSON 형식이어야 한다.

JSON 객체의 루트에는 다음 키가 존재할 수 있다:

session_identifier

세션 식별자를 나타내는 string. 등록 중에는 새로 생성된 세션의 식별자이다. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다. 새로 고침 중에는 현재 세션의 식별자여야 한다. § 8.9 세션 생성을 참조한다.

refresh_url

향후 새로 고침 요청에 사용할 URL을 나타내는 string. 이는 완전한 URL일 수도 있고, 이러한 지시를 제공하는 request를 기준으로 상대적일 수도 있다. 이 키는 OPTIONAL이며, 존재하지 않으면 향후 새로 고침 요청에 해당 request url이 사용된다.

continue

세션이 계속 적용되어야 하는지 나타내는 boolean. 등록 및 새로 고침 엔드포인트는 세션을 종료하기 위해 이를 false로 설정할 수 있다. 이 키는 OPTIONAL이며, 존재하지 않으면 기본값은 true이다.

scope

세션이 포괄하는 리소스를 설명하는 JSON 세션 범위. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다.

credentials

이 세션이 보호하는 쿠키를 설명하는 JSON 세션 자격 증명list. continue 키의 값이 false인 경우를 제외하고 이 키는 존재해야 한다.

allowed_refresh_initiators

어떤 호스트가 DBSC 새로 고침을 시작할 수 있는지 설명하는 stringslist. 자세한 내용은 § 8.3 요청이 새로 고침을 허용하는지 식별을 참조한다. 이 키는 OPTIONAL이며, 존재하지 않으면 기본값은 빈 list이다.

{
  "session_identifier": "session_id",
  "refresh_url": "/RefreshEndpoint",

  "continue": false,

  "scope": {
    // Origin-scoped by default (i.e. https://example.com)
    "origin": "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.
    "include_site": true,

    "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; HttpOnly; SameSite=None"
    // Attributes Max-Age and Expires are ignored
  }],
    
  "allowed_refresh_initiators": [
    "example.com", 
    "*.example.com",
    "site-embedding-example.com"
  ]
}

9.7. JSON 세션 범위 지시 형식

서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시 안에서 JSON 세션 범위를 보낸다.

JSON 객체의 루트에는 다음 키가 존재할 수 있다:

origin

세션이 적용되는 origin 또는 site를 나타내는 string. 이 키는 OPTIONAL이며, 존재하지 않으면 지시를 제공하는 URL의 origin이 사용된다. 등록 중에는 등록 URL이고 새로 고침 중에는 새로 고침 URL이다.

include_site

세션이 origin-scoped(false)인지 site-scoped(true)인지를 나타내는 boolean. 이 키는 존재해야 한다. 이는 "scope_specification" 안의 모든 JSON 세션 범위 규칙보다 우선한다는 점에 유의한다 (§ 8.2 URL이 세션 범위에 있는지 식별 참조).

scope_specification

기본 범위(전체 origin 또는 site)에 대한 수정을 설명하는 JSON 세션 범위 규칙list. 이 키는 OPTIONAL이며, 존재하지 않으면 빈 list가 사용된다.

9.8. JSON 세션 범위 규칙 형식

서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 범위 안에서 JSON 세션 범위 규칙 객체의 list를 보낸다.

JSON 세션 범위 규칙의 루트에는 다음 키가 존재할 수 있다:

type

규칙이 대상을 포함하는지 제외하는지를 나타내는 string. 이 키는 존재해야 하며, 값은 "include" 또는 "exclude"여야 한다.

domain

규칙과 일치해야 하는 도메인을 나타내는 string. 이는 wildcard를 포함할 수 있다 (§ 8.2 URL이 세션 범위에 있는지 식별 참조). 이 키는 OPTIONAL이며, 존재하지 않으면 모든 도메인과 일치하는 '*'가 된다.

path

규칙과 일치해야 하는 path-prefixes를 나타내는 string. 이 키는 OPTIONAL이며, 존재하지 않으면 모든 경로와 일치하는 '/'가 된다. 자세한 의미는 § 8.2 URL이 세션 범위에 있는지 식별을 참조한다.

9.9. JSON 세션 자격 증명 형식

서버는 등록 중 및 선택적으로 세션 새로 고침 중에 JSON 세션 지시 안에서 JSON 세션 자격 증명 객체의 list를 보낸다.

JSON 객체의 루트에는 다음 키가 존재할 수 있다:

type

이 세션이 보호하는 자격 증명의 종류를 나타내는 string. 이 키는 존재해야 하며, 값은 "cookie"여야 한다.

name

바인딩된 쿠키의 이름을 나타내는 string.

attributes

보호되는 쿠키의 예상 속성을 포함하는 string. 이것이 어떻게 사용되는지에 대한 자세한 내용은 § 8.6 세션 자격 증명이 누락되었는지 식별을 참조한다.

9.10. DBSC Proof JWT 구문

DBSC proof는 클라이언트가 선택한 개인 키로 서명된(JSON Web Signature (JWS) 사용) JWT이다.

DBSC proof의 헤더는 최소한 다음 sf-parameter를 포함해야 한다:

typ

string. 이는 "dbsc+jwt"여야 한다.

alg

이 JWT에 서명하는 데 사용된 알고리즘을 정의하는 string. 이는 [IANA.JOSE.ALGS]의 "RS256" 또는 "ES256"이어야 한다.

DBSC proof의 payload는 최소한 다음 claims를 포함해야 한다:

aud

string. 이는 이 JWT가 원래 전송된 URL이어야 한다. 예: "https://example.com/refresh.html".

jti

string. 이는 등록 헤더에서 보낸 challenge 값의 복사본이다.

iat

JWT가 발급된 시간을 식별하는 double. 이는 JWT의 나이를 결정하는 데 사용할 수 있다. 그 값은 [RFC7519]에 설명된 NumericDate 값을 포함하는 number여야 한다.

key

[RFC7517]에 지정된 JWK를 정의하는 dictionary.

또한 다음 claim은 `Secure-Session-Registration` 헤더 필드에 존재하는 경우 반드시 존재해야 한다:

authorization

string. 이는 `Secure-Session-Registration` 헤더 필드에 설정되어 있는 경우 해당 string의 직접 복사본이다. 이 string은 헤더에 포함하는 것이 OPTIONAL이지만, 존재한다면 클라이언트는 이를 DBSC proof의 claim에 추가해야 한다는 점에 유의한다.

DBSC proof가 새로 고침 요청을 위한 것이라면, 다음 claim은 반드시 존재해야 한다:

sub

세션 식별자를 지정하는 string.

https://example.com/reg로 전송되는 DBSC proof의 예:
// Header
{
  "alg": "ES256",
  "typ": "dbsc+jwt"
}
// Payload
{
  "aud": "https://example.com/reg",
  "jti": "cv",
  "iat": 1725579055.0,
  "key": {
    "kty": "EC",
    "crv": "P-256",
    "x": "6_GB2voQ0qroMh6OlDFCFS_SJriQi1PTvvBOhGZ3bHI",
    "y": "IegOJULyE7SxH_Cd1KCER7lWBvGFHQ-h0xyjzUjEIWE"
  },
  "authorization": "ac"
}

다음과 같은 서버의 response header를 가진 http://example.com/page.html에 대한 응답을 기반으로 한다:

HTTP/1.1 200 OK
Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"

10. 다른 명세에 대한 변경 사항

10.1. Fetch 명세에 대한 변경 사항

이 명세는 HTTP-network-or-cache fetch 알고리즘의 업데이트를 요구한다. request는 다음으로 구성된 tupleslist지연된 기기 바인딩 세션 ids를 가진다:

이 list는 처음에는 비어 있다.

8.21단계에서 쿠키를 계산한 뒤, § 8.5 새로 고침이 필요한 세션 식별을 실행한다. 그 결과 session이 non-null이면:

  1. httpRequest, 반환된 session세션 키 쌍, 새로 고침 URL, 세션 식별자, 캐시된 challenge, 빈 authorization으로 § 8.8 요청 보내기를 실행한다.

  2. 원래 입력으로 HTTP-network-or-cache fetch를 다시 시작한다.

이 명세는 또한 새 헤더를 처리하기 위한 두 개의 새 호출을 요구한다. 현재 HTTP-network fetch의 14단계 이후에 다음 단계를 실행한다:

  1. § 8.10 세션 등록 처리§ 8.7 challenge 캐시를 실행한다.

10.2. Clear Site Data 명세에 대한 변경 사항

이 명세는 Clear Site Data 명세 section 4.2.5 Clear DOM-accessible storage for origin가 origin과 일치하는 범위의 모든 기기 바인딩 세션을 지우도록 요구한다. 또한 section 4.2.4를 업데이트하여 등록된 도메인과 일치하는 사이트의 기기 바인딩 세션을 지우도록 요구한다.

11. IANA 고려 사항

영구 message header field registry는 다음 등록으로 업데이트되어야 한다: [RFC3864]

11.1. Secure-Session-Challenge

헤더 필드 이름
Secure-Session-Challenge
적용 가능한 프로토콜
http
상태
draft
작성자/변경 관리자
W3C
명세 문서
이 명세(§ 9.2 `Secure-Session-Challenge` HTTP 헤더 필드 참조)

11.2. Sec-Secure-Session-Id

헤더 필드 이름
Sec-Secure-Session-Id
적용 가능한 프로토콜
http
상태
draft
작성자/변경 관리자
W3C
명세 문서
이 명세(§ 9.4 `Sec-Secure-Session-Id` HTTP 헤더 필드 참조)

11.3. Secure-Session-Registration

헤더 필드 이름
Secure-Session-Registration
적용 가능한 프로토콜
http
상태
draft
작성자/변경 관리자
W3C
명세 문서
이 명세(§ 9.1 `Secure-Session-Registration` HTTP 헤더 필드 참조)

11.4. Secure-Session-Response

헤더 필드 이름
Secure-Session-Response
적용 가능한 프로토콜
http
상태
draft
작성자/변경 관리자
W3C
명세 문서
이 명세(§ 9.3 `Secure-Session-Response` HTTP 헤더 필드 참조)

11.5. Secure-Session-Skipped

헤더 필드 이름
Secure-Session-Skipped
적용 가능한 프로토콜
http
상태
draft
작성자/변경 관리자
W3C
명세 문서
이 명세(§ 9.5 `Secure-Session-Skipped` HTTP 헤더 필드 참조)

11.6. device-bound-sessions Well Known

Well-Known URI registry는 /.well-known/device-bound-sessions를 포함하도록 업데이트되어야 한다.

이 엔드포인트는 JSON으로 인코딩된 dictionary를 제공해야 한다. 세 가지 키가 정의된다:

https://example.com/.well-known/device-bound-sessions가 다음을 제공한다고 하자
{
  "registering_origins": [
    "https://subdomain.example.com",
    "https://subdomain.example.com:8000",
  ],
  "relying_origins": [
    "https://example.co.uk",
    "https://example-partner.com",
  ],
}

그러면 등록 요청은 다음 중 하나가 true인 경우에만 site-scoped session을 정의할 수 있다:

또한 https://example.co.ukhttps://example-partner.comhttps://example.com의 세션과 키를 공유할 수 있으므로, 해당 사이트들이 연합 로그인과 DBSC 보호를 모두 달성할 수 있다. 이를 위해 두 사이트는 각각의 .well-known 파일에서 다음 항목을 제공해야 한다:

{
  "provider_origin": "https://example.com/"
}

12. 변경 기록

이는 명세의 초기 초안이다.

13. 감사의 말

적합성

문서 규약

적합성 요구 사항은 설명적 주장과 RFC 2119 용어의 조합으로 표현된다. 이 문서의 규범적 부분에서 핵심 단어 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”은 RFC 2119에 설명된 대로 해석되어야 한다. 그러나 가독성을 위해 이 명세에서는 이러한 단어가 모두 대문자로 나타나지는 않는다.

이 명세의 모든 텍스트는 규범적이다. 단, 명시적으로 비규범으로 표시된 절, 예시, 참고는 제외한다. [RFC2119]

이 명세의 예시는 “for example”이라는 단어로 도입되거나 규범 텍스트와 구분되도록 class="example"으로 따로 표시된다. 다음과 같다:

이는 정보 제공용 예시의 예이다.

정보 제공용 참고는 “Note”라는 단어로 시작하며 규범 텍스트와 구분되도록 class="note"로 따로 표시된다. 다음과 같다:

Note, 이는 정보 제공용 참고이다.

적합 알고리즘

알고리즘의 일부로 명령형으로 표현된 요구 사항 (예: "strip any leading space characters" 또는 "return false and abort these steps")은 알고리즘을 도입할 때 사용된 핵심 단어 ("must", "should", "may" 등)의 의미로 해석되어야 한다.

알고리즘 또는 특정 단계로 표현된 적합성 요구 사항은 최종 결과가 동등한 한 어떤 방식으로든 구현될 수 있다. 특히 이 명세에서 정의하는 알고리즘은 이해하기 쉽도록 의도된 것이며 성능이 좋도록 의도된 것은 아니다. 구현자는 최적화할 것을 권장한다.

색인

이 명세에서 정의하는 용어

참조로 정의되는 용어

참고 문헌

규범 참고 문헌

[COOKIES]
A. Barth. HTTP State Management Mechanism. 2011년 4월. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. 2024년 11월 7일. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2025년 6월 24일. WD. URL: https://www.w3.org/TR/permissions/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3864]
G. Klyne; M. Nottingham; J. Mogul. Registration Procedures for Message Header Fields. 2004년 9월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings. 2006년 10월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. 2008년 1월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7405]
P. Kyzivat. Case-Sensitive String Support in ABNF. 2014년 12월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7405
[RFC7517]
M. Jones. JSON Web Key (JWK). 2015년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7517
[RFC7519]
M. Jones; J. Bradley; N. Sakimura. JSON Web Token (JWT). 2015년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7519
[RFC7638]
M. Jones; N. Sakimura. JSON Web Key (JWK) Thumbprint. 2015년 9월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7638
[RFC9112]
R. Fielding, Ed.; M. Nottingham, Ed.; J. Reschke, Ed.. HTTP/1.1. 2022년 6월. Internet Standard. URL: https://httpwg.org/specs/rfc9112.html
[RFC9651]
M. Nottingham; P-H. Kamp. Structured Field Values for HTTP. 2024년 9월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9651
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/