diff --git a/workspace-server/internal/handlers/discovery.go b/workspace-server/internal/handlers/discovery.go index 2e66a0cd..d8edf814 100644 --- a/workspace-server/internal/handlers/discovery.go +++ b/workspace-server/internal/handlers/discovery.go @@ -358,12 +358,14 @@ func validateDiscoveryCaller(ctx context.Context, c *gin.Context, workspaceID st tok := wsauth.BearerTokenFromHeader(c.GetHeader("Authorization")) if tok == "" { // Canvas hits this endpoint via session cookie, not bearer token. - // Add verifiedCPSession() as a fallback after the bearer check so - // SaaS canvas Peers tab doesn't 401. Self-hosted workspaces are - // unaffected — they have no CP session cookie. - if ok2, presented2 := middleware.VerifiedCPSession(c.GetHeader("Cookie")); ok2 { - return nil - } else if presented2 { + // verifiedCPSession returns (valid, presented): + // - (false, false) = no cookie, 401 + // - (true, true) = valid session, allow + // - (false, true) = cookie presented but invalid, 401 + if ok, presented := middleware.VerifiedCPSession(c.GetHeader("Cookie")); presented { + if ok { + return nil + } c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid session"}) return errors.New("invalid session") }