Skip to content

chore: JWT_PRIVATE_KEY를 pinlog-secrets-prod에 등록하고 Secret 전달 workflow로 운영에 주입한다 #105

Description

@cherry-go-round

운영 서명 키를 실제로 넣는 작업이다. #101이 문제를 기록했고, #100이 머지되며 전달 수단이 생겼다 — 그래서 #101 본문의 절차(인프라가 수동으로 SealedSecret을 만든다)는 지금 기준으로 낡았다. 이 이슈는 새 수단으로 실행하는 부분만 다룬다.

지금 상태 — 확인한 것

.github/workflows/seal-runtime-secrets.yml(#100, BI-26)이 pinlog-secrets-prod Environment의 시크릿을 읽어 Infra SealedSecret Draft PR을 만든다. 그 Environment에 9개 중 7개가 이미 등록되어 있다.

시크릿 등록 담당
GOOGLE_CLIENT_ID · GOOGLE_CLIENT_SECRET
KAKAO_CLIENT_ID · KAKAO_CLIENT_SECRET
NAVER_CLIENT_ID · NAVER_CLIENT_SECRET
PINLOG_AI_INTERNAL_SECRET 값이 AI 쪽과 같아야 한다(#102)
JWT_PRIVATE_KEY 이 이슈
PINLOG_INFRA_SECRET_PR_TOKEN 인프라 — 직접 발급·등록 예정(#102 코멘트)

workflow는 이 두 개가 채워지기 전까지 실행할 수 없다. 하나는 이 이슈, 하나는 인프라 소관이다.

왜 지금 해야 하는가

키가 없으면 JwtKeyProvider가 기동할 때 임시 키쌍을 만든다. 운영에서는 배포·재시작마다 전체 사용자 로그아웃이고, replicaCount가 2 이상이면 간헐적 401이 상시 발생한다(#101의 표). 재현이 안 되는 로그인 실패로 나타나서 원인을 찾기 어려운 종류의 고장이다.

이 작업은 prod 프로파일 활성화를 기다리지 않는다. private-key: ${JWT_PRIVATE_KEY:}application.yml의 base 설정이라 프로파일이 꺼진 지금도 주입한 값이 그대로 읽힌다. 프로파일 활성화(=fail-fast 복원)는 #101·#102의 순서 문제로 남고, 실제 사용자 피해는 이 이슈만으로 사라진다.

할 일

  • RSA 2048 PKCS#8 PEM 키를 만든다. 저장소에 커밋하지 않는다(public 저장소다)

    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out jwt-prod.pem
  • Team-PinLog/back → Settings → Environments → pinlog-secrets-prodJWT_PRIVATE_KEY로 등록한다. PEM 전문을 개행 그대로 붙여 넣는다

  • 인프라가 PINLOG_INFRA_SECRET_PR_TOKEN을 등록했는지 확인한다 (없으면 workflow가 PR을 만들 수 없다)

  • Seal backend runtime secrets workflow를 수동 실행(workflow_dispatch)한다

  • 생성된 Infra Draft PR을 인프라와 함께 검토·병합한다

  • 로컬 개발용으로도 필요하면 .env에 넣는 방법을 configuration.md·BT-05 기준으로 안내한다(선택)

주의 두 가지

PEM 개행. JwtKeyProvider.fromPem이 파싱 전에 replaceAll("\s", "")로 공백·개행을 모두 지운다. 그래서 실제 개행이 들어간 PEM 원문을 그대로 넣으면 된다. 반대로 \n 두 글자 문자열로 치환해 넣으면 역슬래시가 남아 base64 디코딩이 깨진다 — 로컬 .env\n으로 적는 방식(properties 파서가 실제 개행으로 되돌린다)과 다르므로 혼동하지 않는다.

키 회전은 구현되어 있지 않다. kid 헤더만 심어 뒀고 여러 키를 동시에 검증하지 않는다. 한번 정한 키를 바꾸면 그 시점에 전체 로그아웃이 되고, 키를 잃어버리는 경우도 같다. 등록한 값을 안전하게 보관해야 한다(BD-31).

완료 조건

  • pinlog-secrets-prodJWT_PRIVATE_KEY가 등록된다
  • Seal backend runtime secrets workflow가 성공하고 Infra SealedSecret PR이 생성된다
  • 운영 파드의 환경변수에 JWT_PRIVATE_KEY가 주입된다
  • 배포·재시작 후에도 기존 세션이 유지된다 (임시 키 생성 경로를 타지 않는다)
  • 저장소 어디에도 PEM 원본이 커밋되지 않는다

참고

Metadata

Metadata

Assignees

No one assigned

    Labels

    chore빌드·설정·잡무

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions