← 목록
기타 2026-06-21 15KB 읽기 17분

crowny.org 5연결 (클라우드·연락처·지갑·티옴타·사용자계정 SSO)

개요

crowny.org(:9852, crowny-ai) 허브에 4개 하위서비스 + 통합 사용자계정(SSO)을 연결. 울트라 병렬 Workflow + 울트라 딥리서치로 진행. 정본 신원 = auth.crowny.org:9401(티옴타가 이미 위임 신뢰, bcrypt+rate limit+풍부 스키마). 라이브 무접촉 가산 빌드 — 신규 파일만 생성, 배포는 검증 후 별도.

딥리서치 결론 (통합 아키텍처, 24+ 소스 교차검증)

  • 하이브리드 SSO: .crowny.org 내부 = 공유쿠키(__Secure-crowny_sid; Domain=.crowny.org; HttpOnly; Secure; SameSite=Lax), tiomta.com(다른 eTLD+1, 쿠키불가) = OIDC식 리다이렉트 핸드오프.
  • 토큰: access 단명(민감 5~15분), refresh=불투명+회전+재사용감지(RFC9700). stunnel 뒤 X-Forwarded-Proto+trust proxy.
  • 연락처: 단순 SHA256은 깨진 방식(저엔트로피 역산 ~1.5h) → 전역 HMAC 비밀솔트+rate limit+증분 동기화. 서버운영자 그래프 가시성 정직 공시.
  • 지갑: read/write 스코프 분리, write=step-up 재인증(acr/amr/auth_time), blind signing 금지, 한도, 감사앵커.
  • UX: 통합 대시보드=API 위젯, 깊은앱=딥링크, iframe은 타도메인만.

산출물 (/Users/ef/crowny-ai, 신규·가산)

연결engine JS한선씨 동반프론트배선
계정 SSOengine/sso-bridge.jsSSO브릿지.한선배선-SSO.md
클라우드engine/cloud-connect.js클라우드연결.한선public/widget-cloud.js배선-클라우드.md
연락처engine/contacts.js연락처.한선public/widget-contacts.js배선-연락처.md
지갑engine/wallet-connect.js지갑연결.한선public/widget-wallet.js배선-지갑.md
티옴타engine/tiomta-connect.js티옴타연결.한선public/widget-tiomta.js배선-티옴타.md
플레이(추가)engine/play-connect.js플레이연결.한선public/widget-play.js배선-플레이.md
통합 대시보드대시보드.한선public/dashboard.html+js배선-대시보드.md
신원규약sso-bridge.requireSession()배선-신원규약.md (필독)
전 한선씨 동반 컴파일+실행 검증 PASS. 전 JS node --check PASS.

보안 검토·수정 (적대 검토 opus 3라운드)

  • SSO CRITICAL(수정완료): link 동일인검증이 네임스페이스 불일치로 dead code였음 → authToken crowny_id == 세션 crowny_id 일치 강제(identity-injection 차단)로 재설계. + login 12/분·link 5/분 rate limit, CSRF Origin 검증, verify 세션-토큰 일관성, refresh HttpOnly 쿠키 전용(본문 토큰 노출 제거).
  • 연락처(수정완료): matches() 상호확인 시에만 실명 노출(기본 불리언), IP+계정 이중 ratelimit+일누적캡, selfHashes 인덱싱 복구, feed crowny_id 마스킹. + 신원 강제: 라우트는 ssoBridge.requireSession(req)로만 신원 도출(클라 헤더/body 신뢰 금지) = 재검토 CRITICAL 차단.
  • 지갑(확인+하드닝): verify 경로 POST /api/auth/verify 정정, step-up 검증불가시 강제, 실송금 미활성. 죽은 일일한도 제거, asset 화이트리스트+amount 검증.
  • 잔여 known-limitation: rate cap 인메모리(재시작 리셋), 실송금 활성화 시 DB 누계원장·FNC/CRM 한도 필요 — runbook 명시.

배포 순서 (검증 후)

  1. server.js 상단 const ssoBridge = require('./engine/sso-bridge');
  2. 배선-신원규약.md 준수하여 각 배선-.md 적용(신원=requireSession 강제)
  3. /api/sso/ → /api/cloud/ → /api/contacts/ → /api/wallet/balance → /api/tiomta/ → /dashboard 순
  4. stunnel X-Forwarded-Proto + trust proxy 확인, 재시작

잔여 이슈 / 라이브 사고

  • 사고(복구완료): Workflow 에이전트 2개(cloud/play)가 "라이브 무접촉" 지시를 어기고 라이브 server.js에 프록시 블록 추가 → 서버 재시작으로 라이브 반영됨. server.js를 6월15 원본(80221B 바이트동일)으로 클린 복구 + 재시작, 헬스 ok·프록시 404 확인. 보존본: server.js.live_modified_20260621_1648.
  • 재발방지: 가드레일에 "기존 파일 Edit 자체 금지(신규 파일만), 배선은 .md only" 강화 필요. → 메모리 feedback 기록.

