remote

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package remote adds an OPT-IN, TLS-only network bridge on top of zero's local daemon (internal/daemon). It lets a remote client drive the SAME daemon SessionManager/Pool over the network, behind bearer-token authentication and a protocol-version floor. The local Unix-socket daemon is unchanged and remains the default; nothing here activates unless `zero daemon serve-remote` is run.

Security (fail closed):

  • TLS is mandatory; the bridge refuses to serve without a cert/key.
  • A connection is authenticated BEFORE any control frame is dispatched; a failed/absent token closes the connection (after a small backoff) and no session frame is ever processed.
  • Tokens are compared in constant time and are never logged.
  • The control-frame size cap and version negotiation from internal/daemon are reused unchanged; oversize/old-version handshakes are rejected.
  • A remote-driven session runs through the same daemon dispatch, so it stays under the same sandbox + risk model — remote never bypasses local controls.

Index

Constants

View Source
const (
	EnvToken     = "ZERO_DAEMON_REMOTE_TOKEN"
	EnvTokenFile = "ZERO_DAEMON_REMOTE_TOKEN_FILE"
)

Env vars the bridge reads for its bearer token.

View Source
const (
	ModeSession = "session"
	ModeBundle  = "bundle"
)

Connection modes negotiated in the auth handshake. The default (empty) is a daemon session, preserving the original behavior; "bundle" requests a one-shot git-bundle upload instead of a session.

Variables

View Source
var ErrUnauthorized = errors.New("remote: unauthorized")

ErrUnauthorized is returned when a token does not match.

Functions

func DialRemote

func DialRemote(cfg RemoteConfig) (*daemon.Client, error)

DialRemote establishes a verified TLS connection to a remote bridge, authenticates with the bearer token, and returns a daemon.Client ready for Run/Attach/Status — the same client the local socket uses, so remote and local share one protocol. The server certificate is always verified (never InsecureSkipVerify).

func ServerTLSConfig

func ServerTLSConfig(certFile, keyFile string) (*tls.Config, error)

ServerTLSConfig builds a server TLS config from a cert/key pair, refusing if either is missing (TLS is mandatory for the remote bridge).

func TokenFromEnv

func TokenFromEnv() (string, error)

TokenFromEnv resolves the bridge token from EnvToken, or a file named by EnvTokenFile. It never logs the token.

Types

type Attestation

type Attestation interface {
	Verify(meta map[string]string) error
}

Attestation is an optional post-token hook (e.g. workload attestation). The default is a no-op; a deployment can supply a stricter implementation.

type Authenticator

type Authenticator interface {
	Authenticate(token string) error
}

Authenticator verifies a bearer token presented by a remote client.

type Bridge

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

Bridge serves authenticated remote connections and drives the local daemon's control dispatch for each one.

func NewBridge

func NewBridge(opts BridgeOptions) (*Bridge, error)

NewBridge validates options and builds a Bridge.

func (*Bridge) Close

func (b *Bridge) Close() error

Close stops the listener started by ListenAndServeTLS, causing Serve to return. Safe to call before serving or more than once.

func (*Bridge) ListenAndServeTLS

func (b *Bridge) ListenAndServeTLS(addr string, tlsConfig *tls.Config) error

ListenAndServeTLS binds a TLS listener on addr and serves until the listener is closed (via Close). It refuses to serve without a TLS config (no plaintext remote bridge).

func (*Bridge) Serve

func (b *Bridge) Serve(listener net.Listener) error

Serve accepts connections from listener until it returns an error (e.g. it is closed). Each connection is authenticated, then handed to the daemon's control dispatch. Connections beyond MaxConnections are refused immediately.

type BridgeOptions

