1. 목표
프라이빗 상태 토큰의 목표는 시간에 걸쳐 사이트 간에 제한된 신호를 프라이버시를 보호하는 방식으로 전달하는 것입니다. 이는 IETF Privacy Pass Working Group의 작업 문서에 명시된 privacy pass 프로토콜 [PRIVACY-PASS-ISSUANCE-PROTOCOL]의 변형을 사용하여 달성합니다 [PRIVACY-PASS-WG]. 프라이빗 상태 토큰은 Privacy Pass의 변형을 웹 플랫폼에서 구현한 것으로 볼 수 있습니다.
이 명세는 토큰 작업을 지원하기 위해 요청 딕셔너리에 새로운 필드를 도입합니다. 이 새로운 딕셔너리를 통해 프라이빗 상태 토큰이 어떻게 사용되는지 설명합니다.
2. 배경
프라이빗 상태 토큰 API는 익명 인증을 위한 메커니즘을 제공합니다. 사용자 에이전트가 제공하는 API는 클라이언트를 직접 인증하지 않고, 인증 정보를 전달하는 역할만 합니다.
클라이언트의 인증과 토큰 서명은 모두 발급자(issuer)로 불리는 동일한 엔터티에 의해 수행됩니다. 이는 [PRIVACY-PASS-ARCHITECTURE], [PRIVACY-PASS-AUTH-SCHEME]에서 설명된 attester와 issuer 역할의 결합 구조입니다.
사용자 에이전트는 토큰을 영구 저장소에 보관합니다. 이동된 origin은 퍼스트 파티 컨텍스트에서 토큰을 가져오거나 사용할 수 있고, 써드 파티 코드가 토큰을 가져오거나 사용할 수도 있습니다. 토큰을 사용하는 행위를 redeeming이라고 부릅니다.
Origin은 사용자 에이전트에게 원하는 발급자로부터 토큰을 가져오도록 요청할 수 있습니다. 토큰은 가져온 origin과 다른 origin에서 사용(redeem)될 수 있습니다.
프라이빗 상태 토큰 API는 연결 가능한 상태를 저장하는 쿠키 [RFC6265] 없이 사이트 간 익명 인증을 수행합니다. 쿠키는 사이트 간 인증이 가능하지만, 익명성을 제공하지는 않습니다.
쿠키는 많은 정보를 저장할 수 있습니다. [RFC6265]는 각 쿠키 당 최소 4096 바이트, 도메인 당 50개의 쿠키를 요구합니다. 즉, 하나의 origin은 50 x 4096 x 2^8개의 고유 식별자를 사용할 수 있습니다. 백엔드 데이터베이스와 결합시, 서버는 그만큼 많은 고유 사용자/세션에 대해 임의의 데이터를 저장할 수 있습니다.
쿠키에 비해, 프라이빗 상태 토큰에 저장될 수 있는 데이터 양은 매우 제한적입니다. 토큰은 여섯 개의 값 중 하나를 저장합니다(여섯 가지 enum 타입 값처럼). 즉 토큰은 2~3비트 (4 < 6 < 8) 데이터를 저장하며, 이는 쿠키가 저장할 수 있는 4096바이트에 비해 매우 작습니다.
더불어, 프라이빗 상태 토큰 API는 암호화 프로토콜을 사용하여 origin이 어느 사용자에게 어떤 토큰을 발급했는지 추적하지 못하게 합니다. 토큰을 제시받은 발급자는 자신이 발급한 것임을 확인할 수만 있고, 이 토큰이 언제 어떻게 발급되었는지를 연결할 수 없습니다. 쿠키에는 이러한 성질이 없습니다.
쿠키와 달리, 발급자로부터 여러 개의 토큰을 저장하더라도 토큰의 비연결성(unlinkability)으로 인해 사용자의 프라이버시는 침해되지 않습니다. 프라이빗 상태 토큰 API는 상위(origin) 당 최대 2개의 발급자만 허용합니다. 이는 발급자들이 협력할 경우 사용자에 대해 저장되는 정보를 제한하기 위해서입니다.
프라이빗 상태 토큰 작업은 [FETCH]를 기반으로 합니다. 프라이빗 상태 토큰 작업에 맞는 fetch 요청을 생성하여 fetch 함수의 파라미터로 사용할 수 있습니다.
3. 발급자 공개키
이 섹션에서는 프라이빗 상태 토큰 프로토콜에 사용할 공개키를 제공하기 위해 발급자가 지원해야 하는 공개 인터페이스를 설명합니다.
발급자는 키 세트를 유지하고, Issue 및 Redeem 암호 함수들을 구현하여 토큰을 서명하고 검증해야 합니다. 발급자는 키 커밋먼트 엔드포인트를 제공해야 합니다. 키 커밋먼트는 발급 및 redeem 작업에 필요한 암호키와 연관 메타데이터의 집합입니다. 발급자는 이를 보안 HTTP [RFC8446] 엔드포인트를 통해 제공합니다. 사용자 에이전트는 키 커밋먼트를 주기적으로 가져와야 합니다. 키 커밋먼트는 맵 객체로, 발급 및 리딤(사용) 작업에 필요한 암호키와 연관 메타데이터의 집합입니다.
키 커밋먼트 엔드포인트에 대한 요청의 응답은 다음과 같은 포맷의 JSON이어야 하며, 미디어 타입은 "application/pst-issuer-directory"입니다:
{ < cryptographic protocol_version>: { "protocol_version" : < cryptographic protocol version> , "id" : < key commitment identifier> "batchsize" : < batch size> , "keys" : { < keyID>: { "Y" : < base64- encodedpublic key> , "expiry" : < key expiration date> }, < keyID>: { "Y" : < base64- encodedpublic key> , "expiry" : < key expiration date> }, ... } }, ... }
-
<cryptographic protocol version>은 프라이빗 상태 토큰 프로토콜 버전의 문자열 식별자입니다. 동일한 문자열이 내부"protocol_version"필드 값으로도 사용됩니다. 프로토콜 버전 문자열 식별자는"PrivateStateTokenV1VOPRF"입니다.-
프로토콜 버전
“PrivateStateTokenV1VOPRF”는 [VOPRF] 암호 프로토콜을 구현합니다. 발급자는 최대 6개의 유효한 토큰 서명키를 사용할 수 있습니다.
-
-
"id"필드는 키 커밋먼트의 식별자를 제공합니다. 이는 부호 없는 32비트 정수 범위 내의 0 이상의 정수입니다. 값은 단조 증가해야 합니다. -
"batchsize"는 발급자 별 토큰 발급 작업마다 지원되는 마스킹된 토큰 최대 개수를 명시합니다. 값은 양의 정수입니다. 사용자 에이전트는 한 번에 더 적은 토큰을 보낼 수 있으나, 일반적으로batchsize만큼 보냅니다. -
"keys"필드는 각 식별자별 공개키 딕셔너리입니다.
모든 필드 이름 및 값은 문자열입니다. 발급자의 새로운 키 커밋먼트를 가져오면 기존 커밋먼트는 폐기됩니다.
3.1. 발급자 키 가져오기/등록
API의 프라이버시 보호를 유지하고 사용자별 키를 피하기 위해, 발급자는 토큰을 발급·사용하는 모든 클라이언트에 동일한 키를 제공해야 합니다.
이 특성을 보장하기 위해, 사용자 에이전트는 키 커밋먼트 가져오기를 프록시 방식이나 중앙 집중화 방식 등 사용자 구분 없는 방식으로 수행해 키를 개별 클라이언트에 배포하는 것이 권장됩니다.
키를 가져오기 위한 중앙 집중식 메커니즘을 사용하는 경우, 사용자 에이전트는 발급자가 자신의 키 커밋먼트를 등록하고 정기적으로 클라이언트에 제공할 수 있도록 등록 프로세스를 제공해야 합니다. 등록에 필요한 요구 사항과 방식은 구현 정의입니다.
등록 프로세스를 사용할 때는, 사용자 에이전트가 등록 요청에 만료일을 적용하여 더 이상 사용하지 않거나 폐기된 발급자는 제거할 수 있도록 하는 것이 좋습니다.
4. VOPRF 메서드
본 문서는 [RFC8446] 3절에서 정의한 TLS 표현 언어로 프로토콜 메시지를 인코딩합니다.
프로토콜 메시지 직렬화 및 프로토콜 메시지 역직렬화를 위해, 프로토콜 메시지는 [RFC8446] 3절에서 기술된 대로 인코딩 및 해석합니다.
프라이빗 상태 토큰의 경우, VOPRF 프로토콜은 곡선(G는 아래 함수에서 설명되는 대로)으로 P-384를 사용하며, nonce_size는 64로 정의합니다.
참고: 현재 버전 PST에서는 입력/출력에 X9.62 미압축 포인트를 사용하는 것은 [VOPRF] 명세와의 역사적 차이입니다. nonce_size 선택 역시 [BatchedTokens] 최신 드래프트와 역사적 차이입니다.
서버가 발급을 수행할 때, BlindEvaluateBatch 함수를 [BatchedTokens] 프로토콜에 따라 수행하며 입력 IssueRequest와 출력 IssueResponse는 아래와 같이 직렬화됩니다:
// 스칼라는 곡선에 따라 길이가 Ns인 타원곡선 스칼라(P-384의 경우 48).
// ECPoint는 X9.62 미압축 포인트 표현으로 인코딩된 타원곡선 포인트(P-384의 경우 97).
struct {
uint16 count;
ECPoint nonces[count]; // blindedElements에 대응
} IssueRequest;
struct {
ECPoint evaluated; // evaluatedElements에 대응
} SignedNonce;
struct {
Scalar c;
Scalar s;
} DLEQProof;
struct {
uint16 issued;
uint32 key_id;
SignedNonce signed[issued];
opaque proof<1..2^16-1>; // 직렬화된 DLEQProof 구조체 바이트.
} IssueResponse;
서버가 Redemption을 수행할 때는, 서버는 PSTEvaluate를 Token에 대해 실행하며 입력 RedeemRequest와 출력 RedeemResponse는 다음과 같이 직렬화합니다:
struct {
uint32 key_id;
opaque nonce[nonce_size];
ECPoint W;
} Token;
struct {
opaque token<1..2^16-1>; // 직렬화된 Token 구조체 바이트.
opaque client_data<1..2^16-1>;
} RedeemRequest;
struct {
opaque rr<1..2^16-1>;
} RedeemResponse;
프라이빗 상태 토큰은 PSTFinalize를 정의하는데, 이는 FinalizeBatch 함수의 변형이며, [BatchedTokens] 프로토콜에 따라 다음과 같습니다:
def PSTFinalize(input, blinds, evaluatedElements,
blindedElements, pkS, proof):
if VerifyProof(G.Generator(), pkS, blindedElements,
evaluatedElements, proof) == false:
raise VerifyError
// PST: 배치 생성 사용.
unblindedElements = []
for index in range(evaluatedElements.length):
N = G.ScalarInverse(blinds[index]) * evaluatedElements[index]
unblindedElements.append(G.SerializeElement(N))
// PST: hash output 대신 unblindedElements 반환.
return unblindedElements
프라이빗 상태 토큰은 아래와 같이 PSTEvaluate를 정의하는데, 이는 Evaluate 함수의 변형입니다 [VOPRF]:
// skS는 서버가 key_id를 사용하여 대응하는 비공개키를 조회해 결정.
def PSTEvaluate(skS, nonce, W, client_data):
inputElement = G.HashToGroup(nonce)
if inputElement == G.Identity():
raise InvalidInputError
evaluatedElement = skS * inputElement
issuedElement = G.SerializeElement(evaluatedElement)
// PST: hash output 대신 issuedElement 체크.
if issuedElement != W:
raise InvalidInputError
// PST: 서버는 client_data 등으로 redemptionRecord를 생성해 클라이언트에 반환할 수 있음.
return redemptionRecord
5. 알고리즘
사용자 에이전트는 issuerAssociations를 가진다. 이것은 맵으로, 키는 origin topLevel이고, 값은 리스트 타입의 origin들이다.
origin issuer와 origin topLevel이 주어졌을 때, 발급자 연관이 최상위 제한을 초과하는지 판단하기 알고리즘은 다음과 같다:
-
issuerAssociations[topLevel]가 존재하지 않으면, false를 반환한다.
-
issuerAssociations[topLevel]이 issuer를 포함하고 있으면, false를 반환한다.
-
issuerAssociations[topLevel]의 크기가 2보다 작으면, false를 반환한다.
-
true를 반환한다.
origin issuer를 origin topLevel과 연관짓기 알고리즘은 다음과 같다:
-
issuerAssociations[topLevel]가 존재하지 않으면, issuerAssociations[topLevel]를 빈 리스트로 만든다.
-
issuer를 issuerAssociations[topLevel]에 추가한다.
주어진 origin issuer가 origin topLevel과 연관되어 있는지 판단하기 위해 다음을 수행한다:
-
issuerAssociations[topLevel]가 존재하지 않으면, false를 반환한다.
-
issuerAssociations[topLevel]이 issuer를 포함하고 있으면, true를 반환한다.
-
false를 반환한다.
사용자 에이전트는 redemptionTimes를 가진다. 이는 맵으로, 키는 (issuer, topLevel)튜플이고, 값은 (lastRedemption, penultimateRedemption) 튜플이다.
주어진 origin issuer와 origin topLevel에 대해 redeem 타임스탬프 기록하기:
-
currentTime을 현재 날짜와 시간으로 정한다.
-
previousRedemption을 표현 가능한 가장 이른 날짜와 시간으로 정한다.
-
redemptionTimes[(issuer,topLevel)]가 존재하면 previousRedemption을 해당 튜플의 lastRedemption 값으로 한다.
-
set redemptionTimes[(issuer,topLevel)]를 (currentTime, previousRedemption)로 한다.
주어진 origin issuer와 origin topLevel에 대해 직전 redeem 조회하기:
-
penultimateRedemption을 표현 가능한 가장 이른 날짜와 시간으로 정한다.
-
redemptionTimes[(issuer,topLevel)]가 존재하면 penultimateRedemption을 해당 튜플의 penultimateRedemption 값으로 한다.
-
penultimateRedemption을 반환한다.
사용자 에이전트는 redemptionRecords를 가진다. 이는 맵으로, 키는 (issuer, topLevel)튜플이고, 값은 (record, expiration, signingKeys)튜플이다.
주어진 origin issuer, origin topLevel, 바이트 시퀀스 header, 지속시간 lifetime이 주어졌을 때, redemption record 저장하기:
-
lifetime이 0이라면, 종료한다.
-
currentTime을 1970년 1월 1일 UTC부터 현재까지 밀리초로 정한다.
-
expiration을 currentTime과 lifetime의 합으로 정한다.
-
signingKeys를 가장 최신 키 조회 결과로 얻는다.
-
redemptionRecords[(issuer, topLevel)]를 (header, expiration, signingKeys)로 설정한다.
주어진 origin issuer와 origin topLevel에 대해 redemption record 조회하기:
-
currentTime을 1970년 1월 1일 UTC부터 현재까지 밀리초로 정한다.
-
redemptionRecords[(issuer,topLevel)]가 존재하지 않으면, null 반환.
-
(record, expiration, signingKeys)를 redemptionRecords[(issuer,topLevel)]로 한다.
-
expiration이 currentTime보다 작으면, null 반환.
-
currentSigningKeys를 가장 최신 키 조회 결과로 얻는다.
-
currentSigningKeys가 signingKeys와 다르면, null 반환.
-
record를 반환한다.
사용자 에이전트는 pstKeyCommitments를 가진다. 이는 맵으로, 키는 origin이고, 값은 key commitment 객체이다.
참고: 각 사용자 에이전트는 신뢰할 수 있는 인프라를 통해 정기적으로 발급자에서 키 커밋먼트를 가져오고, 모든 인스턴스에서 동일한 키, 커밋 연결 맵을 클라이언트에 전달하도록 하는 것이 권장된다.
주어진 origin issuer에 대한 key commitment 조회:
-
pstKeyCommitments[issuer]가 존재하지 않으면, null 반환.
-
issuerKeys를 pstKeyCommitments[issuer]로 정한다.
-
해당 API에서 지원하는 각 cryptoProtocolVersion에 대해 구현 정의 순서로 반복:
-
issuerKeys[cryptoProtocolVersion]가 존재하면, 반환한다.
-
-
null 반환.
참고: cryptoProtocolVersion은 이 API에서 사용 가능한 여러 암호 버전 식별자 문자열이다. 사용자 에이전트는 지원하는 버전만 선택·우선순위로 키를 선택해야 하며, 성능·사용자 설정에 맞게 정렬됨.
주어진 origin issuer에 대해 가장 최신 키 조회:
-
commitment을 key commitment 조회로 정한다.
-
commitment가 null이라면 null 반환.
-
chosenKey를 null로 둔다.
-
currentTime을 현재 날짜와 시간으로 둔다.
-
commitment["keys"] 리스트의 각 key에 대해:
-
key["expiry"]가 currentTime보다 작으면, continue.
-
chosenKey가 null이면, chosenKey를 key로 설정한다.
-
key["expiry"]가 chosenKey["expiry"]보다 작으면, chosenKey를 key로 설정한다.
-
-
chosenKey 반환.
사용자 에이전트는 tokenStore를 가진다. 이는 맵으로, 키는 origin이고 값은 리스트 타입의 storedToken이다. storedToken은 (바이트 시퀀스, 바이트 시퀀스)의 튜플이다.
토큰 삽입하기를 수행하기 위해, origin issuer, 바이트 시퀀스 token, 그리고 바이트 시퀀스 signingKey가 주어졌을 때, 다음 단계를 수행한다:
-
(token, signingKey)로 새로운 storedToken을 만든다.
-
tokenStore[issuer]가 존재하지 않으면, 빈 리스트로 만든다.
-
storedToken을 tokenStore[issuer]에 추가한다.
토큰 조회를 origin issuer에 대해 실행하려면 다음 단계를 따른다:
-
tokenStore[issuer]가 존재하지 않으면, null을 반환한다.
-
tokenStore[issuer]의 크기가 0이면, null을 반환한다.
-
tokenStore[issuer]에서 임의의 요소를 제거하고, 그 요소를 반환한다.
토큰 폐기를 origin issuer와 바이트 시퀀스 signingKey에 대해 실행하려면, 다음 단계를 수행한다:
-
tokenStore[issuer]가 존재하지 않으면, 반환한다.
-
tokenStore[issuer]의 두 번째 요소가 signingKey와 동일하지 않은 모든 요소를 제거한다.
origin issuer의 토큰 개수 조회:
-
tokenStore[issuer]가 존재하지 않으면, 0 반환.
-
tokenStore[issuer]의 크기 반환.
주어진 origin issuer의 최대 배치 크기 조회:
-
key commitment 조회로 issuerKey 획득.
-
issuerKey가 null이면 0 반환.
-
issuerKey["batchsize"] 반환.
key commitments issuerKeys와 숫자 numTokens로 마스킹 토큰 생성:
-
빈 IssueRequest로 issueRequest 생성.
-
issueRequest["count"]를 numTokens로 설정.
-
빈 바이트 시퀀스로 blinds 생성.
-
numTokens번 반복:
-
프로토콜 메시지 직렬화로 issueHeader 생성.
-
튜플 (issueHeader, blinds) 반환.
key commitments issuerKeys, 바이트열 blinds, 바이트열 response으로 토큰 언마스킹:
-
빈 바이트열로 input 생성.
-
빈 리스트로 evaluatedElements 생성.
-
빈 리스트로 blindedElements 생성.
-
프로토콜 메시지 역직렬화로 response를 IssueResponse로 변환하여 issueResponse에 할당.
-
issueResponse["signed"]의 각 nonce에 대해:
-
nonce["blinded"]를 blindedElements에 추가.
-
nonce["evaluated"]를 evaluatedElements에 추가.
-
-
pkS를 issuerKeys["keys"][issueResponse["key_id"]]["Y"]로 설정.
-
proof에 issueResponse["proof"] 할당.
-
빈 리스트로 blindsList 생성.
-
blinds의 길이가 0보다 큰 동안 반복:
-
N은 X9.62 미압축 포인트 길이. blinds에서 앞 N개를 blind로, 나머지는 다시 blinds로.
-
blind를 blindsList에 추가.
-
-
PSTFinalize를 input, blindsList, evaluatedElements, blindedElements, pkS, proof로 실행해 result로.
-
result 반환.
PrivateToken
privateToken과 request request가 주어지면 request의 private token 속성 세팅하기:
-
request의 private token operation을 privateToken["
operation"]으로 설정한다. -
privateToken["
operation"]이"token-request"이면:-
Should request be allowed to use feature?에서 "
private-state-token-issuance"와 request를 인자로 실행 시false가 반환되면 "NotAllowedError"DOMException를 throw. -
이후 단계를 수행하지 않는다.
-
-
Assert: privateToken["
operation"]이"token-redemption"이거나"send-redemption-record"여야 한다. -
Should request be allowed to use feature?에서 "
private-state-token-redemption"와 request를 인자로 실행 시false가 반환되면 "NotAllowedError"DOMException를 throw. -
privateToken["
operation"]이"token-redemption"이면:-
request의 private token refresh policy를 privateToken["
refreshPolicy"]로 한다. -
이후 단계를 수행하지 않는다.
-
-
privateToken["
issuers"]의 각 issuer에 대해:-
issuerURL을 URL parser로 issuer에 대해 실행한 결과로 얻는다.
-
issuerURL이 실패(failure)라면,
TypeError를 throw. -
issuerURL의 scheme이 HTTP(S) scheme이 아니면,
TypeError를 throw. -
issuerOrigin을 issuerURL의 origin으로 설정.
-
issuerOrigin이 신뢰할 수 있는 origin이 아니면
TypeError를 throw. -
issuerURL을 request의 private token issuers에 추가한다.
-
6. Fetch 통합
6.1. 정의
RefreshPolicy
는 리딤션 요청에 첨부되며, 이 리딤션이 이전에 반환된 만료되지 않은 redemption record를 반환해야 하는지, 아니면 새로운 것을 반환해야 하는지 결정합니다.
enum {RefreshPolicy ,"none" };"refresh"
TokenVersion
은 현재 1로만 설정되어 있으며, 명세가 현재 지원하는 유일한 버전입니다.
enum {TokenVersion };"1"
OperationType
은 사용자 에이전트가 진행하고자 하는 작업이 무엇인지 나타냅니다.
enum {OperationType ,"token-request" ,"send-redemption-record" };"token-redemption"
PrivateToken
은 fetch 요청을 만들기 위해 필요한 정보를 담고 있습니다.
dictionary {PrivateToken required TokenVersion ;version required OperationType ;operation RefreshPolicy = "none";refreshPolicy sequence <USVString >; };issuers
이 명세는 RequestInit
딕셔너리에 새로운 속성을 추가합니다:
partial dictionary RequestInit {PrivateToken ; };privateToken
6.2. 요청 변경 사항
request는 private token refresh
policy 연관 값을 갖고, 타입은 RefreshPolicy
이며 기본값은 "none"입니다.
request는 private
token operation 연관 값을 가지며, 타입은 OperationType입니다.
request는 private token issuers 연관 값을 가지고, 이는 문자열 리스트입니다.
참고: Private
token refresh policy는 private token
operation이 "token-redemption"이 아닐 경우 무시됩니다. Private token
issuers는 private token operation이
"send-redemption-record"이 아닐 경우 무시됩니다. Private token
issuers는 private token operation이
"send-redemption-record"일 때 반드시 지정되어야 하며 비어 있으면 안 됩니다.
이 명세는 두 개의 새로운 정책 제어 기능을 정의합니다. 각각의 기능은 주어진 프라이빗 상태 토큰 동작에 정확히 하나씩 적용됩니다.
"private-state-token-issuance"라는
정책 제어 기능은 "token-request" 작업에 적용됩니다. 기본 허용 목록은 ["self"]입니다.
"private-state-token-redemption"라는
정책 제어 기능은 "send-redemption-record" 및
"token-redemption" 작업에 적용됩니다. 기본 허용 목록은 ["self"]입니다.
request는 pstPretokens 연관 값을 가지고, 이는 null 또는 바이트 시퀀스입니다.
new Request (input, init)
생성자에, 28번째 단계(
"Set this's request to request")
전에 다음 단계를 추가합니다:
RequestInit
init과 Request
request가 주어지면 다음을 수행:
-
init["
privateToken"] 가 존재하면:-
privateToken을 init["
privateToken"]로 둠. -
set private token properties for request from private token을 privateToken과 request에 대해 실행.
-
6.3. http-network-or-cache fetch 변경 사항
이 명세는 http-network-or-cache fetch 알고리즘에, 헤더 목록을 수정하기 전에 다음 단계를 추가합니다:
-
request의 private token operation이 null이면, 나머지 단계 중단.
-
request의 private token operation이
"token-request"인 경우:-
private state token issue request headers 추가를 httpRequest에 실행.
-
나머지 단계 중단.
-
-
request의 private token operation이
"token-redemption"인 경우:-
private state token redemption request headers 추가를 httpRequest에 실행.
-
나머지 단계 중단.
-
-
Assert: request의 private token operation이
"send-redemption-record"임. -
private state token redemption record headers 추가를 httpRequest에 실행.
6.4. HTTP fetch 단계 변경
이 명세는 HTTP fetch 알고리즘에, redirect status 확인 전(예: "7. If actualResponse’s status is a redirect status, ...") 아래 단계를 추가합니다:
-
issue response result를 handle an issue response (request request, response actualResponse)의 결과로 둠.
-
issue response result가 network error이면, issue response result를 반환.
-
redeem response result를 handle a redeem response (request request, response actualResponse)의 결과로 둠.
-
redeem response result가 network error이면, issue response result를 반환.
7. iframe 통합
7.1. HTMLIframeElement의 privateToken 콘텐츠 속성
iframe
요소는 privateToken 콘텐츠 속성을 포함합니다. IDL 속성 privateToken
은 reflects 동작을 따르며,
privateToken
콘텐츠 속성을 반영합니다.
partial interface HTMLIFrameElement { [SecureContext ]attribute DOMString ; };privateToken
7.2. "fetch로 내비게이션 파라미터 생성" 단계 변경
아래 단계는 create navigation params by fetching의 "25. Return a new navigation params, with ..." 단계 이전에 추가됩니다:
-
navigable의 container가
iframe요소이면서,privateToken콘텐츠 속성을 가진 경우, set private token properties for request from private token을 navigable의 privateToken 및 request에 대해 실행.
8. XMLHttpRequest 통합
8.1. PrivateToken 첨부
XMLHttpRequest
객체는 private state token 연관 값을 가지고,
이는 PrivateToken
오브젝트로 이 요청에 대해 어떤 OperationType
을 실행할지 지정합니다.
partial interface XMLHttpRequest {undefined setPrivateToken (PrivateToken ); };privateToken
setPrivateToken(PrivateToken privateToken)
메서드의 단계는 다음과 같습니다:
-
this의 state가 "opened"가 아니라면, "
InvalidStateError"DOMException를 throw. - this의
send()플래그가 set되어 있다면, throw "InvalidStateError"DOMException. - this의 private state token을 privateToken으로 설정.
8.2. send() monkeypatch
send(body)
를 다음과 같이 수정:
다음 단계 이후:
req를 request의 새로운 인스턴스로 초기화한다...
아래 단계를 추가:
9. 발급 프로토콜
이 섹션은 발급 프로토콜을 설명합니다. 사용자 에이전트와 발급자 모두를 위한 발급 프로토콜 단계 두 부분을 포함합니다.
9.1. 이슈 요청 생성
let issueRequest= new Request( "https://example.issuer:1234/issuer_path" , { privateToken: { version: 1 , operation: "token-request" , } }); fetch( issueRequest);
private state token issue request headers 추가 알고리즘, request request에 대해:
-
request의 client가 secure context가 아니면 return.
-
topLevel을 request의 client의 top-level origin으로 둔다.
-
issuer를 topLevel과 연관시키는 것이 최상위 발급자 수 제한을 초과한다면, return.
-
발급자 연관짓기를 issuer와 topLevel에 대해 수행.
-
토큰 개수가 issuer에 대해 500 이상인 경우 return.
-
issuerKeys를 key commitment 조회 결과로 둔다.
-
issuerKeys가 null이면 return.
-
signingKey는 가장 최신 키 조회 결과로 얻음.
-
토큰 폐기를 issuer와 signingKey에 대해 실행.
-
numTokens를 issuer의 최대 배치 크기 또는 구현 의존적 토큰 개수 제한(권장값 100) 중 작은 값으로 결정.
-
(issueHeader, pretokens)를 마스킹 토큰 생성 (issuerKeys, numTokens)로 얻음.
-
request의 cache mode를
"no-store"로 설정. -
request의 pstPretokens를 pretokens로 설정.
-
base64EncodedTokens를 issueHeader의 base64 인코딩 [RFC4648] 버전으로 둔다.
-
cryptoProtocolVersion을 실제로 사용된 암호 프로토콜 버전으로 둡니다.
-
구조화 헤더 값 설정 (
Sec-Private-State-Token, base64EncodedTokens) 을 request의 header list에 반영. -
구조화 헤더 값 설정 (
Sec-Private-State-Token-Crypto-Version, cryptoProtocolVersion) 을 request의 header list에 반영.
Sec-Private-State-Token: <masked tokens encoded as base64 string> Sec-Private-State-Token-Crypto-Version: <cryptographic protocol version, VOPRF>
9.2. 발급자 서명 토큰
이 섹션은 발급자 서버에서 발생하는 토큰 서명에 대해 설명합니다. VOPRF는 사용할 키의 선택을 통해 여섯 개 값 중 하나만을 인코딩할 수 있습니다.
발급자는 자신의 개인키를 사용하여 Sec-Private-State-Token 요청 헤더 값으로 전달된 마스킹 토큰을, 발급 요청의 다른 정보에 따라 결정되는 값과 함께 서명합니다. 발급자는 요청의 Sec-Private-State-Token-Crypto-Version 헤더에 명시된 암호 프로토콜을 사용합니다. 발급자는 서명된 토큰을 Sec-Private-State-Token 응답 헤더 값에 base64 [RFC4648] 바이트 문자열로 인코딩하여 반환합니다.
Sec-Private-State-Token: <token encoded as base64 string>
9.3. 이슈 응답 처리
이슈 응답 처리를 위해 request request와 response response가 주어졌을 때, 다음을 수행합니다:
-
request의 header list에 Sec-Private-State-Token이 없으면 null을 반환합니다.
-
response의 header list에 Sec-Private-State-Token이 없으면 network error를 반환합니다.
-
header를 get Sec-Private-State-Token from response의 header list 결과로 할당합니다.
-
header가 비어 있으면 반환.
-
Delete Sec-Private-State-Token을 response의 header list에서 삭제합니다.
-
issuerKeys를 key commitment 조회 결과로 할당합니다.
-
issuerKeys가 null이면 반환.
-
pretokens를 request의 pstPretokens 값으로 둡니다.
-
pretokens가 null이면 반환.
-
rawResponse를 header의 base64 디코딩 [RFC4648] 버전으로 둡니다.
-
unmasked tokens을 unmasking response tokens (issuerKeys, pretokens, rawResponse)의 결과로 둡니다.
-
unmasked tokens가 null이면 network error를 반환합니다.
-
signingKey를 가장 최신 키 조회 결과로 둡니다.
-
unmasked tokens의 각 token에 대하여 다음 실행:
-
Insert a token for issuer, token, and signingKey.
-
-
반환.
10. 토큰 사용(Redeem)
사용자 에이전트가 최상위 origin으로 이동할 때, 이 origin 또는 해당 origin에 포함된 서드 파티 사이트는 사용자 에이전트가 보관 중인 특정 발급자의 토큰을 사용(redeem)하여 토큰에 인코딩된 데이터를 확인할 수 있습니다.
'none'입니다.
let redemptionRequest= new Request( 'https://example.issuer:1234/redemption_path' , { privateToken: { version: 1 , operation: 'token-redemption' , refreshPolicy: { 'none' , 'refresh' } } });
redemption 헤더 설정을 request request 와 RedeemRequest record로 실행:
-
redemptionRequest를 serialize protocol message record 결과로 둡니다.
-
cryptoProtocolVersion을 사용된 암호 프로토콜 버전으로 둡니다.
-
token-lifetime을 redemption record의 만료 시간(초)으로 둡니다.
-
구조화 헤더 값 설정 (
Sec-Private-State-Token, redemptionRequest) 을 request의 header list에 설정. -
구조화 헤더 값 설정 (
Sec-Private-State-Token-Crypto-Version, cryptoProtocolVersion) 을 request의 header list에 설정. -
필요하다면 구조화 헤더 값 설정 (
Sec-Private-State-Token-Lifetime, token-lifetime) 을 request의 header list에 설정. -
request의 cache mode를
"no-store"로 설정.
private state token redemption request headers 추가는 request request에 대해 아래를 실행:
-
topLevel을 request의 client의 top-level origin으로 설정.
-
request의 client가 secure context가 아니면 return.
-
issuer를 topLevel과 연관시키는 것이 최상위 발급자 수 제한을 초과한다면 return.
-
발급자 연관짓기 실행.
-
request의 private token refresh policy가
"none"이라면:-
record를 redemption record 조회 (issuer, topLevel)로 획득.
-
record가 null이 아니면 redemption 헤더 설정(request, record) 후 return.
-
-
penultimateRedemption을 직전 redeem 조회 (issuer, topLevel) 실행.
-
penultimateRedemption이 구현 의존 시간(권장값 48시간)보다 작다면 error 반환.
-
commitments를 key commitment 조회 결과로 설정.
-
commitments가 null이면 return.
-
가장 최근 커밋이 아닌 키로 서명된 토큰 폐기 (issuer).
-
token을 토큰 조회(issuer)로 획득.
-
token이 null이면 return.
-
빈 RedeemRequest를 redeemRequest로 생성.
-
redeemRequest["token"] = token로 설정.
-
redemption 헤더 설정을 request, record로 실행.
10.1. 리딤 응답 처리
리딤 응답 처리: request request와 response response가 주어졌을 때:
-
request의 header list에 Sec-Private-State-Token이 없으면 null.
-
response의 header list에 Sec-Private-State-Token이 없으면 network error를 반환.
-
rawHeader를 get Sec-Private-State-Token from response의 header list로 둔다.
-
rawHeader가 비어 있으면 null 반환.
-
rawResponse를 rawHeader base64 디코딩 [RFC4648] 버전으로 둔다.
-
header를 프로토콜 메시지 역직렬화 rawHeader (타입: RedeemResponse) 결과로 둔다.
-
Delete Sec-Private-State-Token을 response의 header list에서 삭제합니다.
-
lifetime을 표현 가능한 가장 긴 duration으로 둔다.
-
response의 header list에 Sec-Private-State-Token-Lifetime 헤더가 있으면, lifetime은 해당 값으로 설정.
-
Delete Sec-Private-State-Token-Lifetime 을 response의 header list에서 삭제.
-
topLevel을 request의 client의 top-level origin으로 설정.
-
redeem 타임스탬프 기록을 issuer, topLevel로 수행.
-
redemption record 저장을 issuer, topLevel, header, lifetime으로 수행.
참고: redemption record는 HTTP 전용이며, JavaScript는 Private State Token Fetch API를 통해서만 해당 redemption record에 접근/전송할 수 있습니다. redemption record는 발급자가 정의하는 의미를 가질 수 있는 임의 바이트 블롭으로 취급합니다.
10.2. Redemption Record(리딤 기록)
통신 오버헤드를 줄이기 위해, 사용자 에이전트는 redemption 응답의 Sec-Private-State-Token 헤더 값에 반환된 blob들을 캐시할 수
있습니다. 이 blob들을 Redemption
Record라 부릅니다. 사용자 에이전트는 이 기록을 캐싱해
이후 해당 유효성을 확인할 수 있는 origin 요청에 포함시킬 수 있습니다. 발급자는 리딤 응답에 선택적으로
Sec-Private-State-Token-Lifetime
헤더를 포함할 수 있으며, 이 헤더 값은 redemption record의 만료 시간을 초 단위로 명시합니다. 이 만료는 Sec-Private-State-Token-Lifetime
HTTP 응답 헤더 값으로 지정됩니다.
Redemption Record 는 바이트 시퀀스입니다.
Private State Tokens API는 'send-redemption-record' 연산을 제공하며, 이는 private state token redemption
record headers 추가에 사용됩니다. 이 연산은
handle a
redeem response에서 저장된 redemption record를 attach합니다.
private state token redemption record headers 추가는 request request에 대해 다음을 수행:
-
request의 client가 secure context가 아니면, 종료.
-
topLevel을 request의 client의 top-level origin으로 둡니다.
-
private token issuers의 각 issuer에 대해 반복:
-
issuerURL을 URL parser로 issuer를 파싱한 결과로 정함.
-
issuerURL이 실패라면 종료.
-
issuerURL의 scheme이 HTTP(S) scheme이 아니면 종료.
-
issuerOrigin을 issuerURL의 origin으로 둠.
-
issuerOrigin이 신뢰할 수 있는 origin이 아니면 종료.
-
-
records_per_issuer를 USVString 키, redemption record 값의 맵으로 생성.
-
private token issuers의 각 issuer에 대해 반복:
-
record를 redemption record 조회(issuer, topLevel)로 획득.
-
record가 null이면 continue.
-
Set records_per_issuer[issuer] = record.
-
-
records_per_issuer가 비어 있으면 종료.
-
headerItems를 구조화 헤더 리스트([RFC8941])로 생성.
-
records_per_issuer의 각 issuer -> record에 대해:
-
serializedIssuer를 issuer serialize한 결과로 둠.
-
serializedRecord를 record serialize한 결과로 둠.
-
serializedIssuer, serializedRecord 쌍을 headerItems에 추가함.
-
-
serializedHeaderItems를 headerItems serialize 결과로 둠.
-
serializedHeaderItems가 null이면 종료.
-
Sec-Redemption-Record에 serializedHeaderItems 설정.
10.3. Document
객체 변경점
partial interface Document {Promise <boolean >hasPrivateToken (USVString );issuer Promise <boolean >hasRedemptionRecord (USVString ); };issuer
11. 쿼리 API
11.1. 토큰 쿼리
Document
doc에서 USVString
issuer로 hasPrivateToken(issuer) 메서드를 호출하면
다음 단계를 실행해야 합니다:
-
p를 새로운 프로미스로 둡니다.
-
doc이 완전히 활성(fully active)이 아니면 p를 Reject하며, "
InvalidStateError"DOMException으로 반환합니다. -
global을 doc의 relevant global object로 둡니다.
-
global이 secure context가 아니면 p를 Reject하며, "
NotAllowedError"DOMException으로 반환합니다. -
parsedURL을 URL 파서를 issuer에 실행한 결과로 둡니다.
-
parsedURL이 실패(failure)라면 p를 Reject하며, "
TypeError"DOMException으로 반환합니다. -
origin을 parsedURL의 origin으로 둡니다.
-
topLevel을 doc의 top-level origin(relevant settings object 기준)으로 둡니다.
-
다음 단계들을 병렬로 실행:
-
issuer를 topLevel에 연관하는 것이 최상위 발급자 수 제한을 초과한다면, 글로벌 태스크 큐 추가로 networking task source에 global을 지정해 p를 Reject하며, "
NotAllowedError"DOMException으로 반환. -
발급자 연관짓기를 origin과 topLevel에 대해 수행.
-
key commitment 조회를 origin에 대해 실행한다. 커밋이 있으면 토큰 폐기를 origin에서, 발급자의 최신 커밋이 아닌 키로 서명된 토큰을 대상으로 실행.
-
글로벌 태스크 큐 추가로 networking task source에 global을 지정해 p를 resolve하는데, 해당 발급자의 토큰이 저장되어 있으면 true, 아니면 false로 설정.
-
-
p 반환.
참고: 이 쿼리는 사용자 에이전트의 상태를 변경합니다. issuer 인자가 현재 origin에 연관됩니다. 명세는 origin 별로 최대 2개의 issuer만 연관 허용합니다. 이는 사용자가 토큰을 보유한 issuer를 통해 정보가 누출되는 것을 방지하기 위함입니다. 토큰 쿼리는 오래된 토큰 삭제를 트리거합니다.
11.2. 리딤 기록 쿼리
Document
doc에서 USVString
issuer로 hasRedemptionRecord(issuer) 메서드를
호출하면 다음 단계를 실행해야 합니다:
-
p를 새로운 프로미스로 둡니다.
-
doc이 완전히 활성(fully active)이 아니면 p를 Reject하며, "
InvalidStateError"DOMException으로 반환합니다. -
global을 doc의 relevant global object로 둡니다.
-
global이 secure context가 아니면 p를 Reject하며, "
NotAllowedError"DOMException으로 반환합니다. -
parsedURL을 URL 파서를 issuer에 실행한 결과로 둡니다.
-
parsedURL이 실패(failure)라면 p를 Reject하며, "
TypeError"DOMException으로 반환합니다. -
origin을 parsedURL의 origin으로 둡니다.
-
topLevel을 doc의 top-level origin(relevant settings object 기준)으로 둡니다.
-
다음 단계들을 병렬로 실행:
-
origin이 topLevel과 연관되지 않았다면 글로벌 태스크 큐 추가로 networking task source에 global을 지정해 p를 resolve함 (false로 설정).
-
key commitment 조회를 origin에 대해 실행. 커밋이 있으면 토큰 폐기를 origin에서, 발급자의 최신 커밋이 아닌 키로 서명된 토큰을 대상으로 실행.
-
글로벌 태스크 큐 추가로 networking task source에 global을 지정해 p를 resolve함 (해당 issuer와 top level 쌍에 대해 redemption record가 있으면 true, 아니면 false).
-
-
p 반환.
참고: 토큰 쿼리와 비슷하게 리딤 쿼리도 사용자 에이전트의 상태를 수정할 수 있습니다. 단, 토큰 쿼리와 달리 리딤 쿼리는 issuer를 top level origin과 연관시키지 않습니다. 현재 저장된 토큰의 issuer에 대한 정보를 리딤 쿼리가 노출하지 않으므로 연관할 필요가 없습니다. 토큰 쿼리처럼 리딤 쿼리도 오래된 토큰 삭제를 유발할 수 있습니다.
11.3. PST 데이터 삭제
storage 표준의 사용자 인터페이스 가이드라인을 따라야 합니다. 사용자 에이전트는 PST 데이터를 storage에서 삭제할 수 있는 인터페이스를 제공해야 합니다.
12. Private State Token HTTP 헤더 필드
12.1. 'Sec-Private-State-Token' 헤더 필드
Sec-Private-State-Token request 헤더 필드는 발급 시 서명되지 않은 마스킹 토큰의 집합을 보냅니다. 리딤 시에는 서명된 마스킹 해제 토큰 한 개와 연관된 리딤 관련 메타데이터를 보냅니다.
Sec-Private-State-Token response 헤더 필드는 서명된 마스킹 토큰의 집합을 전달합니다. 리딤 과정에서는 방금 생성된 서명된 redemption record를 전달합니다.
이 필드는 구조화 헤더(Structured Header)이며, 값은 문자열(string)이어야 합니다. [RFC8941] 참고.
헤더의 ABNF는 다음과 같습니다:
Sec-Private-State-Token = sf-string
12.2. 'Sec-Private-State-Token-Lifetime' 헤더 필드
Sec-Private-State-Token-Lifetime
response 헤더 필드는, 관련 redemption record가 포함된 Sec-Private-State-Token response
헤더의 만료 시간을 초 단위로 전달합니다.
이 필드는 구조화 헤더(Structured Header)이며, 값은 정수(integer)여야 합니다. [RFC8941] 참고.
헤더의 ABNF는 다음과 같습니다:
Sec-Private-State-Token-Lifetime = sf-integer
12.3. 'Sec-Private-State-Token-Crypto-Version' 헤더 필드
Sec-Private-State-Token-Crypto-Version
헤더 필드는
Private State Token의 암호 프로토콜 버전을 전달합니다.
이 필드는 구조화 헤더(Structured Header)이며, 값은 문자열(string)이어야 합니다. [RFC8941] 참고.
헤더의 ABNF는 다음과 같습니다:
Sec-Private-State-Token-Crypto-Version = sf-string
12.4. 'Sec-Redemption-Record' 헤더 필드
Sec-Redemption-Record request
헤더 필드는
이전 redeem 작업의 캐시된 redemption record를 전송합니다.
이 필드는 구조화 헤더(Structured Header)이며, 값은 문자열(string)이어야 합니다. [RFC8941] 참고.
헤더의 ABNF는 다음과 같습니다:
Sec-Redemption-Record = sf-string
13. 프라이버시 고찰
13.1. 비연결성(Unlinkability)
암호 프로토콜 [VOPRF]는 마스킹 서명을 제공합니다. 리딤 시점에 발급자는 주어진 토큰에 대해 자신의 서명을 인식할 수 있지만, 언제 또는 어떤 컨텍스트에서 서명했는지는 알 수 없습니다. 이로 인해 발급자가 한 origin에서 토큰을 발급한 것을, 다른 origin에서의 리딤과 상관관계를 가지지 않게 합니다. 발급사는 사용자가 방문하는 origin에 대한 집계 정보만 파악할 수 있습니다.
13.2. 인코딩 정보 한정
사용자 에이전트는 프라이버시 보호를 위해 발급자가 동시에 가질 수 있는 고유 키의 개수를 제한해야 합니다. 제한이 없을 경우 발급자가 각 클라이언트 별로 고유 키를 발급해 비식별성을 깨트릴 수 있습니다. [VOPRF]의 경우, 최대 여섯 개의 키로 제한됩니다.
발급자는 서로 다른 "label"을 나타내는 키를 사용할 수 있으며, 이 label은 클라이언트의 신뢰 수준 등 임의의 상태를 대응할 수 있습니다. 발급자가 해당 label의 의미를 이해하고 토큰 리디머와 key "label" 정보를 공유해 각 토큰의 의미를 해석할 수 있습니다. 이는 악의적인 분석을 어렵게 하고 사람에게 의미가 있는 label로 인한 개인정보 노출을 막습니다. [VOPRF]에서 발급자의 6개 키는 곧 6개의 label을 의미할 수 있습니다.
13.2.1. 잠재적 공격: 사이드 채널 핑거프린팅
발급자가 네트워크 수준 핑거프린팅 또는 기타 사이드 채널을 활용하여, Private State Token API 자체는 사용자 에이전트에 대해 제한된 정보만 저장 및 노출하더라도, 토큰 발급 시점의 사용자 에이전트와 리딤 시점의 사용자 에이전트를 연관지을 수 있다면 비연결성(unlinkability)은 깨집니다.
13.3. 사이트 간 정보 전송
Private State Tokens는 퍼스트 파티 컨텍스트 간에 제한된 정보를 전송합니다. 기본 암호화 프로토콜은 각 토큰에 소량의 정보만을 담는 것을 보장합니다. 그러나 만약 하나의 페이지에서 많은 토큰 리딤을 허용한다면, 도메인 A의 사용자 U에 대한 1st party 쿠키를 Private State Token의 정보 채널로 인코딩해서 도메인 B에서 디코드할 수 있으며, 이로 인해 도메인 B가 도메인 A의 사용자 A의 쿠키 값을 알 수 있게 됩니다(1p 쿠키가 지워지기 전까지). 도메인 간 임의 통신을 허용하는 채널 문제 외에도, 일부 식별 공격(예: 악의적인 리디머가 특정 사용자가 토큰을 발급받은 issuer 집합 전체를 파악하려는 경우)에도 유사한 완화책이 적용됩니다.
13.3.1. 완화: 동적 발급/리딤 한도
이러한 공격을 막기 위해 본 명세는 발급과 리딤 모두에 한도를 둡니다. 발급 작업에서는 사용자의 발급 사이트 활성화가 필요합니다. 또한, 명세상 한 타임 윈도우(보통 48시간, 구현 정의) 내에 세 번째 리딤은 허용되지 않습니다.
13.3.2. 완화: 사이트별 발급자 한도
한 origin 당 허용되는 발급자 수가 늘어날수록 한 origin에서 다른 origin으로 개인정보가 유출될 확률도 높아집니다. 남용을 막기 위해, 사용자 에이전트는 최상위 origin 당 최대 2개의 발급자만 연관 짓도록 허용합니다. 발급자 연관은 토큰 쿼리 API에도 적용되며, § 11.1 Token Query 참고.
14. 보안 고찰
14.1. 토큰 소모 방지
악의적인 origin은 저장된 모든 토큰을 리딤시켜 토큰을 소진(Exhaustion)시키려 할 수 있습니다. 이를 막기 위해 명세는 리딤 작업 횟수에 제한을 둡니다. 특정 origin의 컨텍스트 내에선 2회 리딤까지만 허용되며, 3회차 리딤은 최초 리딤 후 구현 정의한 시간을(보통 48시간) 초과해야만 허용됩니다.
14.2. 발급자 소진 방지
경쟁하는 스크립트들이hasPrivateToken(issuer)를 경쟁적으로 호출해, 최대 두 개의 issuer 제한 내에서 다른 스크립트의
issuer보다 먼저 issuerAssociations 맵에 등록될 수 있습니다. 이를 통제하기 위해,
최상위 origin는 다른 JavaScript가 로드되기 전에
hasPrivateToken(issuer)를 최대 두 번까지 호출해 원하는 issuer를 선점할 수 있습니다.
14.3. 이중 사용(더블스펜딩) 방지
모든 리딤이 동일 발급자에게 전송되므로, 발급자는 각 토큰이 한 번만 사용(리딤)되는지 검증할 수 있습니다. 따라서 악의적인 악성코드가 사용자의 모든 토큰을 탈취하더라도, 시간이 지나면 토큰이 소진됩니다. 위험을 줄이기 위해 발급자는 한 번에 적은 수의 토큰만 서명할 수 있습니다.
15. IANA 고찰
이 문서는 Sec-Private-State-Token, Sec-Private-State-Token-Lifetime, Sec-Private-State-Token-Crypto-Version HTTP 요청 헤더 필드를 정의하고, 이를 영구 메시지 헤더 필드 레지스트리에 등록하는 것을 목표로 합니다([RFC9110] 참고).
15.1. 'Sec-Private-State-Token' 헤더 필드
헤더 필드명: Sec-Private-State-Token
적용 프로토콜: http
상태: standard
작성자/변경 제어자: IETF
명세 문서: 이 명세 (§ 12.1 'Sec-Private-State-Token' 헤더 필드)
15.2. 'Sec-Private-State-Token-Lifetime' 헤더 필드
헤더 필드명: Sec-Private-State-Token-Lifetime
적용 프로토콜: http
상태: standard
작성자/변경 제어자: IETF
명세 문서: 이 명세 (§ 12.2 'Sec-Private-State-Token-Lifetime' 헤더 필드)
15.3. 'Sec-Private-State-Token-Crypto-Version' 헤더 필드
헤더 필드명: Sec-Private-State-Token-Crypto-Version
적용 프로토콜: http
상태: standard
작성자/변경 제어자: IETF
명세 문서: 이 명세 (§ 12.3 'Sec-Private-State-Token-Crypto-Version' 헤더 필드)
15.4. 'Sec-Redemption-Record' 헤더 필드
헤더 필드명: Sec-Redemption-Record
적용 프로토콜: http
상태: standard
작성자/변경 제어자: IETF
명세 문서: 이 명세 (§ 12.4 'Sec-Redemption-Record' 헤더 필드)
감사의 글
이 스펙의 기여자 Alex Kallam, Charlie Harrison, Chris Fredrickson, David Van Cleve, Dylan Cutler, Eric Trouton, Johann Hofmann, Kaustubha Govind, Mike Taylor, Ryan Kalla, Sam Schlesinger께 감사드립니다. 또한 Chris Wilson에게도 리뷰와 멘토링에 감사드립니다.