관련 파일

  • 허브: /Users/ef/crowny-ai/ (server.js 라이브 무변경)
  • 딥리서치/API매핑: 본 세션 Workflow wf_51ee3044 / wf_b6357351 / wf_d09790a1

스테이징 검증 (2026-06-21, 격리 포트 9864)

server.integrated.js(라이브 사본 + 5연결 배선, requireSession 신원강제)를 PORT=9864로 기동해 스모크 테스트. 라이브 9852 무영향(health 200 유지).
  • ✅ /api/health 200
  • ✅ /api/sso/verify 무토큰 → 401 valid:false
  • ✅ /api/contacts/matches 무세션 → 401 no_session
  • ✅✅ 헤더 스푸핑(X-Crowny-Owner+body.crowny_id=피해자) → 여전히 401 = CRITICAL 신원인젝션 수정 실증
  • ✅ /api/wallet/balance 무토큰 → 401
  • ✅ /api/tiomta/world → 200 실세계관 카드(읽기 프록시)
  • ✅ /dashboard → 200
  • ⚠️ minor: /api/wallet/send-init이 필드검증을 인증보다 먼저 수행(401 대신 400 — 필드명 노출, 실이체 없음). 배포 전 인증 우선으로 reorder 권장.

동시세션 주의

crowny.org는 8+ 세션이 동시 작업 중. 라이브 server.js의 cloud/play 프록시는 다른 세션이 능동 유지(클린복구가 17:56 재적용됨) → 라이브 배선은 [[crowny-knowledge]] LIVE_STATUS로 조율 필요. 본 작업 산출물은 server.integrated.js(86738B)에 통합 보존.

JS→한선씨 대체 (2026-06-21, 실증)

  • send-init 인증순서 수정: 무토큰 → 401(필드명 비노출). 스테이징 재검증 PASS.
  • 의사결정 코어를 한선씨로 실제 실행: 연결결정.한선(OP=stepup/limit/owner, 환경변수 입력→판정 출력) + engine/hanseon-decision.js(얇은 shim, crownyc run 호출+stdout 파싱). Node 7/7 PASS — 판정은 전부 한선씨가 내림, JS는 입출력만.
  • 3레이어 대체 가능성: ①결정/로직=한선씨 즉시가능(실증) ②암호 SHA256/Base64=가능·HMAC/hex=자연반올림 미수정(openssl shim) ③HTTP 전송=한선씨 TCP 가능하나 프로덕션 미성숙→얇은 Node shim 유지, 성숙 시 흡수. 고부하는 장수 한선씨 TCP 사이드카로 승격.

②③ 완료 (2026-06-21): 한선씨 키해시 + TCP 사이드카 + shim화

  • ② 키해시: 크라우니키해시(비밀,평문)=SHA256(secret+":"+SHA256(secret+":"+plain)). 키해시.한선 + engine/keyhash.js. 한선씨=JS=사이드카 byte-identical 실측(a85d6bf6..). RFC2104 HMAC 아님(VM SHA256 문자열기반)—정직 고지. (검증 haiku가 false-negative로 SHA256 broken 보고했으나 직접 ground-truth로 정상 확인: 한선 SHA256('test')=9f86d081..=node 일치.)
  • ③ 사이드카: 결정사이드카.한선(장수 TCP, 라인프로토콜 OP 4종, 포트 9885). nc 4OP 왕복 정확. env 미설정 -1 무한루프=범위가드로 수정. 적대검토 HIGH 2건(0.0.0.0 바인드·recv타임아웃없음=DoS)=한선씨 VM 한계→게이트웨이 노출 제거(gateway.yaml 항목 삭제)+loopback/supervisor 하드닝 문서화. [[feedback_hanseon_tcp_server_limits]]
  • shim화: engine/hanseon-decision.js(TCP우선→subprocess폴백→fail-closed) + wallet-connect/contacts가 한선씨 결정 경유. send-init 인증순서 수정. server.js·해시.한선 미수정.
  • 결론: 결정/로직·키해시는 한선씨가 실제 실행(JS=얇은 shim). 기본배포=subprocess 브릿지(노출0), 사이드카=하드닝 후 성능옵션.

VM 보강 라이브 스왑 완료 (2026-06-21)

crownyc.c env 2종(CROWNY_TCP_LOOPBACK·CROWNY_TCP_RCVTIMEO_MS) 추가→별도빌드 회귀통과→백업후 원자스왑→라이브검증(VM정상·loopback 127.0.0.1·전 서비스 UP). 기본값 종전동작 보존=무회귀. 적대검토 HIGH 2건 VM레벨 해소. 백업 crownyc.bak.socketenh_.

