items 5-7: passkey step-up, tools enable/disable, note RAG — end to end
Completes the three in-flight open items and fixes the away-fallthrough bug. Item 7 — passkey step-up (WebAuthn): - internal/webauthn: ES256/P-256 register + assert with real ecdsa signature verification, minimal CBOR/COSE decode, PasskeySession (L2→L3 on assert, decays after TTL). Drop the RS256 offer we can't verify (register-ok/ assert-fail trap). Verify rpIdHash + UP/UV flags in FinishAssertion — UV is the step-up gesture. Round-trip test with negative cases (tampered sig, missing UV, wrong origin). - cmd/mavweb: /auth/passkey enroll+assert page (the only surface that can do a WebAuthn gesture) + the four begin/finish endpoints. Without this the daemon's PasskeySession swap leaves /tools enable permanently blocked. - daemon wires PasskeySession as the auth Session + srv.StepUp; policy gates MethodAssertStepUp at AuthRead. Item 5 — tools page: DisableTool through store/ipc/client/wire; /tools grows a disable action and a link to the passkey page. Lifecycle test. Item 6 — note RAG: PhraseQuery on the phraser (LLM-composed answer over top-k notes, raw-notes fallback); IntentQuery routes through it. Stub returns a deterministic summary. Item 2 — away-fallthrough: on ErrVoiceNoSession the dispatcher now reroutes through the AWAY table (sev3→ntfy, sev4→telegram-repeat-til-ack, sev≤2→drop) instead of silently dropping / mis-routing to the present-list remainder. Covers DispatchNudge + DispatchReminder. 4 tests. Also: re-add ProposeTool to CoreAPI (dropped in a comment rewrite), fix missing imports + a duplicate block left mid-edit, drop dead AssertStepUpFunc, gitignore /mavcaldav. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-8
@@ -47,6 +47,7 @@ import (
|
||||
"github.com/kami/maven/internal/loop"
|
||||
"github.com/kami/maven/internal/phraser"
|
||||
"github.com/kami/maven/internal/store"
|
||||
"github.com/kami/maven/internal/webauthn"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -114,7 +115,7 @@ func run(args []string) error {
|
||||
defer phr.Close()
|
||||
|
||||
// ----- voice: reactive audio path (TCP listener + stt/router/tts) -----
|
||||
voiceW, err := wireVoice(cfg, ipc.NewStoreAPI(st))
|
||||
voiceW, err := wireVoice(cfg, ipc.NewStoreAPI(st), phr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("wire voice: %w", err)
|
||||
}
|
||||
@@ -169,13 +170,14 @@ func run(args []string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("ipc listen: %w", err)
|
||||
}
|
||||
// auth floor: any same-uid caller is fully trusted (FloorEnrollment +
|
||||
// FloorSession — L3, step-up satisfied). The cold-start unlock dance and a
|
||||
// real passkey Session are the open spec items; today the daemon runs
|
||||
// unlocked — plain sqlite, sqlcipher deferred. FloorSession keeps the floor
|
||||
// consistent so the authed mavweb /tools page can EnableTool (AuthStepUp)
|
||||
// against the local socket; the passkey verifier swaps FloorSession later.
|
||||
srv.Check = (&auth.Gate{Enrollment: auth.NewFloorEnrollment(), Session: auth.FloorSession{}}).Check
|
||||
// auth: Enrolled callers can assert step-up via MethodAssertStepUp (calls
|
||||
// Session.Assert). After a successful passkey assertion, the session bumps
|
||||
// to L3 for assertionTTL, enabling AuthStepUp methods (EnableTool).
|
||||
// FloorEnrollment still trusts same-uid callers; the passkey verifier
|
||||
// (WebAuthn) gates the session step-up, not the enrollment.
|
||||
passkeySess := webauthn.NewPasskeySession(5 * time.Minute)
|
||||
srv.Check = (&auth.Gate{Enrollment: auth.NewFloorEnrollment(), Session: passkeySess}).Check
|
||||
srv.StepUp = func(ctx context.Context) error { return passkeySess.Assert(ctx, auth.Scope{}) }
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
Reference in New Issue
Block a user