제 4 장: 온라인 티켓 프로토콜

본 장은 Trusted_Ticket의 발급, 조회, 변환 및 디그레이드 흐름을 정의한다. 본 장의 흐름은 블루프린트 §2.2의 설계 의도에 대응한다.

4.1 적용 전제

Trusted_Ticket은 단말이 온라인으로 Ticket_Issuer 또는 온라인 폐기 서비스에 접근할 수 있는 경우에만 사용된다. 온라인 서비스를 사용할 수 없는 경우, 단말은 §4.5에 따라 자동으로 오프라인 인가로 폴백한다.

단말은 MUST Authorization_Descriptor(제 3 장)와 Trusted_Ticket을 모두 지원한다. 단말은 MUST NOT 합법적 서명의 Trusted_Ticket의 수용을 거부한다. 해당 단말 정책이 오프라인 인가를 선호하는 경우에도 마찬가지다.

4.2 발급 흐름

4.2.1 발급 요청

인가자는 CAP을 지원하는 클라이언트(모바일 App, Web 콘솔 등)를 통해 Ticket_Issuer에 발급 요청을 발신한다. 클라이언트와 Ticket_Issuer 간의 상호작용은 본 사양의 범위를 벗어나지만, Ticket_Issuer는 MUST:

  1. 요청 출처가 인증된 인가자임을 검증한다
  2. 인가자가 대상 Fay와 리소스에 인가할 권한을 가짐을 검증한다
  3. 로컬 정책으로 인가 범위를 검증한다(최대 유효 기간, 리소스 화이트리스트 등)

4.2.2 발급 단계

Ticket_Issuer는 MUST 다음 단계로 Trusted_Ticket을 생성한다:

  1. Header 구축: §2.4.2에 따라 alg, typ, kid 설정
  2. Payload 구축: §2.4.3에 따라 TicketPayload를 채우며, 모든 required 필드를 MUST 설정한다
  3. 제약 검증: exp - nbf ≤ 7일을 로컬 검증
  4. JSON 시리얼라이제이션: Header와 Payload를 UTF-8 JSON 바이트로 시리얼라이즈
  5. Base64URL 인코딩: Header와 Payload 바이트를 각각 Base64URL 인코딩
  6. 서명: RFC 7515에 따라 서명 입력 base64url(header) + "." + base64url(payload)를 계산
  7. Compact Serialization 생성: header.payload.signature 문자열로 연결
  8. 기록 등록: Ticket_Issuer 내부에서 발급된 티켓 상태를 유지(폐기 조회용)

4.2.3 발급 후 전달

Trusted_Ticket은 HTTPS 등 암호화 채널을 통해 대상 Fay 또는 그 iFay_Runtime에 전달된다. 전달의 구체적 방식은 본 사양의 범위를 벗어난다.

4.3 단말 검증 흐름

단말이 Trusted_Ticket을 검증하는 흐름과 Authorization_Descriptor를 검증하는 흐름의 차이점:

  1. Trusted_Ticket은 요청 시 iFay_Runtime이 완전히 단말에 전송한다(사전 보관하지 않음)
  2. 단말은 온라인 시 MAY Ticket_Issuer의 폐기 상태를 실시간 조회할 수 있다
  3. 검증 실패 시의 에러 코드는 E_TICKET_* 접두사

4.3.1 검증 요청

iFay_Runtime이 전송하는 AuthRequest는 완전한 Trusted_Ticket을 휴대한다:

AuthRequest (body of ProtocolMessage) {
  required fay_id        : Fay_ID
  required resource_id   : Resource_ID
  required access_mode   : AccessMode
  required credential    : CredentialContent
}

CredentialContent {
  required type : enum["descriptor_ref", "ticket"]
  oneof:
    descriptor_id : string                  // type == "descriptor_ref"
    ticket        : string                  // type == "ticket", JWS Compact 문자열
}

4.3.2 검증 단계(순서대로 실행)

단말은 MUST 다음 순서로 검증을 실행한다. 임의 단계 실패 시 즉시 에러를 반환한다.

단계 1: JWS 파싱

단말은 JWS Compact 문자열을 파싱한다:

  • header.payload.signature 세 부분으로 분할
  • header와 payload를 Base64URL 디코딩
  • header.typ == "cap-ticket+jws" 검증
  • header.alg이 §8에서 허용된 알고리즘 집합 내에 있음을 검증

