mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-14 00:16:38 +00:00
fix: use agent_key instead of UUID for session tool authorization (#573)
Session tools (sessions_list, session_status, sessions_history, sessions_send) were using resolveAgentIDString(ctx) which returns the agent UUID, but session keys are built using agent_key. This caused all session tool operations to fail silently or return "access denied" for every channel. Replace resolveAgentIDString() with ToolAgentKeyFromCtx() in all four session tools. Add fail-closed guard for empty agent key.
This commit is contained in:
1 parent
bb5647aaa8
commit
33f975edf0
4 files changed
+24
-17
No files matched your search
@@ -58,11 +58,12 @@ func (t *SessionsListTool) Execute(ctx context.Context, args map[string]any) *Re
|
||||
activeMinutes = int(v)
|
||||
}
|
||||
|
||||
agentID := resolveAgentIDString(ctx)
|
||||
if agentID == "" {
|
||||
// Session keys use agent_key (e.g. "agent:victoria:..."), not UUID.
|
||||
agentKey := ToolAgentKeyFromCtx(ctx)
|
||||
if agentKey == "" {
|
||||
return ErrorResult("agent context required")
|
||||
}
|
||||
sessions := t.sessions.List(ctx, agentID)
|
||||
sessions := t.sessions.List(ctx, agentKey)
|
||||
|
||||
// Filter by active_minutes
|
||||
if activeMinutes > 0 {
|
||||
@@ -145,12 +146,13 @@ func (t *SessionStatusTool) Execute(ctx context.Context, args map[string]any) *R
|
||||
return ErrorResult("session_key is required (could not detect current session)")
|
||||
}
|
||||
|
||||
// Security: validate session belongs to current agent (fail-closed)
|
||||
agentID := resolveAgentIDString(ctx)
|
||||
if agentID == "" {
|
||||
// Security: validate session belongs to current agent (fail-closed).
|
||||
// Session keys use agent_key (e.g. "agent:victoria:..."), not UUID.
|
||||
agentKey := ToolAgentKeyFromCtx(ctx)
|
||||
if agentKey == "" {
|
||||
return ErrorResult("agent context required")
|
||||
}
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentID+":") {
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentKey+":") {
|
||||
return ErrorResult("access denied: session belongs to a different agent")
|
||||
}
|
||||
|
||||
|
||||
@@ -70,12 +70,13 @@ func (t *SessionsHistoryTool) Execute(ctx context.Context, args map[string]any)
|
||||
|
||||
includeTools, _ := args["include_tools"].(bool)
|
||||
|
||||
// Security: validate session belongs to current agent (fail-closed)
|
||||
agentID := resolveAgentIDString(ctx)
|
||||
if agentID == "" {
|
||||
// Security: validate session belongs to current agent (fail-closed).
|
||||
// Session keys use agent_key (e.g. "agent:victoria:..."), not UUID.
|
||||
agentKey := ToolAgentKeyFromCtx(ctx)
|
||||
if agentKey == "" {
|
||||
return ErrorResult("agent context required")
|
||||
}
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentID+":") {
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentKey+":") {
|
||||
return ErrorResult("access denied: session belongs to a different agent")
|
||||
}
|
||||
|
||||
|
||||
@@ -69,15 +69,16 @@ func (t *SessionsSendTool) Execute(ctx context.Context, args map[string]any) *Re
|
||||
return ErrorResult("either session_key or label is required")
|
||||
}
|
||||
|
||||
// Security: fail-closed when agentID missing
|
||||
agentID := resolveAgentIDString(ctx)
|
||||
if agentID == "" {
|
||||
// Security: fail-closed when agent key missing.
|
||||
// Session keys use agent_key (e.g. "agent:victoria:..."), not UUID.
|
||||
agentKey := ToolAgentKeyFromCtx(ctx)
|
||||
if agentKey == "" {
|
||||
return ErrorResult("agent context required")
|
||||
}
|
||||
|
||||
// Resolve by label if needed
|
||||
if sessionKey == "" && label != "" {
|
||||
sessions := t.sessions.List(ctx, agentID)
|
||||
sessions := t.sessions.List(ctx, agentKey)
|
||||
for _, s := range sessions {
|
||||
if s.Label == label {
|
||||
sessionKey = s.Key
|
||||
@@ -90,7 +91,7 @@ func (t *SessionsSendTool) Execute(ctx context.Context, args map[string]any) *Re
|
||||
}
|
||||
|
||||
// Security: validate target session belongs to same agent
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentID+":") {
|
||||
if !strings.HasPrefix(sessionKey, "agent:"+agentKey+":") {
|
||||
return ErrorResult("access denied: target session belongs to a different agent")
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,10 @@ func agentCtx(agentID string) context.Context {
|
||||
if err != nil {
|
||||
return ctx
|
||||
}
|
||||
return store.WithAgentID(ctx, uid)
|
||||
ctx = store.WithAgentID(ctx, uid)
|
||||
// Session keys use agent_key, not UUID. In production WithToolAgentKey
|
||||
// is set by the agent loop; tests must mirror this.
|
||||
return WithToolAgentKey(ctx, agentID)
|
||||
}
|
||||
|
||||
func agentCtxWithSandbox(agentID, sandboxKey string) context.Context {
|
||||
|
||||
Reference in new issue
Block a user