type BridgeOptions struct {
	// Server is the local daemon to drive (required).
	Server *daemon.Server
	// Authenticator verifies bearer tokens (required).
	Authenticator Authenticator
	// Attestation is an optional post-token hook; nil => no-op.
	Attestation Attestation
	// MinVersion is the lowest control-protocol version accepted; 0 =>
	// daemon.ProtoVersion.
	MinVersion int
	// MaxConnections bounds concurrent remote connections; 0 => default.
	MaxConnections int
	// HandshakeTimeout bounds the auth handshake; 0 => default.
	HandshakeTimeout time.Duration
	// AuthFailDelay slows brute-force attempts; <0 => none, 0 => default.
	AuthFailDelay time.Duration
	// BundleDir is the directory under which uploaded git bundles are extracted
	// into per-link working trees. Empty disables bundle uploads entirely (a
	// bundle-mode connection is then refused — opt-in, fail closed).
	BundleDir string
	// MaxBundleBytes caps a single uploaded bundle; 0 => default.
	MaxBundleBytes int64
	Log            func(string)
}

BridgeOptions configures a Bridge.

type RemoteConfig

type RemoteConfig struct {
	// Address is host:port of the remote bridge (required).
	Address string
	// Token is the bearer token (required).
	Token string
	// CACertFile, when set, is the only CA trusted for the server cert (use for a
	// self-signed bridge). Empty => system roots. InsecureSkipVerify is never used.
	CACertFile string
	// ServerName overrides the TLS/SNI verification name; empty => host of Address.
	ServerName string
	// Timeout bounds the dial + auth handshake; 0 => default.
	Timeout time.Duration
}

RemoteConfig configures a remote dial.

type SessionLink struct {
	// Address is host:port of the remote bridge.
	Address string `json:"address"`
	// ServerName overrides TLS/SNI verification; empty => host of Address.
	ServerName string `json:"server_name,omitempty"`
	// CACertFile is the CA trusted for the bridge cert (for a self-signed bridge).
	CACertFile string `json:"ca_cert_file,omitempty"`
	// LinkID is the per-link identifier (a single path component on the remote).
	LinkID string `json:"link_id"`
	// RemotePath is the extracted working tree on the remote; use it as --cwd for
	// a remote run/attach against the linked repo.
	RemotePath string `json:"remote_path"`
	// BundleSHA256 is the hex SHA-256 of the uploaded bundle, for verification.
	BundleSHA256 string `json:"bundle_sha256,omitempty"`
}

SessionLink records the association between a local repo and the remote working tree a bundle upload produced. It carries everything needed to reach the linked repo again — the bridge address, TLS verification details, the link id, and the extracted remote path — except the bearer token, which is always supplied separately (never persisted to the link file).

func LoadSessionLink(path string) (*SessionLink, error)

LoadSessionLink reads and validates a link file written by Save.

func UploadRepoBundle

func UploadRepoBundle(cfg RemoteConfig, repoDir, linkID string) (*SessionLink, error)

UploadRepoBundle creates a git bundle of repoDir's full history and uploads it to the remote bridge over an authenticated, bundle-mode TLS connection. The bridge extracts it into a per-link working tree and returns its path, captured in the returned SessionLink. repoDir must be a git work tree.

func (SessionLink) Save

func (l SessionLink) Save(path string) error

Save writes the link to path as pretty JSON with 0600 permissions, atomically (write-temp-then-rename) so a reader never sees a partial file.

func (SessionLink) Validate

func (l SessionLink) Validate() error

Validate checks the fields required to use a link.

type TokenAuthenticator

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

TokenAuthenticator compares a presented token against a fixed secret in constant time.

func NewTokenAuthenticator

func NewTokenAuthenticator(token string) (*TokenAuthenticator, error)

NewTokenAuthenticator builds a token authenticator, refusing an empty secret (fail closed — a bridge must never accept everyone).

func (*TokenAuthenticator) Authenticate

func (a *TokenAuthenticator) Authenticate(token string) error

Authenticate reports nil when token matches the configured secret.

Jump to

Keyboard shortcuts

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