Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,27 +288,32 @@ func requireProxy(inLambda bool) func(http.Handler) http.Handler {
// reject rather than silently pass every request through.
if expected == "" {
log.Printf("mirrorstack: proxy guard rejected (token source configured but unreadable) from %s %s", r.RemoteAddr, r.URL.Path)
httputil.JSON(w, http.StatusForbidden, httputil.ErrorResponse{
Error: "request did not come through the platform proxy",
Code: CodeNotProxied,
})
rejectNotProxied(w)
return
}

token := r.Header.Get(header)
if !constantTimeEqual(token, expected) {
log.Printf("mirrorstack: proxy guard rejected (token mismatch, header_present=%v) from %s %s", token != "", r.RemoteAddr, r.URL.Path)
httputil.JSON(w, http.StatusForbidden, httputil.ErrorResponse{
Error: "request did not come through the platform proxy",
Code: CodeNotProxied,
})
rejectNotProxied(w)
return
}
next.ServeHTTP(w, r)
})
}
}

// rejectNotProxied writes the standard 403 not_proxied response. Both failure
// paths in requireProxy (unreadable token source and token mismatch) produce
// the same JSON body; the log call before each site carries the distinct
// diagnostic.
func rejectNotProxied(w http.ResponseWriter) {
httputil.JSON(w, http.StatusForbidden, httputil.ErrorResponse{
Error: "request did not come through the platform proxy",
Code: CodeNotProxied,
})
}

// secretReader returns the current secret, which header carries it, and
// whether a secret SOURCE is configured at all. The file-backed variant
// re-reads on every call so a refreshed token (CLI reconnect) is picked up
Expand Down
Loading