문서 목적 — 발주사(페이네스트) 또는 인수 개발자가 NestPay 시스템을 넘겨받아 개발·운영을 이어가기 위해 필요한 모든 접근권한의 위치·발급방법·절차를 한 곳에 정리한 인계서입니다.
★ 비밀값은 이 문서에 담지 않습니다. 비밀번호·암호화 키·시크릿·토큰의 실제 값 자체는 보안상 문서에 기재하지 않으며, "무엇을 · 어디서 · 어떻게 받는지"만 안내합니다. 실제 값은 별도 안전채널(대면 전달·비밀번호 관리도구·봉인 문서 등)로 인계합니다.
근거: docker-compose.yml, application.yml, SecretsGuard.java/StubGuard.java, 마이그레이션 V3/V31, build.js, 각 저장소 git remote (실제 파일 조회).
1. 저장소(Git) 접근
소스코드는 자체 호스팅 Git 서버 git.madeitup.kr 에 3개 저장소로 나뉘어 있습니다. HTTPS 프로토콜로 접근합니다.
| 저장소 | 내용 | 클론 주소 (git remote 실측) |
| paynest-v1 | API 서버(Spring Boot)·관리자 웹(admin)·소개 사이트(www)·nginx 설정·DB(마이그레이션·스키마·쿼리) | https://git.madeitup.kr/paynest/paynest-v1.git |
| paynest-app | Flutter 앱 (회원앱 user_app·매장앱 store_app·공용 packages/nestpay_shared) | https://git.madeitup.kr/paynest/paynest-app.git |
| paynest-docs | 발주사 공유용 산출물 문서 포털(이 문서 포함) | https://git.madeitup.kr/paynest/paynest-docs.git |
접근 발급
| 항목 | 내용 / 받는 방법 |
| Git 호스트 | git.madeitup.kr (개발사 운영 Git 서버) |
| 인증 수단 | Git 계정(ID/비밀번호) 또는 개인 액세스 토큰(PAT) — 값은 별도 안전채널로 전달. 인수 시 발주사 명의 계정으로 소유권 이전 권장. |
| 브랜치 | 기본 브랜치 main (실측) |
2. 서버·인프라 (도커 스택·포트)
발주사 제공 서버 2대를 L4 로드밸런서 뒤에 동일 구성으로 두고, DB·파일 스토리지를 공유하는 무상태(stateless) 구조입니다. 각 서버는 아래 도커 스택을 동일하게 올립니다.
| 서비스(컨테이너) | 이미지 (실측) | 역할 | 인터넷 노출 |
db (nestpay-mariadb) | mariadb:10.3 | 데이터베이스 — 발주사와 동일 버전 | 미노출(사설망) |
storage (nestpay-storage) | minio/minio (S3 호환) | 파일·이미지 실물 저장 — 운영은 외부 오브젝트 스토리지로 대체 | 미노출(사설망) |
api (nestpay-api) | 멀티스테이지 빌드(Temurin JDK17→JRE17) | Spring Boot API — Flyway 자동 마이그레이션 | nginx 경유 |
web (nestpay-web) | nginx:1.27-alpine | https 입구 — www/api/pg/admin 서브도메인 경로 분리 | 노출(443) |
포트 구성 (docker-compose.yml 실측)
| 구분 | 포트 | 용도 |
| 운영 | 443 | 하나의 서버(nginx)가 server_name 으로 www·api·pg·admin 서브도메인을 동시 서비스 (L4 뒤 2대 동일) |
| 운영 | /health | L4 헬스체크 경로 (api 서버 상태 점검) |
| 로컬 개발 | 8443 | api. 입구 — 앱 API(/app·/store) |
| 로컬 개발 | 9443 | admin. 입구 — 관리자 웹(정적 + /api) |
| 로컬 개발 | 7443 | pg. 입구 — 외부 PG 연동(/pg, HMAC) |
| 로컬 개발 | 6443 | www. 입구 — 회사·서비스 소개 정적 |
| 로컬 개발 | 3307→3306 | DB (로컬 확인용, 운영은 사설망만) |
| 로컬 개발 | 9000 / 9001 | 스토리지 S3 API / 웹 콘솔 (로컬 확인용) |
서버 접속(SSH) 및 도메인
미확정/확인필요: 운영 서버 2대의 IP·SSH 계정·L4 설정은 발주사 제공 인프라로, 소스코드/설정 파일에 값이 없어 이 문서에서 단정할 수 없습니다. 실제 접속정보는 발주사↔개발사 간 별도 안전채널로 인계합니다. 서비스 도메인도 현재 미확정이며 코드에서는 nestpay.co.kr 로 가정(SERVICE_DOMAIN 환경변수 1곳 변경으로 전체 반영).
3. 운영 필수 환경변수 (부팅 가드)
운영(NESTPAY_ENV가 dev가 아닐 때)에서 아래 값들이 개발 기본값 그대로거나 미설정이면, 서버가 켜지기 전에 부팅 자체를 차단합니다(fail-fast). 개발용 시크릿이 운영에 남아 토큰·개인정보가 위조되는 사고를 원천 차단하기 위함입니다. 아래는 환경변수 "이름"만 표기하며, 실제 값은 별도 안전채널로 전달합니다.
3-1. SecretsGuard — 개발 기본값이면 부팅 차단 (SecretsGuard.java 실측)
| 환경변수 이름 | 매핑 설정키 | 역할 | 미교체 시 |
APP_CRYPTO_KEY | security.crypto-key | 민감값(카드·CVC·계좌·OTP 씨앗 등) 암호화 열쇠 | 부팅 차단 |
ADMIN_TOKEN_SECRET | security.admin-token-secret | 관리자 출입증(토큰) 서명 비밀키 | 부팅 차단 |
INTERNAL_API_KEY | security.internal-api-key | 내부 웹훅(입금 통지) 인증 열쇠 — 은행/PG 게이트웨이만 아는 값 | 부팅 차단 |
DB_PASSWORD | spring.datasource.password | DB 접속 비밀번호 | 부팅 차단 |
STORAGE_SECRET_KEY | app.storage.secret-key | 파일 스토리지 비밀키 (개인정보 이미지 보호) | 부팅 차단 |
SWAGGER_ENABLED=false | springdoc.api-docs.enabled | 내부 API 문서 비공개 — false 아니면(기본 true) 차단 | 부팅 차단 |
3-2. 함께 설정하는 운영 환경변수 (application.yml / docker-compose 실측)
| 환경변수 이름 | 용도 | 운영 값 |
NESTPAY_ENV | 실행 환경 — 이 값이 dev가 아니면 SecretsGuard·StubGuard 작동 | live |
DB_HOST / DB_PORT / DB_NAME / DB_USER | DB 접속 주소·포트·DB명·계정 (비번은 위 DB_PASSWORD) | 운영 DB 값(별도) |
STORAGE_ENDPOINT / STORAGE_ACCESS_KEY / STORAGE_BUCKET | 운영 오브젝트 스토리지 주소·접근키·버킷 (시크릿은 위 STORAGE_SECRET_KEY) | 운영 스토리지 값(별도) |
SERVICE_DOMAIN | 서비스 도메인 — api/admin/www 서브도메인이 자동 파생 (단일 변경지점) | 도메인 확정 후 |
TRUSTED_PROXIES | X-Forwarded-For(진짜 IP)를 신뢰할 중계자(nginx) 대역 | 운영 프록시 대역 |
ADMIN_BOOTSTRAP_ALLOW | 관리자 IP 미등록(설치 직후)에만 쓰는 초기 허용 목록 | 운영은 미설정 권장(기본 127.0.0.1,::1) |
표기 주의 (실측 불일치): docker-compose.yml 주석에는 APP_ENV=live 로 적혀 있으나, 실제 코드(application.yml)가 읽는 환경변수 이름은 NESTPAY_ENV 입니다. 운영 설정 시 NESTPAY_ENV=live 를 사용해야 가드가 정상 작동합니다.
3-3. StubGuard — 외부연동 스텁이면 부팅 차단 (StubGuard.java 실측)
NestPay 는 실제 외부기관 계약 전까지 아래를 개발용 스텁으로 대신 동작시킵니다. 운영(NESTPAY_ENV≠dev)에서 스텁이 그대로 물려 있으면 부팅을 차단합니다 — 돈·신원 무검증 오픈 방지.
| 스텁 대상 | 현재 구현 | 운영 오픈 조건 |
은행 실명조회·1원인증 (BankVerifier) | StubBankVerifier (계약 전) | 실연동 구현 교체 필요 |
본인인증 (IdentityVerifier) | StubIdentityVerifier (계약 전) | 실연동 구현 교체 필요 |
4. 관리자 계정 (최초 로그인·OTP)
관리자는 전원 동등 구조입니다(V31 마이그레이션에서 root/admin 권한 구분 폐지 — "관리자는 전부 동등"이 발주사 확정). 로그인은 2단계(아이디+비밀번호 → OTP)이며, 최초 1회는 OTP 등록 절차를 거칩니다.
초기 시드 계정 (V3 마이그레이션 실측)
| 로그인 ID | 초기 비밀번호 | OTP 상태 | 비고 |
root | 123456 (초기값) | 미등록(첫 로그인 시 등록) | V31 이후 일반 관리자와 동등 |
admin | 123456 (초기값) | 미등록(첫 로그인 시 등록) | V32 에서 표시이름 중립화 |
★ 인수 즉시 초기 비밀번호(123456)를 반드시 변경하고, 각 관리자 개인 OTP(예: Google Authenticator 등 TOTP 앱)를 등록하십시오. 초기 비밀번호는 마이그레이션에 포함된 개발용 기본값입니다.
최초 로그인·OTP 등록 절차 (AdminAuthController 실측)
| 순서 | API | 동작 |
| 1 | POST /admin/auth/login | 아이디+비밀번호 확인 → 다음 단계(OTP 등록/입력) 안내 + 임시토큰 |
| 2 (최초 1회) | POST /admin/auth/otp/setup | OTP 앱 등록 후 6자리 코드 확인 → 정식 출입증(토큰) 발급 |
| 2 (평상시) | POST /admin/auth/otp/verify | OTP 6자리 확인 → 정식 출입증 발급 |
| 확인 | GET /admin/auth/me | 로그인한 관리자 정보(화면 상단 이름) |
보안: 로그인은 아이디 기준 무차별 대입 차단(RateLimit), OTP 검증은 IP 기준 차단이 적용됩니다. 관리자 API(/admin/*)는 화이트 IP 제한이 걸려 있으며, 각 관리자별 허용 IP 를 admin_allowed_ips 로 관리합니다.
5. DB · 파일 스토리지 접근
둘 다 인터넷 미노출(사설망)이며 앱 서버에서만 접속합니다. 아래는 계정 이름·경로만 표기하며, 운영 실제 값은 3장의 환경변수(DB_PASSWORD·STORAGE_SECRET_KEY 등)로 주입하고 별도 안전채널로 전달합니다.
데이터베이스 (MariaDB)
| 항목 | 로컬 개발 기본값 | 운영 |
| DB 이름 | nestpay | DB_NAME 로 지정 |
| 애플리케이션 계정 | nestpay / (로컬 비번) | DB_USER / DB_PASSWORD (별도) |
| 관리 계정(root) | root / (로컬 비번) | 운영 정책값(별도) |
| 접속 | localhost:3307 → 컨테이너 3306 | 사설망 내부 DB_HOST:DB_PORT |
파일 스토리지 (MinIO / 오브젝트 스토리지, S3 호환)
| 항목 | 로컬 개발 기본값 | 운영 |
| 엔드포인트 | http://nestpay-storage:9000 | STORAGE_ENDPOINT (예: storages 오브젝트 스토리지) |
| 액세스 키 / 시크릿 키 | 로컬 기본값 | STORAGE_ACCESS_KEY / STORAGE_SECRET_KEY (별도) |
| 버킷 | nestpay-files | STORAGE_BUCKET |
| 웹 콘솔 | localhost:9001 (로컬만) | 운영 콘솔 접근은 인프라 정책 |
파일 정보(이름·크기·형식)는 DB files 테이블, 실물 바이트는 스토리지 버킷에 보관합니다. L4 뒤 2대 서버가 같은 스토리지를 공유하므로 어느 서버로 업로드해도 다른 서버에서 그대로 읽고 지웁니다.
6. 외부 서비스 계정
| 서비스 | 소유(제공) | 용도 / 인계 방법 | 현재 상태 |
| 애플 개발자 계정 | 발주사 제공 | iOS 앱 App Store 배포·서명 인증서·프로비저닝 | 발주사 명의 계정 필요 |
| 구글 Play 개발자 계정 | 발주사 제공 | Android 앱 Play Store 배포 | 발주사 명의 계정 필요 |
| Firebase (FCM 푸시) | 발주사 제공 | 폰 화면 푸시. Firebase 프로젝트 ID + 서비스계정 키(JSON) 를 관리자 화면에서 업로드(중앙 files 보관) | 실발송 스텁 — 푸시 키 발급 후 연동 |
| Cloudflare | 개발사 | 문서 포털(nestpay.madeitup.kr, Cloudflare Pages) 배포. 서비스 운영과 무관 | 운영 중 |
| 은행 실명조회·1원인증 | 발주사 계약 | 실계좌 검증 — 계약 후 BankVerifier 실연동 교체 | 계약 전 스텁 |
| 본인인증(PASS 등) | 발주사 계약 | 가입자 신원확인 — 계약 후 IdentityVerifier 실연동 교체 | 계약 전 스텁 |
| PG(매장 결제 연동) | 발주사 계약 | /pg Open API(HMAC 서명 검증) — 서버측 검증부는 구현 완료 | 연동처별 키 교환 필요 |
FCM 인계 상세: Firebase 서비스계정 키 JSON 파일 자체를 이 문서에 넣지 않습니다. 관리자 웹의 푸시 설정 화면에서 프로젝트 ID 입력 + 서비스계정 키 파일 업로드 로 등록하며, 실제 파일은 발주사 Firebase 콘솔에서 발급받아 별도 안전채널로 전달합니다. FCM 실발송 연동은 키 발급 이후 코드 연동 지점(PushDispatchService/OutboxWorker)에서 마무리하는 스텁 상태입니다.
7. 배포 절차 요약
API·웹 스택 (paynest-v1 / apps/api)
| 단계 | 명령 / 내용 |
| 전체 한 번에 | docker compose up -d --build — DB healthy 대기 → API 빌드 → Flyway 마이그레이션 자동 적용 → nginx 기동 |
| 빌드 | 멀티스테이지 Dockerfile(컨테이너 안에서 JDK17 빌드) — 로컬에 Java·Gradle 불필요 |
| 마이그레이션 선행 | Flyway 가 기동 시 V1~V36(36단계)을 순서대로 자동 적용 — 스키마+기본데이터. 별도 수동 SQL 불필요 |
| 분리 제어 | docker-compose.db.yml(DB만)·docker-compose.api.yml(API만)·docker-compose.web.yml(nginx만) — 순서: DB → API → web |
| 인증서 | ./tls.sh — nginx 인증서 준비까지 포함해 web 입구 기동 |
| 운영 전제 | 기동 전 3장의 운영 환경변수 주입 필수(미설정 시 SecretsGuard/StubGuard 가 부팅 차단) |
문서 포털 (paynest-docs)
| 단계 | 명령 / 내용 |
| 재생성 | node build.js — 원본(paynest-app·paynest-v1)에서 산출물·코드 뷰어 site/ 갱신 |
| 배포 | wrangler pages deploy site --project-name nestpay (Cloudflare Pages). Git 연동 시 main push 자동 배포 |
| 버전 | 제출 버전은 git 태그 v0.x + CHANGELOG.md 이력 |
앱 배포 (paynest-app)
Flutter 회원앱·매장앱은 각각 애플/구글 개발자 계정으로 스토어 배포합니다. 앱 업데이트 정책은 강제 업데이트(스토어 최소버전 게이트) 확정입니다. API 주소는 NESTPAY_API_BASE 빌드 환경변수 또는 SERVICE_DOMAIN 파생값을 사용합니다.
인계 직후 필수 조치 체크리스트
- 관리자 초기 비밀번호(
root·admin = 123456) 즉시 변경 + 개인 OTP 등록
- 운영 시크릿(APP_CRYPTO_KEY·ADMIN_TOKEN_SECRET·INTERNAL_API_KEY·DB_PASSWORD·STORAGE_SECRET_KEY) 강한 값으로 발급·주입
NESTPAY_ENV=live · SWAGGER_ENABLED=false 설정 확인(미설정 시 부팅 차단)
- 외부연동(은행·본인인증) 실연동 교체 전에는 운영 부팅 불가(StubGuard) — 계약·구현 후 오픈
- Git·서버·스토리지·Firebase 계정을 발주사 명의로 소유권 이전
NestPay 산출물 · (주)페이네스트 · 작성일 2026-07-27 · 실제 코드/DB 기준 · 외부연동(펌뱅킹·본인인증·은행 실명조회)은 계약 전 스텁 상태임을 명시