# Entitlement verifier

Google Play의 고정된 비소모성 상품을 검증하고 설치에 묶인 단기 Pro 인증서를 발급하는 Cloud Run용
Node 서비스다. 공개 구매 검증, 인증된 Play RTDN 수신, 인증된 Voided Purchases 동기화만 제공한다.
Codex 계정·인증·채팅·로컬 경로에는 접근하지 않는다.

## 로컬 검사와 컨테이너

저장소 루트에서 테스트한다.

```powershell
npm.cmd --workspace apps/entitlement-verifier test
node --test tools/verifier-release.test.mjs
```

컨테이너 context에는 production 소스와 잠금 파일만 들어간다. 다음 명령은 이 디렉터리에서 실행한다.

```powershell
docker build --pull --tag entitlement-verifier:local .
```

이미지는 Node `22.17.0`을 고정하고 `node` 사용자로 실행하며 `/healthz`를 검사한다. Docker가 없는
개발 환경에서는 release test로 context와 보안 불변조건을 먼저 검사하고, 승인된 빌드 환경에서 실제
image build와 digest 기록을 완료한다.

## 환경 변수

필수 값의 이름만 아래와 같다. 실제 project ID, URL, 계정, secret 값은 저장소에 기록하지 않는다.

- `GOOGLE_PLAY_PACKAGE_NAME`
- `GOOGLE_PLAY_PRODUCT_ID`
- `PUBLIC_BASE_URL`
- `ENTITLEMENT_SIGNING_KEY_VERSION`
- `ENTITLEMENT_SIGNING_KEY_FILE`
- `PUBSUB_OIDC_AUDIENCE`
- `PUBSUB_OIDC_SERVICE_ACCOUNTS`
- `SCHEDULER_OIDC_AUDIENCE`
- `SCHEDULER_OIDC_SERVICE_ACCOUNTS`
- 선택: `PORT`, `REQUEST_TIMEOUT_MS`

`GOOGLE_APPLICATION_CREDENTIALS`는 허용하지 않는다. Google API 인증은 Cloud Run runtime 서비스
계정의 Application Default Credentials만 사용한다. Ed25519 개인키는 Secret Manager volume으로
마운트하고 `ENTITLEMENT_SIGNING_KEY_FILE`에는 그 절대 파일 경로만 전달한다.

## 최소 권한 경계

- runtime 서비스 계정: Play Console의 구매 조회·acknowledgement 권한, Firestore 읽기·쓰기,
  지정된 signing secret 버전에 대한 `roles/secretmanager.secretAccessor`
- Pub/Sub push 서비스 계정: 해당 Cloud Run 서비스의 `roles/run.invoker`
- Scheduler 서비스 계정: 해당 Cloud Run 서비스의 `roles/run.invoker`
- Pub/Sub 서비스 에이전트: push 인증 토큰 발급에 필요한 범위만 부여

서비스 계정 JSON 키는 만들거나 이미지·환경 변수에 넣지 않는다. audience는 각 내부 endpoint의
완전한 HTTPS URL과 정확히 같아야 하고, 호출 계정은 대응 allowlist에 명시되어야 한다.

실제 Cloud 리소스 생성, Play Console 연결, secret 업로드, 배포는
`docs/PRO_ENTITLEMENT_OPERATIONS.md`의 승인 절차를 별도로 따른다.
