Phase4 P1 — 연합 노드등록 서명 게이트 라이브 통합
개요
연합 API(:9160)의
POST /register는 그동안 누구나 등록 가능해 위장노드가 가짜 서비스를
연합체인에 append → 라우트 오염 위험이 있었다(인증=신원/권한은 해시체인 무결성과 별개 문제).
설계(연합인증설계.한선, 8/8 PASS)를 연합 API에 실제 배선해
서명 게이트를 활성화했다.
무엇을 했는지
- 연합인증설계.한선 라이브러리화
- 끝의
인증단위검증() 자동실행 줄 제거 (가져오기 시 단위검증 실행 방지)
- 신규 진입점
연합인증검증.한선 생성 (가져오기 + 호출) → 컴파일 후
8/8 PASS 재확인
- 연합 API에 가져오기 추가 —
가져오기 "연합인증설계.한선" (연합.한선과 함께).
이름충돌 없음(F공백정리/J값 ↔ A공백정리/A값 별개,
해시_SHA256은 builtin·
HMAC_SHA256은 해시.한선 함수).
- 등록처리() 서명 게이트
- body에서
nonce/ts/sig/auth 파싱(기존 node/loc/services/health 패턴 따름)
-
등록인증(모드,노드,위치,서비스,헬스,nonce,ts,sig,공유키) 호출 →
반환 1일 때만 노드등록() append
- 실패코드 → HTTP 매핑(
인증실패응답): -1 미등록/폐기·0 서명불일치 →
403, -2 ts만료·-3 nonce재사용 →
401
- 공유키는
노드공유키조회(노드)가
node-shared-keys.ndjson 라인스캔(최신 우선)
- POST /enroll 엔드포인트 — 노드가 등록키 최초 등록(부트스트랩토큰 HMAC 보호)
→
enroll검증() 통과 시
등록키저장() →
node-keys.ndjson append. 계층 B 연동.
부트스트랩 루트키는
fed-shared.key에서 읽고, 없으면 난수 SHA256으로 1회 생성(chmod 600).
- 하위호환 — sig 미포함 등록은 기본 거부(401).
FED_AUTH_OPTIONAL=1이면 경고만 하고 통과(점진전환용).
curl 검증 결과 (라이브 :9160)
| 케이스 | 결과 |
|---|
| (a) sig 없이 POST /register | 401 auth required ✅ |
| (b) 올바른 HMAC sig (계층A) | 200 block hash 반환 ✅ |
| (b2) 같은 nonce 재전송 | 401 code=-3 nonce replay ✅ |
| (b3) 위조 sig | 403 code=0 signature mismatch ✅ |
| (c) POST /enroll 올바른 부트스트랩 sig | 200 enrolled, node-keys.ndjson append ✅ |
| (c2) /enroll 위조 sig | 403 bootstrap mismatch ✅ |
| (c3) enroll된 노드 계층B 등록 | 200 block hash ✅ |
| (d) GET /verify | 200 chain intact, corrupted:false ✅ |
| (e) FED_AUTH_OPTIONAL=1 unsigned | 200 WARN 통과 ✅ |
관련 파일 (절대경로)
수정: /Users/ef/crowny-gateway/한선게이트웨이/연합인증설계.한선 (자동실행 제거 → 라이브러리화)
수정: /Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합API.한선 (게이트+enroll+공유키조회+부트스트랩)
생성: /Users/ef/crowny-gateway/한선게이트웨이/연합인증검증.한선 (단위검증 진입점)
데이터: /Users/ef/crowny-gateway/data/federation-chain/
fed-shared.key — 부트스트랩 루트키(enroll 보호, chmod 600, 자동생성/회전)
node-shared-keys.ndjson — 계층A 노드별 공유키(append-only)
node-keys.ndjson — 계층B enroll 등록키(append-only, revoke=state)
used-nonces.log — nonce 1회성 로그(replay 방어)
fedapi.toau — 컴파일된 실행본(LaunchAgent가 실행)컴파일/기동
bashcd /Users/ef/crowny-gateway/한선게이트웨이
export CROWNY_STD=/Users/ef/Downloads/CrownyTVM/std
/Users/ef/CrownyOS/crownyc/hanseonc_high 크라우니게이트웨이연합API.한선 \
> /Users/ef/crowny-gateway/data/federation-chain/fedapi.toau 2>/dev/null
/Users/ef/CrownyOS/crownyc/crownyc run \
/Users/ef/crowny-gateway/data/federation-chain/fedapi.toau # ENFORCE 기본
# 점진전환: FED_AUTH_OPTIONAL=1 crownyc run ...
현재 :9160 ENFORCE 모드로 기동 중. 라이브 게이트웨이(:8080/:8443) 무접촉.
원격 노드 서명 생성 예시 (인수인계)
계층A(공유키 HMAC). 정규문 =
노드ID|위치|서비스직렬|헬스|nonce|ts, sig = HMAC_SHA256(공유키, 정규문).
javascript가져오기 "해시.한선"
변수 canon = "node-seoul|seoul-rpi5|talk.crowny.org=127.0.0.1:9752|T|" + nonce + "|" + ts
변수 sig = HMAC_SHA256(공유키, canon)
앵커 운영자는 노드별 공유키를
node-shared-keys.ndjson에 사전 등록
(
{"node":"...","key":"...","ts":"..."} append). 계층B는 먼저 /enroll로 등록키를 올린 뒤
HMAC_SHA256(등록키, 정규문)으로
auth:"B" 등록.
잔여 이슈
- 부트스트랩 루트키 운영 배포: 현재 fed-shared.key는 앵커 로컬 자동생성. 노드 enroll 시
같은 루트키를 안전채널로 노드에 전달해야 함(운영 절차 필요).
- gateway.yaml 미등록: :9160은 내부 포트. 외부 노출 시 메인세션이
crowny-ports.sh set 으로 등록.
- 빌드 환경 메모: crownyc.c가 TLS(SSLWrite 등) 의존 추가됨 →
cc -O2 -o crownyc crownyc.c -framework Security -framework CoreFoundation 로 빌드해야 링크됨.
- 테스트 중 라이브 chain에 검증블록(node-seoul/busan/legacy) 3개 append됨(모두 유효, corrupted:false).
append-only 정책상 truncate 안 함.