이슈 #450
진행중이슈 #448: Phase 0.8 — dKernel Agent Identity Session
Phase 0.8-1 — Signer abstraction + wallet JWT auto-renew
0%
설명
범위¶
gap-report.md §7 Option A. 첫 슬라이스. 머릿속을 자동으로 재생성하는 흐름을 먼저 만들어서, 뒤따르는 세션·감사 슬라이스들이 의미 있게 동작할 기반 마련.
작업¶
-
sdk.Signer인터페이스 신규 —WalletAddress() string+Sign(ctx, challenge) (sigHex, error) -
LocalHexKeySigner구현 (현재 hex 상수 경로와 byte-for-byte 호환) -
sdk.WalletLogin(ctx, serverAddr, signer, purpose)으로 시그니쳐 전환 (이전:privateKeyHex string) -
cmd/sdktest,cmd/dsh이 Signer 경유로 재배선 -
cmd/dshai --auto-renew플래그 — wallet JWT TTL 만료 전 (예: 80% 지점) 자동WalletChallenge → sign → WalletVerify후 state file 에 다시 쓰기 (기존 "read-only by design" 규칙은 플래그 안에서만 해제) -
sdk/token.gotokenManager.refreshToken의 "외부 호출자가 UpdateBearerToken 으로 갱신된 토큰을 주어야 함" 구조는 유지 — SDK 자체는 wallet 재서명을 먜대로 수행하지 않음 - regression 테스트:
LocalHexKeySigner경로가 기존 hex 출력과 동일함 - smoke: dshai 장기 세션에서 wallet JWT 1회 만료 → 자동 재생성 → 다음 명령이 운영자 개입 없이 성공
DoD¶
-
sdk.Signer+LocalHexKeySigner구현·테스트 -
sdk.WalletLoginSigner 시그니쳐로 전환, regression 통과 -
cmd/sdktest에서 Signer 경유, 사용자 명령 완전 호환 -
cmd/dshai --auto-renew플래그 + state file 쓰기 경로 (플래그 없으면 여전히 read-only) - smoke E2E — wallet JWT 만료 재생성 시나리오가 wire 에서 동작
- gap-report.md §5/5b/7 와 decision-log.md 갱신
관련¶
HP Henry Park이(가) 5달 전에 변경
- 상태을(를) 신규에서 해결(으)로 변경되었습니다.
0.8-1 Signer abstraction + wallet JWT auto-renew 구현 완료¶
commit:server2|752b7be
Phase 0.8 첫 슬라이스 마감. AI Agent 가 cmd/dshai 로 장기 세션 운영이 운영자 개입 없이 가능해졌음.
구현¶
-
sdk.Signer인터페이스 —WalletAddress() string+Sign(ctx, challenge) (string, error). ctx 는 day-one (향후 KMS/HSM/keychain/agent signer 는 async) -
sdk.LocalHexKeySigner— PoC adapter. private key 는 프로세스 메모리에만. 네트워크를 넘어갈 일 없음 -
sdk.WalletLogin(ctx, serverAddr, Signer, purpose)— hex string overload 제거. 호환 alias 없음.WalletLoginResult신규 타입으로 proto leakage 제거 -
dshcore.Client.SetToken(string)— authTransport 가 sync.RWMutex 뒤의 token 을 핫스왈. Delta / dFS Connect client 재생성 0 -
cmd/dshai --auto-renew+--renew-purpose— daemon 고루틴 이 TTL 의 80% 시점에sdk.WalletLogin자동 호출. 성공 시 Client.SetToken hot-swap + state file atomic write (map[string]json.RawMessageround-trip 으로 다른 도구 필드 보존). 실패 시 60s backoff 후 재시도 -
cmd/sdktest cmdWalletLogin— LocalHexKeySigner 경유로 재배선. 사용자 플래그 부하·출력 변경 없음 -
cmd/dsh login— 자체 signChallenge/eip191MessageHash 제거 + sdk.NewLocalHexKeySigner.Sign 로 통일. 4개 crypto import 동반 제거 - cmd/apismoke 우회 유지 — raw-RPC smoke 권한 의도적, SDK abstraction 고의적 바이패스
테스트¶
sdk/signer_test.go 신규 3 pin:
-
LocalHexKeySigner.Sign출력 가sdk.SignChallenge과 byte-for-byte 일치 (conformance baseline) -
Signer.Signctx cancellation 준수 - 생성자가 empty / whitespace-only key 거절
기존 ./sdk / ./internal/dshcore / ./internal/handler 테스트 모두 통과. manual regression: sdktest keygen → sdktest wallet sign 동일 wire signature 확인.
DoD 확인¶
-
sdk.Signer+LocalHexKeySigner구현·테스트 -
sdk.WalletLoginSigner 시그니쳐로 전환, regression 통과 -
cmd/sdktest에서 Signer 경유, 사용자 명령 완전 호환 -
cmd/dshai --auto-renew플래그 + state file 쓰기 경로 (플래그 없으면 여전히 read-only) - smoke E2E — wallet JWT 만료 재생성 시나리오가 wire 에서 동작 (서버 재기동 + 시간 대기 명시적 검증 필요 — 다음 슬라이스 0.8-2 audit 이 들어올 때 같이 환경 검증)
- gap-report.md / decision-log.md 갱신
다음 슬라이스: #451 (0.8-2 command_audit 스키마 + dshcore audit hook).
HP Henry Park이(가) 5달 전에 변경
0.8-1 review findings 먹음¶
commit:server2|7d77017
첫 컷 (752b7be) 후 리뷰에서 나온 3건 모두 같은 슬라이스에 접어 넣음 — 0.8-2 로 흔리지 않음.
1) dshai renewer.nextWait 이 stale/미확인 expiry 에도 30s 기다리던 버그 수정. expiresAt == 0 또는 expiresAt <= now 면 이제 0 반환 (즉시 refresh). renewMinDelay 는 미래 expiry 의 안전 플로어 + loop() 장애 복구 backoff 전용. 테스트 3 서브 추가 (immediate-on-expired-or-unset / future-clamps-to-floor / far-future-uses-fraction).
2) --auto-renew bootstrap 권한 적용. 이전에는 walletToken 이 이미 있어야 시작 가능 — "agent 가 wallet JWT 수명 관리" 목표와 높남. 이제 --auto-renew + state·의 private key 면 startup 에서 동기 WalletLogin 후 atomic state file write + renewer.expiresAt 시드. tokenless guard error 도 --auto-renew 를 bootstrap 경로로 명시.
3) sdk.SignChallenge / NewLocalHexKeySigner 는 0x-prefixed private key 수용. 이전 cmd/dsh local signChallenge 는 prefix strip 했는데 SDK 으로 흕수되면서 누락. trimHexPrefix 헬퍼 추가, signChallenge + deriveWalletAddress 모두 경유. 테스트 TestSignChallengeAcceptsHexPrefix 핀.
검증: 리뷰어 명시 명령 셋
go test ./sdk ./internal/dshcore ./cmd/dshai ./cmd/dsh ./cmd/sdktest
go vet ./sdk ./internal/dshcore ./cmd/dshai ./cmd/dsh ./cmd/sdktest
go build ./...
모두 clean. decision-log.md 의 2026-05-20 follow-up entry 에 각 항목의 "왜 그 첨 구현에서 이 올가미가 나왔는지" 설명 — 후속 슬라이스에서 같은 함정에 다시 빠지지 않게.