임의 단계 실패 → E_TICKET_MALFORMED 반환

단계 2: 서명 검증

단말은 header.kid에 대응하는 Verification_Key로 JWS 서명을 검증한다(RFC 7515에 따름).

  • 서명 검증 실패 → E_INVALID_SIGNATURE 반환
  • kid에 대응하는 키가 미등록 또는 폐기됨 → E_VERIFICATION_KEY_INVALID 반환

단계 3: 유효 기간

§3.3.2 단계 3의 규칙에 따라 nbfexp를 검증한다.

단계 4: 주체, 단말, 리소스, 모드 매칭

§3.3.2 단계 4–6의 규칙에 따라 매칭을 진행한다. 에러 코드는 E_TICKET_* 접두사를 사용한다(§9 참조).

단계 5: 온라인 폐기 조회(옵션)

단말 정책이 온라인 폐기 검증을 요구하는 경우, 단말은 MAY Ticket_Issuer에 폐기 상태 조회를 발신할 수 있다:

TicketRevocationQuery {
  required jti : uuid
}

TicketRevocationResponse {
  required jti      : uuid
  required revoked  : boolean
  optional revoked_at : timestamp
}
  • 조회 타임아웃(기본 2초) → 단말은 SHOULD 해당 요청을 거부하고 E_REVOCATION_QUERY_TIMEOUT을 반환하지만, MAY 통과를 허용하도록 설정할 수 있다(폐기 지연 위험 수용)
  • 조회가 revoked == true 반환 → E_TICKET_REVOKED 반환
  • 조회 실패(서비스 도달 불가 등) → 단말은 MAY 로컬 캐시의 폐기 상태로 결정, 캐시 유효 기간 초과 시 타임아웃으로 처리

단말은 SHOULD 폐기 조회 결과를 캐시하며, 캐시 유효 기간은 5분을 초과하지 않는다.

4.3.3 검증 통과 후

검증 통과 후의 처리는 §3.3.3과 일치하며, Session을 생성하고 AuthResult를 반환한다.

4.4 오프라인 Authorization_Descriptor로의 변환

TicketPayload.convertible == true(기본값)인 경우, 단말은 검증 통과 후 Trusted_Ticket을 로컬 Authorization_Descriptor로 변환하여 오프라인 사용에 제공할 수 있다.

4.4.1 변환 발동

변환은 SHOULD 다음 상황에서 자동 실행된다:

  1. Trusted_Ticket 검증 통과 및 convertible == true
  2. 단말 정책이 오프라인 후속 접근을 허용
  3. TicketPayload.exp가 현재 시각에서 충분히 김(권장 > 1시간)

4.4.2 변환 단계

  1. 필드 매핑: §2.4.4 표에 따라 TicketPayload 필드를 DescriptorPayload에 매핑
  2. 유효 기간 제약: 변환 후의 not_after는 MUST min(TicketPayload.exp, 변환 시각 + 7일)을 초과하지 않음
  3. 메타데이터 보존: 원본 Trusted_Ticket의 핵심 감사 정보를 metadata에 저장:
    • metadata["origin"] = "converted_from_ticket"
    • metadata["origin_jti"] = TicketPayload.jti
    • metadata["origin_iss"] = TicketPayload.iss
    • metadata["origin_kid"] = TicketHeader.kid
  4. 로컬 서명: 단말은 그 로컬 보관 키를 사용하여 변환 후 payload를 재서명한다(§4.4.3 참조)
  5. 로컬 보관: 변환 후의 Authorization_Descriptor를 §3.2.3에 따라 암호화 보관

4.4.3 단말 로컬 서명 키

변환 흐름을 지원하기 위해, 단말은 MUST 한 쌍의 로컬 서명 키를 보유한다:

  • 개인 키: 단말 안전 보관에 보존되며, 로컬 변환 흐름에만 사용
  • 공개 키: source == "pre-installed" 종류의 Verification_Key로서 자체의 키 보관소에 등록

변환 후의 Authorization_Descriptor의 signature.key_id는 MUST 해당 로컬 키를 식별하고, payload.issuer_id는 MUST "local-conversion:" + terminal_id로 설정된다.

단말이 로컬 변환된 Authorization_Descriptor를 검증할 때, 로컬 공개 키로 서명을 검증한다. 이 설계로 다음을 보장한다:

  • 변환 후의 자격 증명은 독립적으로 오프라인 검증 가능하며, 원본 Ticket_Issuer에 의존하지 않는다
  • 변환 신뢰 체인은 단말 자체의 키 보안에 앵커링된다