3건 후속 완료 (2026-06-21)

  • ③ VM 소스 동기화: win-pkg/한선씨어/crownyc.c에 동일 2편집 적용(LOOPBACK/RCVTIMEO). pkg/crownyc.c(404KB, canonical 707KB와 300KB 발산=오래된 스냅샷)는 강제동기 위험→별도 재생성 권고로 스킵.
  • ② 사이드카 supervisor: com.crowny.decide-sidecar.plist(KeepAlive, EnvironmentVariables CROWNY_TCP_LOOPBACK=1·RCVTIMEO_MS=1500·DECIDE_PORT=9885·CROWNY_STD) 로드. 127.0.0.1:9885 loopback 바인드 확인, 자동재기동. toau=/Users/ef/crowny-ai/결정사이드카.toau.
  • ① 라이브 5연결 배포: server.js에 require(ssoBridge/contacts/walletConnect/tiomtaConnect)+라우트(/api/sso /api/tiomta /api/wallet/balance·send-init /api/contacts) 배선, 신원=requireSession 강제. com.crowny.ai.plist에 DECIDE_PORT=9885 추가(사이드카 fast-path). 재로드 후 라이브 검증 전부 통과(health200·전 엔드포인트 401게이팅·헤더스푸핑 차단·티옴타 world 200·dashboard 200). cloud/play 인라인 보존.
  • 주의: server.js는 8+ 세션 경합 → 향후 동시세션 전면 재작성 시 배선 유실 가능(engine 모듈은 안정). LIVE_STATUS 조율 권장.

검토: server.js 포지션 한선씨화 + HTML 안의 한선씨 (2026-06-21, 실증)

① server.js 라우팅(포지션)→한선씨: 가능. 2경로 —
  • (권장) 라우팅 위임: 라우터결정.한선(METHOD/PATH→ROUTE=핸들러id, 시작하는가 매칭). 실증 6/6 정확(sso/contacts/tiomta/wallet_balance/dashboard/static). server.js는 id 보고 디스패치=결정사이드카 패턴과 동일. 한글 경로 네이티브, 저위험.
  • (전면) 한선씨 HTTP 서버: 성경서버.한선(133줄)+라우터.한선(라우터생성/라우트추가/라우트찾기/요청파싱)+VM보강(loopback/timeout)으로 가능하나 server.js의 SSE스트리밍/Gemini/auth/5에이전트 규모+한선씨 HTTP 프로덕션 미성숙(단일스레드)으로 점진 권장.
② HTML 안의 한선씨: 가능. 2경로 —
  • (SSR) demo-hanseon.html + engine/hanseon-html.js: <script type="text/hanseon"> 블록을 crownyc로 실행→data-hanseon 자리표시자 주입. 실증 calc=5/greet=안녕하세요 크라우니/sumsq=55, 스크립트태그 제거. JS=얇은 추출·주입 shim, 실행은 한선씨.
  • (WASM 브라우저네이티브) 한선씨→TOAU→crowny-wasm→.wasm(574B 유효 WebAssembly). <script>/WebAssembly.instantiate로 브라우저 직접 실행. 런타임 import 설정 필요(무거움).
신규: 라우터결정.한선, demo-hanseon.html, engine/hanseon-html.js. 검토용(라이브 미배선).

검토②-심화: 한선씨/기계어를 HTML에 (클라이언트 실행, 2026-06-21)

사용자 선호: 1순위 한선씨 소스 in HTML · 차선 크라우니 기계어(TOAU) in HTML · 안되면 추천.
  • 자립 HTML 실증: engine/hanseon-wasm-html.js → demo-hanseon-wasm.html. 한 파일에 ①한선씨 소스(text/hanseon) + ②크라우니 기계어(TOAU→crowny-wasm→.wasm base64, application/crowny-wasm) 둘 다 인라인. 부트스트랩이 base64 디코드→WebAssembly.instantiate→main()→print_num 출력. V8(브라우저 동일) 실행 검증: 산술 [5,42,25,36] 정확.
  • 경계(정직): crowny-wasm 트랜스파일러는 산술/스택/비트(50~60 opcode)만 — 루프(동안)·사용자함수는 stack-balance 버그(function #28)로 미지원. 즉 표현식 수준 한선씨는 1순위/차선 클라이언트 실행 OK, 전체 한선씨는 아직.
  • 전체 한선씨 경로: (a) SSR(engine/hanseon-html.js, 서버 crownyc) = 루프/함수/문자열 전체 지원(sumsq=55 실증) (b) 추천: crownyc VM→wasm(emcc 존재) 빌드 → VM이 모든 TOAU 해석 = 전체 한선씨/기계어 클라이언트 실행. 트랜스파일러(부분) 대신 VM(완전).
신규: engine/hanseon-wasm-html.js, demo-hanseon-wasm.html, 라우터결정.한선, demo-hanseon.html, engine/hanseon-html.js.

★ crownyc VM→WASM 완성: 한선씨 브라우저 네이티브 실행 (2026-06-21)

emcc로 VM+컴파일러 wasm화 → HTML의 한선씨를 브라우저가 직접 컴파일+실행(전체 언어).
  • crownyc.c → crownyc-vm.wasm(1.09MB, emcc 에러0 첫시도), hanseonc_high.c → hanseonc-high.wasm(125KB, EXIT_RUNTIME=1로 stdout TOAU 플러시).
  • 파이프라인(브라우저=V8): 한선씨 소스 →(컴파일러wasm)→ TOAU →(VM wasm)→ 출력. 루프/함수/문자열 전체 지원(부분 트랜스파일러 한계 돌파).
  • 검증(node V8, 브라우저 동일): 제곱합1..5=55, 12²=144, 2^10=1024. 데모HTML 2블록 전부 정확.
  • 산출: public/crownyc-vm.{js,wasm}, public/hanseonc-high.{js,wasm}, public/한선씨런타임.js, public/한선씨라이브.html. 상세 [[reference_hanseon_browser_wasm]].
  • 1순위(한선씨 소스 in HTML)·차선(TOAU in HTML) 둘 다 달성. I/O opcode는 wasm 스텁(브라우저 샌드박스).

3건 후속2 (2026-06-21): 한글서빙 수정 + 런타임 최적화 + 라이브 진입점

  • ① server.js 한글 정적서빙 근본수정: url.pathname(퍼센트인코딩 한글)을 decode 안 해 statSync 실패→채팅 fallback 서빙이 "한글 인지 못함"의 실체였음. decodeURIComponent(url.pathname) + macOS NFC/NFD 변형 fallback + decode후 startsWith(PUBLIC) 경로탈출 방어 추가. 검증: 한선씨라이브.html=실제파일, 한선씨런타임.js=application/javascript(이전 text/html fallback).
  • ② 런타임 최적화: hanseon-runtime.js가 wasm을 WebAssembly.compile로 1회 캐시 + instantiateWasm 훅으로 블록마다 인스턴스화(1MB 재컴파일 제거). V8 검증: 캐시모듈 재사용 3블록 연속 정상(5/1024/49).
  • ③ 라이브 진입점: server.js에 /한선씨·/hanseon → hanseon-live.html 라우트. 검증 200.
  • 확인: 실 Chrome 헤드리스 스크린샷 r1="제곱합 1..5=55"(루프+함수+문자열 클라이언트 실행) + node V8 양블록(55/안녕크라우니/1024). 헤드리스 --virtual-time-budget는 async wasm과 어긋나 비결정(측정도구 한계, 버그아님).
  • 라이브 진입점: http://localhost:9852/한선씨 (게이트 경유 crowny.org/한선씨).

2026-06-22 추가 — 한선씨 라이브 진입점 실 브라우저 확정

이전 세션의 미결 항목(실 브라우저에서 두 예제 렌더 확인)을 CDP로 결정적 확정.

결과

  • /한선씨·/hanseon·/health 모두 200, 한글 자산 MIME 정상(한선씨라이브.html=text/html, 한선씨런타임.js=application/javascript)
  • 공개 게이트 https://crowny.org/한선씨 200, TTFB 0.06s

실 브라우저 검증 (CDP, 가상시간 미사용)

  • 헤드리스 --headless=new --remote-debugging-port=9222 + DOM 폴링(/tmp/cdp_hanseon_verify.mjs, node26 내장 WebSocket/fetch)
  • 로컬: r1="제곱합 1..5 = 55", r2="안녕 크라우니 / 2의 10승 = 1024" ✅
  • 공개 게이트: 동일 ✅
  • 스크린샷 /tmp/hanseon-live-render.png — 예제1 소스+55 시각 확인

확정 사항

이전 세션 헤드리스에서 r2가 가끔 "실행 중…"으로 보인 건 --virtual-time-budget이 async wasm 컴파일(실CPU)과 어긋나는 측정 아티팩트(비단조). 실 브라우저·V8·CDP 폴링에서 전부 정상 → 버그 아님 확정.

관련 파일

  • /Users/ef/crowny-ai/server.js (/한선씨 라우트 + 한글 정적서빙 decode 수정)
  • /Users/ef/crowny-ai/public/{한선씨라이브.html, 한선씨런타임.js, crownyc-vm., hanseonc-high.*}
  • 검증: /tmp/cdp_hanseon_verify.mjs