Harden worker federation and operator UI

This commit is contained in:
2026-07-29 13:30:55 +04:00
parent 95a96d87a5
commit 1ca9d64e89
35 changed files with 1195 additions and 581 deletions
+28
View File
@@ -141,6 +141,19 @@ func (s *Sessions) Valid(v string) bool {
return true
}
// Revoke removes one browser session. It is deliberately idempotent so a
// logout request remains safe after expiry or after a cookie was cleared by
// the browser.
func (s *Sessions) Revoke(v string) {
if v == "" {
return
}
sum := sha256.Sum256([]byte(v))
s.mu.Lock()
defer s.mu.Unlock()
delete(s.ids, hex.EncodeToString(sum[:]))
}
// HTTP enforces the same policy at the bus boundary. Authentication is
// optional for local development; when a token is supplied, control surfaces
// must present it as a Bearer token.
@@ -153,6 +166,21 @@ func HTTP(tokens map[Surface]string, next http.Handler) http.Handler {
// still has to present the token directly.
func HTTPWithSessions(tokens map[Surface]string, sessions *Sessions, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Federation has per-worker credentials, not one shared surface token.
// Let only its registration request and requests that name a worker
// reach their handlers; those handlers authenticate the admission token
// or worker token respectively. Without this exception, an authenticated
// worker is incorrectly treated as the default Web surface.
worker := r.Header.Get("X-Orchestra-Worker") != ""
federationRegistration := r.Method == http.MethodPost && r.URL.Path == "/v1/federation/workers"
workerPath := strings.HasPrefix(r.URL.Path, "/v1/federation/") ||
(r.Method == http.MethodGet && r.URL.Path == "/v1/tasks") ||
(r.Method == http.MethodPost && r.URL.Path == "/v1/artifacts") ||
(r.Method == http.MethodGet && strings.HasPrefix(r.URL.Path, "/v1/artifacts/"))
if federationRegistration || (worker && workerPath) {
next.ServeHTTP(w, r)
return
}
s := ParseSurface(r.Header.Get("X-Orchestra-Surface"))
if s == "" {
s = Web