Help us shape the future of Go! Take the 2026 Go Developer Survey

serve

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 49 Imported by: 0

Documentation

Overview

appmode.go owns the app-window lifecycle: it counts the window's liveness stream and shuts the server down when the window is gone, so an app-mode server never outlives the UI it was opened for.

Design note: the liveness channel carries no server-side heartbeat ticker. The handler simply blocks until the client goes away or the server starts shutting down, which keeps "an idle server does nothing" literally true: the only timers are the two deadlines below, both armed only while app mode is actually running.

apptoken.go holds the one-time tokens that let an app-mode window log itself in. A token is 256 bits of crypto/rand, base64url encoded, lives in memory only, expires in a minute, and is destroyed the first time it is exchanged.

The token travels in a URL fragment, so it never reaches server logs or a Referer header. It is briefly visible in the browser's argv; single use and a short TTL are what make that acceptable.

Package serve implements `sift serve`: a local web server for the embedded Svelte single-page app, a browser alternative to the TUI picker.

Security is load-bearing here, not layered on. The rules, in brief:

  • loopback by default; anything else demands --allow-remote plus a full credential/TLS/host/root configuration, refused before binding;
  • token (local) or password (remote) auth with stateless signed cookies;
  • every client path is jailed to configured roots with symlink containment and a credential-directory denylist;
  • redaction defaults on and covers previews and output;
  • no CORS, strict security headers, Host/Origin/fetch-metadata checks;
  • idle means zero: no tickers, watchers, caches, or polling. The only exception is --app, where a client-held liveness connection decides when the server may exit; it is armed solely by a real app launch and carries no server-side heartbeat.

launch.go opens the serve UI in a chromeless app-mode window (Chromium `--app=`) for `sift serve --app`. Launching is best-effort by design: a missing browser or an unlaunchable process is never fatal, since the server stays useful through a normal browser or the printed URL.

Every OS touchpoint (PATH lookup, stat, env, process start) is injected so discovery and argument building are pure and testable on any platform.

Index

Constants

View Source
const DefaultListen = "127.0.0.1:7777"

DefaultListen is the fixed local port, keeping the browser origin stable.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Listen          string
	Roots           []string
	Deny            []string
	PasswordFile    string
	AllowRemote     bool
	TLSCert         string
	TLSKey          string
	TLSSelfSigned   bool
	BehindProxy     bool
	AllowedHosts    []string
	AllowUnredacted bool
	// AllowClone enables "clone a repository" in the web UI (needs system
	// git too). Off by default on every bind; without it the clone routes
	// are 404 and the UI hides every entry point.
	AllowClone   bool
	InsecureHTTP bool
	IdleTimeout  time.Duration
	Open         bool
	// App launches the UI in a chromeless browser window and, unless
	// KeepAlive is set, stops the server when that window goes away.
	App bool
	// KeepAlive suppresses the app-window shutdown (only meaningful with App).
	KeepAlive bool
	// EngineFlagOverrides carries operator-passed engine flags (name → value)
	// recorded before profile resolution. Each request re-applies them over
	// the target project's own .sift.toml, so CLI flag precedence holds
	// without the server's startup directory leaking into other projects.
	// Not a CLI flag.
	EngineFlagOverrides map[string]string
}

Config holds the `sift serve` flags. Durations and sizes follow the spec: fixed loopback port, explicit opt-ins for everything remote.

func (*Config) Validate

func (c *Config) Validate() (*auth.Auth, error)

Validate checks the remote refusal matrix before binding, naming the missing flag. It also resolves and validates the password source.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a configured `sift serve` instance. It holds no per-project state: the browser sends the selection with each request, and only the auth key plus small state-dir files live server-side.

func New

func New(cfg *Config, engineCfg *config.Config, log *slog.Logger) (*Server, error)

New validates the config (refusing bad remote setups before binding), builds the jail, and registers every route from one table.

func (*Server) Run

func (s *Server) Run() error

Run binds (refusing to start on any misconfiguration), prints the startup banner with the login URL, and serves until SIGINT/SIGTERM or the idle timeout. Missing web assets are checked before binding or printing any token.

Directories

Path Synopsis
Package auth holds the serve authentication primitives: startup token or configured password verification, stateless signed session cookies, and login throttling.
Package auth holds the serve authentication primitives: startup token or configured password verification, stateless signed session cookies, and login throttling.
Package jail resolves every client-supplied path against the configured roots.
Package jail resolves every client-supplied path against the configured roots.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL