---
status: NODE_BOUND_HTTPS_RELAY_RUNTIME_POLICY_SELF_TESTED_DEFAULT_OFF
candidate_version: 1.4.81-node-bound-distinct-upnp-port-default-off-locked
candidate_bytes: 481811
candidate_sha256: bbac9679202b815127ec270ea8646f56d1abb872ff6e652e3bfc9556f358ce96
production_enabled: false
https_tunnel_provisioned: false
router_mapping_performed: false
operator_signing_used: false
validator_signing_used: false
---

# node-bound HTTPS relay runtime policy

## 목적

Web/TWA verifier는 production에서 HTTP PC endpoint를 거부한다. 기존 PC Sync는 `gatewayPublicUrl`을 지원하지만 각 PC의 환경변수나 config에 수동 고정해야 했으므로, 임의 적격 노드가 짧은 승인 lease로 HTTPS relay를 받아 directory signer가 되는 구조와 맞지 않았다.

PC Sync `1.4.81`과 기존 HMAC runtime policy 전달 경로에 `publicRelayUrlsByNodeKeyId`를 추가했다. 이 맵은 HTTPS tunnel을 생성하는 기능이 아니라, 외부에서 이미 준비된 HTTPS relay URL을 해당 PC의 Ed25519 node identity에 제한적으로 결합하는 기능이다.

## server-side 검증

rollout policy는 다음 조건을 모두 만족해야 한다.

- map key가 64자리 node key hash
- key가 같은 policy의 `admittedNodeKeyIds`에 포함
- URL scheme가 HTTPS
- username/password/query/fragment가 없음
- origin root만 허용
- 모든 URL origin이 서로 다름
- 최대 6개
- `peerRpcPublicRelayEnabled`와 `signedManifestVoteExchangeEnabled`가 함께 true

검증된 맵만 기존 sync-token HMAC update manifest의 runtime policy에 포함된다. 정책이 없거나 invalid이면 stable client를 반환하는 기존 fail-closed 동작은 유지된다.

## PC-side 검증과 선택

PC는 HMAC envelope를 검증한 뒤 같은 규칙으로 URL 맵을 다시 검증한다. 그 다음 자기 `rpcAttestationKeyId`와 정확히 일치하는 URL 하나만 `gatewayPublicUrl`로 선택한다. 다른 node의 URL을 대신 사용할 수 없으며 policy가 만료되면 runtime 기능과 URL 선택도 함께 사라진다. 명시적 로컬 환경변수는 기존처럼 운영자의 최우선 override로 남는다.

## 자기 시험

- admitted node key 3개와 HTTPS origin 3개 수락
- 각 PC가 자기 key에 해당하는 URL만 선택
- HTTP URL 거부
- 중복 HTTPS origin 거부
- 미승인 node key와 잘못된 URL 구조 거부
- 정책 만료·버전 불일치·타입 혼동 거부
- atomic runtime policy 저장 유지

증거: `evidence/node-bound-https-relay-policy-self-test-redacted.json`

## 제한

이 단계는 TLS certificate나 outbound tunnel을 자동으로 만들지 않았고 외부 전송도 시작하지 않았다. 실제 Web/TWA continuity를 위해서는 세 독립 failure domain의 PC에 각각 유효한 공인 HTTPS origin을 준비하고, 별도 승인 canary에서 이 맵을 넣어 브라우저와 물리 Android가 같은 signed bundle을 검증해야 한다.