4.4.4 변환의 한계성

로컬 변환된 Authorization_Descriptor는 MUST NOT:

  1. 다른 단말에서 신뢰된다(그 서명 key_id는 로컬임)
  2. 단말을 가로질러 마이그레이션 사용된다
  3. Descriptor_Issuer의 폐기 메커니즘으로 폐기된다(로컬 삭제를 거쳐야 함)

단말은 SHOULD 다음 상황에서 로컬 변환된 Authorization_Descriptor를 능동 삭제한다:

  1. 원본 Trusted_Ticket의 폐기 알림을 수신(jti로 연관)
  2. 자격 증명이 만료된 후 24 시간을 초과

4.5 온라인에서 오프라인으로의 디그레이드

4.5.1 디그레이드 발동

단말은 온라인 서비스 가용성을 지속적으로 모니터링한다. 다음 중 하나의 조건을 충족하면 디그레이드를 발동한다:

  1. Ticket_Issuer와의 연결이 30 초 이상 도달 불가
  2. 폐기 조회 요청이 연속 3 회 타임아웃
  3. 네트워크 스택이 글로벌 네트워크 사용 불가를 보고

4.5.2 디그레이드 동작

디그레이드 후, 단말은 다음 규칙으로 처리한다:

  1. 새 Trusted_Ticket의 수용을 거부한다(오프라인 수용으로 구성된 경우 제외) — 폐기 상태를 온라인 검증할 수 없음을 회피
  2. 이미 로컬 Authorization_Descriptor로 변환된 티켓은 §3 규칙에 따라 계속 사용
  3. Authorization_Descriptor를 직접 사용한 인가 검증 요청은 디그레이드의 영향을 받지 않음
  4. 단말은 MAY iFay_Runtime에 현재 오프라인 모드임을 시사하여, Fay가 동작 정책을 조정할 수 있도록 한다

4.5.3 복구

단말이 온라인 서비스 복구를 감지한 후 MUST:

  1. 폐기 목록의 동기화를 우선하여, 오프라인 기간에 누락되었을 가능성이 있는 폐기 선언을 로컬 상태에 적용
  2. 활성 Session을 다시 확인하고, 로컬 변환 Authorization_Descriptor를 사용하며 원본 ticket이 폐기된 Session에 대해, 제 5 장 규칙에 따라 강제 종료
  3. 정상적인 Trusted_Ticket 수용 정책으로 복구

복구 프로세스는 iFay_Runtime에 대해 투명하지만, 단말은 MAY SessionStateChanged를 통해 모드 변경을 알릴 수 있다.

4.6 이중 자격 증명 시나리오의 우선순위

하나의 Fay가 동일 리소스에 대한 Trusted_Ticket과 Authorization_Descriptor를 동시에 보유하는 경우, iFay_Runtime의 선택 정책:

네트워크 상태권장 선택이유
온라인 및 Ticket_Issuer 도달 가Trusted_Ticket시효성이 강하고, 실시간 폐기 가능
오프라인Authorization_Descriptor 또는 변환 후의 로컬 자격 증명Trusted_Ticket은 온라인 폐기 검증 불가

iFay_Runtime은 MAY AuthRequest에 폴백 자격 증명을 제공하여, 메인 자격 증명 검증 실패 시 예비 자격 증명을 시도할 수 있도록 한다. 본 사양은 폴백 메커니즘의 구체적 형식을 강제 정의하지 않지만, SHOULD 두 번의 독립적인 AuthRequest로 실현하여 프로토콜 복잡화를 회피한다.

4.7 Trusted_Ticket과 Authorization_Descriptor의 시맨틱 일관성

iFay_Runtime이 두 가지 자격 증명 종류를 동시에 사용할 때, 단말은 MUST 다음을 보장한다:

  1. 검증 결과 일관성: 동일 인가 범위가 두 자격 증명 하에서 검증 통과/거부의 판정 결과 일치
  2. 에러 코드 시맨틱 일관성: 등가의 실패 원인(유효 기간, 서명, 폐기 등)에 대해 시맨틱이 대응하는 에러 코드 사용(제 9 장 참조)
  3. Session 생성 일관성: 두 자격 증명으로 생성된 Session의 라이프사이클 관리에 차이 없음