Documentation
¶
Index ¶
- Constants
- Variables
- func Auth(s *store.Store, cfg *config.Config) func(http.Handler) http.Handler
- func DesktopShellAuth(cfg *config.Config) func(http.Handler) http.Handler
- func GetProjectID(ctx context.Context) string
- func GetProjectRole(ctx context.Context) string
- func GetSession(ctx context.Context) *model.Session
- func GetUser(ctx context.Context) *service.User
- func GetUserEmail(ctx context.Context) string
- func GetUserID(ctx context.Context) string
- func IsProjectAdmin(ctx context.Context) bool
- func IsProjectOwner(ctx context.Context) bool
- func OptionalAuth(s *store.Store, cfg *config.Config) func(http.Handler) http.Handler
- func ProjectMember(s *store.Store) func(http.Handler) http.Handler
- func SanitizedLogger(next http.Handler) http.Handler
- func ServiceProxy(provider sandbox.Provider, tracker ConnectionTracker) func(http.Handler) http.Handler
- func SessionBelongsToProject(s *store.Store) func(http.Handler) http.Handler
- type ConnectionTracker
Constants ¶
const ( UserKey contextKey = "user" UserIDKey contextKey = "userID" UserEmailKey contextKey = "userEmail" )
const ( ProjectIDKey contextKey = "projectID" ProjectRoleKey contextKey = "projectRole" )
const SessionKey contextKey = "session"
Variables ¶
var SensitiveQueryParams = []string{"token", "password", "api_key", "secret", "apiKey"}
SensitiveQueryParams are query parameters that should be redacted in logs
Functions ¶
func Auth ¶
Auth middleware validates user authentication. If auth is disabled (cfg.AuthEnabled == false), it uses the anonymous user.
func DesktopShellAuth ¶
DesktopShellAuth middleware validates the desktop shell secret from cookie or query string. Only active when cfg.DesktopMode is true. Rejects requests without valid secret with 401 Unauthorized. Checks both cookie and ?token= query parameter for flexibility with WebSocket/SSE.
Two paths are exempt from auth because they are called without a desktop shell session:
- MCP OAuth callbacks (/sessions/.../mcp/.../callback) — browser redirects from external OAuth servers that cannot carry the desktop shell session cookie.
- MCP token persistence (/api/projects/.../credentials/mcp) — POST from agent containers that have no access to the desktop shell session cookie.
func GetProjectID ¶
GetProjectID extracts project ID from context
func GetProjectRole ¶
GetProjectRole extracts project role from context
func GetSession ¶
GetSession extracts the session from context (set by SessionBelongsToProject middleware).
func GetUserEmail ¶
GetUserEmail extracts user email from context
func IsProjectAdmin ¶
IsProjectAdmin checks if user is project admin or owner
func IsProjectOwner ¶
IsProjectOwner checks if user is project owner
func OptionalAuth ¶
OptionalAuth middleware allows unauthenticated requests but adds user info if authenticated
func ProjectMember ¶
ProjectMember middleware validates project membership
func SanitizedLogger ¶
SanitizedLogger is a middleware that logs HTTP requests with sensitive query params redacted
func ServiceProxy ¶
func ServiceProxy(provider sandbox.Provider, tracker ConnectionTracker) func(http.Handler) http.Handler
ServiceProxy creates middleware that intercepts requests to service subdomains and proxies them to the agent-api's HTTP proxy endpoint using httputil.ReverseProxy.
Subdomain format: {session-id}-svc-{service-id}.{base-domain} Example: 01HXYZ123456789ABCDEFGHIJ-svc-myservice.localhost:3000
The proxy does NOT pass credentials to the agent-api, as service HTTP endpoints are considered public within the sandbox.
This properly handles: - HTTP/1.1 and HTTP/2 - WebSocket upgrades - Server-Sent Events (SSE) - Chunked transfer encoding - Request/response streaming
tracker, if non-nil, is notified for every proxied request (including long-lived connections such as SSE and WebSocket) so that the idle monitor can avoid shutting down sandboxes with live service-proxy connections.
func SessionBelongsToProject ¶
SessionBelongsToProject middleware validates that the session identified by the {sessionId} URL parameter belongs to the project identified by the {projectId} URL parameter (already validated and stored in context by ProjectMember). This prevents IDOR attacks where a user could access sessions from other projects by guessing session IDs.
Must be mounted inside a route that defines {sessionId}, e.g.:
r.Route("/{sessionId}", func(r chi.Router) {
r.Use(middleware.SessionBelongsToProject(s))
...
})
Types ¶
type ConnectionTracker ¶
type ConnectionTracker interface {
// Track registers an active connection for sessionID and returns a release
// function that must be called when the connection ends.
Track(sessionID string) func()
}
ConnectionTracker tracks active connections per session. Implementations must be safe for concurrent use.