Documentation
¶
Index ¶
- Constants
- Variables
- func BinaryName() string
- func CanonicalProviderPath(path string) string
- func Channel() string
- func ChannelLabel() string
- func DefaultDir() string
- func DefaultListenAddr() string
- func DefaultLocalRelayURL() string
- func DefaultRelayURL() string
- func LoadRemotes(dir string) (map[string]Remote, error)
- func PreviewProviderHome(stateDir string) string
- func ResolvePreviewProviderHome(stateDir string) (home string, bound bool, err error)
- func ResolveToolsDir(configDir, configured string) string
- func RetainContextConfig(next *WingConfig, current *ContextConfig)
- func SaveRemotes(dir string, remotes map[string]Remote) error
- func SaveWingConfig(dir string, cfg *WingConfig) error
- func StateDir() (string, error)
- func ToolNames(tools []*ToolConfig) []string
- func UpdateRemotes(dir string, update func(map[string]Remote) error) error
- func ValidateExports(dir string, cfg *WingConfig) error
- func ValidatePreviewListenAddr(addr string) error
- func ValidatePreviewRelay(raw string) error
- func ValidateRemoteName(name string) error
- func ValidateSSHTarget(target string) error
- func ValidateStateDirectory(dir string) error
- func ValidateWTBinary(binary string) error
- type AllowKey
- type Config
- type ContextConfig
- type DirectMCPConfig
- type ExportTarget
- type ICEServer
- type LocalOwner
- type MCPConfig
- func (p *MCPConfig) AllowedAny(roles []string, tool string) bool
- func (p *MCPConfig) EnabledAny(roles []string) bool
- func (p *MCPConfig) EnabledRoles(roles []string) []string
- func (p *MCPConfig) RolesForEmail(email string) []string
- func (p *MCPConfig) UnmarshalYAML(value *yaml.Node) error
- func (p *MCPConfig) Validate() error
- type MCPRoleConfig
- type PathEntry
- type PathList
- type RelayOwnerBinding
- type Remote
- type ToolConfig
- type ToolParam
- type WingConfig
Constants ¶
const ( HostedRelayAllow = "allow" HostedRelayDeny = "deny" ConversationsEnabled = "enabled" ConversationsDisabled = "disabled" )
const ProviderHomeBinding = ".provider-home"
ProviderHomeBinding is the optional host-selected file inside preview state that names an existing provider data home. It only relocates the credential namespace this state already uses; it grants no authority and carries no auth.
Variables ¶
var ReleaseChannel = "stable"
ReleaseChannel is set at build time. Renaming a stable binary never opts it into preview, and environment variables cannot switch an installed channel.
Functions ¶
func BinaryName ¶ added in v0.148.0
func BinaryName() string
func CanonicalProviderPath ¶ added in v0.148.0
func ChannelLabel ¶ added in v0.148.0
func ChannelLabel() string
func DefaultDir ¶ added in v0.148.0
func DefaultDir() string
func DefaultListenAddr ¶ added in v0.148.0
func DefaultListenAddr() string
func DefaultLocalRelayURL ¶ added in v0.148.0
func DefaultLocalRelayURL() string
func DefaultRelayURL ¶ added in v0.148.0
func DefaultRelayURL() string
func LoadRemotes ¶ added in v0.148.0
LoadRemotes is read-only, including when no registry has been created yet.
func PreviewProviderHome ¶ added in v0.148.0
PreviewProviderHome gives every entry point the same lexical credential namespace, including paths below macOS /tmp aliases. Validation is separate.
func ResolvePreviewProviderHome ¶ added in v0.148.0
ResolvePreviewProviderHome returns the provider data home for preview state. A missing binding selects exactly PreviewProviderHome(stateDir). A present binding is used only when fully valid; otherwise it fails closed and never falls back to the default namespace.
func ResolveToolsDir ¶ added in v0.140.0
ResolveToolsDir returns the configured privileged-tools directory, applying the same default and home expansion for both the wing and its remote MCP surface.
func RetainContextConfig ¶ added in v0.148.0
func RetainContextConfig(next *WingConfig, current *ContextConfig)
RetainContextConfig lets SIGHUP reload other settings without changing the credentials or secret masks of surviving sessions.
func SaveRemotes ¶ added in v0.148.0
SaveRemotes replaces the registry atomically with an owner-only, synced file.
func SaveWingConfig ¶ added in v0.34.0
func SaveWingConfig(dir string, cfg *WingConfig) error
SaveWingConfig writes wing.yaml to dir. The file may contain the roost's JWT signing key, so it must never be readable by other local users.
func StateDir ¶ added in v0.148.0
StateDir resolves without creating or changing any files. Preview refuses overlapping stable paths, including aliases through existing symlinks.
func ToolNames ¶ added in v0.130.0
func ToolNames(tools []*ToolConfig) []string
ToolNames returns just the tool names from a slice of configs.
func UpdateRemotes ¶ added in v0.148.0
UpdateRemotes holds a process-wide filesystem lock through read/modify/write, so concurrent add/rm commands cannot overwrite each other's changes.
func ValidateExports ¶ added in v0.148.0
func ValidateExports(dir string, cfg *WingConfig) error
ValidateExports verifies that export destinations stay isolated from both Wingthing state and configured workspaces. Call it on every live snapshot before using an export target; wing.yaml can also be mutated while the daemon is running.
func ValidatePreviewListenAddr ¶ added in v0.148.0
func ValidatePreviewRelay ¶ added in v0.148.0
The first preview is personal localhost/SSH dogfooding. It cannot enroll in an organization or contact a shared/hosted coordinator, even if a config or environment variable was copied accidentally. SSH-native control is separate.
func ValidateRemoteName ¶ added in v0.148.0
func ValidateSSHTarget ¶ added in v0.148.0
func ValidateStateDirectory ¶ added in v0.148.0
ValidateStateDirectory runs before mkdir/chmod, daemon inspection, or auth loading. Legacy stable directories remain compatible. Preview only adopts an empty directory or a directory already marked preview; it never migrates data.
func ValidateWTBinary ¶ added in v0.149.0
ValidateWTBinary accepts a POSIX absolute executable path or a bare command name. Shell syntax and control characters are forbidden even though callers must also quote the executable when building an SSH command.
Types ¶
type AllowKey ¶ added in v0.34.0
type AllowKey struct {
Key string `yaml:"key,omitempty"` // base64 raw P-256 public key (optional)
UserID string `yaml:"user_id,omitempty"` // relay user ID
Email string `yaml:"email,omitempty"` // auto-set from relay, for display
}
AllowKey is an allowed user for wing access control.
type Config ¶
type Config struct {
Dir string `yaml:"-"`
DefaultAgent string `yaml:"default_agent"`
DefaultEmbedder string `yaml:"default_embedder"`
WingID string `yaml:"wing_id"`
Hostname string `yaml:"-"` // os.Hostname(), not persisted
PollInterval string `yaml:"poll_interval"`
DefaultMaxRetries int `yaml:"max_retries"`
RoostURL string `yaml:"roost_url"`
Vars map[string]string `yaml:"vars"`
// contains filtered or unexported fields
}
func (*Config) PromptsDir ¶ added in v0.144.0
func (*Config) ProviderDataHome ¶ added in v0.148.0
ProviderDataHome is the preview provider data home validated by Load, including any ProviderHomeBinding. A Config not produced by Load has no binding and uses the default location below its state directory.
func (*Config) RelayDBPath ¶ added in v0.16.1
func (*Config) ResolveVars ¶
type ContextConfig ¶ added in v0.148.0
type ContextConfig struct {
URL string `yaml:"url"`
ClientID string `yaml:"client_id"`
SecretFile string `yaml:"secret_file"`
Scopes []string `yaml:"scopes,omitempty"`
}
ContextConfig enrolls the wing as an impersonation client. Only the wing reads SecretFile.
func FreezeContextConfig ¶ added in v0.148.0
func FreezeContextConfig(dir string, c *ContextConfig) (*ContextConfig, func())
func LoadContextConfig ¶ added in v0.148.0
func LoadContextConfig(dir string) (*ContextConfig, error)
func (*ContextConfig) Validate ¶ added in v0.148.0
func (c *ContextConfig) Validate() error
type DirectMCPConfig ¶ added in v0.145.0
type DirectMCPConfig struct {
Disabled bool `yaml:"disabled,omitempty"`
AllowGrants []string `yaml:"allow_grants,omitempty"`
DenyGrants []string `yaml:"deny_grants,omitempty"`
MaxSessions int `yaml:"max_sessions,omitempty"`
MaxSpawnsPerHour int `yaml:"max_spawns_per_hour,omitempty"`
}
DirectMCPConfig optionally narrows the built-in native direct-control policy. A missing direct_mcp section preserves the compatible default operation set and bounded quotas. Operators can disable the surface, select an allow/deny subset of grant names, or override the positive bounds without configuring every user.
func (*DirectMCPConfig) UnmarshalYAML ¶ added in v0.145.0
func (p *DirectMCPConfig) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML decodes the security-sensitive direct policy strictly even though wing.yaml remains permissive at its compatibility-oriented top level.
func (*DirectMCPConfig) Validate ¶ added in v0.145.0
func (p *DirectMCPConfig) Validate() error
Validate rejects ambiguous grant policy and nonsensical resource bounds. Grant existence is checked against the direct operation registry by the wing so the low-level config package does not own a second grant catalog.
type ExportTarget ¶ added in v0.148.0
type ExportTarget struct {
Name string `yaml:"name" json:"name"`
Path string `yaml:"path" json:"-"`
Members []string `yaml:"members,omitempty" json:"-"`
}
ExportTarget is an administrator configured folder destination. Every exported file is placed in a caller-specific subdirectory below Path. Members is an explicit email allowlist; an empty allowlist grants no access so a newly added destination cannot accidentally become org-wide.
type ICEServer ¶ added in v0.108.0
type ICEServer struct {
URLs []string `yaml:"urls" json:"urls"`
Username string `yaml:"username,omitempty" json:"username,omitempty"`
Credential string `yaml:"credential,omitempty" json:"credential,omitempty"`
}
ICEServer is a STUN/TURN server configuration for WebRTC P2P connections.
type LocalOwner ¶ added in v0.149.0
type LocalOwner struct {
ID string `yaml:"id"`
Bindings []RelayOwnerBinding `yaml:"relay_bindings,omitempty"`
}
LocalOwner is the personal wing's durable authority. Relay enrollment adds an explicit binding; it never replaces ID or rewrites existing egg ownership.
func BindLocalOwnerRelay ¶ added in v0.149.0
func BindLocalOwnerRelay(dir, relayURL, userID string) (*LocalOwner, error)
BindLocalOwnerRelay is an explicit, locally administered enrollment step. Merely loading a device credential does not grant its account this binding.
func EnsureLocalOwner ¶ added in v0.149.0
func EnsureLocalOwner(dir, legacyUserID string) (*LocalOwner, error)
EnsureLocalOwner seeds an older account-backed wing with its existing owner, or creates an account-free identity. An existing identity always wins.
func (*LocalOwner) OwnerForRelay ¶ added in v0.149.0
func (o *LocalOwner) OwnerForRelay(relayURL, userID string) string
OwnerForRelay normalizes authenticated authority at the relay adapter only. Unbound accounts retain their own identity and cannot inherit local eggs.
type MCPConfig ¶ added in v0.140.0
type MCPConfig struct {
Enabled bool `yaml:"enabled"`
DefaultAllowAll bool `yaml:"default_allow_all"`
Roles map[string]*MCPRoleConfig `yaml:"roles"`
}
MCPConfig configures the OAuth-gated MCP endpoint exposed by a roost.
func (*MCPConfig) AllowedAny ¶ added in v0.140.0
AllowedAny implements maximum-subset semantics: a tool is visible when any one of the caller's MCP-enabled roles allows it. Disabled roles contribute neither grants nor denies.
func (*MCPConfig) EnabledAny ¶ added in v0.140.0
EnabledAny reports whether at least one of the caller's roles enables MCP.
func (*MCPConfig) EnabledRoles ¶ added in v0.140.0
EnabledRoles removes memberships that do not participate in the MCP surface.
func (*MCPConfig) RolesForEmail ¶ added in v0.140.0
RolesForEmail returns every configured role an email belongs to in name order.
func (*MCPConfig) UnmarshalYAML ¶ added in v0.140.0
UnmarshalYAML keeps wing.yaml backwards-compatible at the top level while decoding the security-sensitive MCP section strictly. A typo in enabled/allow/deny must fail closed.
type MCPRoleConfig ¶ added in v0.140.0
type MCPRoleConfig struct {
Enabled bool `yaml:"enabled"`
Allow []string `yaml:"allow,omitempty"`
Deny []string `yaml:"deny,omitempty"`
Members []string `yaml:"members,omitempty"`
}
MCPRoleConfig controls which privileged tools one role may use over the remote MCP surface. It does not affect tools available to in-wing agents.
type PathEntry ¶ added in v0.56.0
type PathEntry struct {
Path string `yaml:"path" json:"path"`
Members []string `yaml:"members,omitempty" json:"members,omitempty"`
}
PathEntry is a directory path with optional per-folder member ACLs. When Members is nil/empty, the path is visible to all authenticated users (legacy behavior). When Members is set, only those emails + owner/admin can access the path.
type PathList ¶ added in v0.56.0
type PathList []PathEntry
PathList is a list of PathEntry values that supports mixed YAML formats: plain strings ("~/repos") and mappings ({path: ~/repos, members: [...]}).
func (PathList) MarshalYAML ¶ added in v0.56.0
MarshalYAML serializes PathList: entries without members become plain strings (backwards compat).
func (PathList) PathsForUser ¶ added in v0.56.0
PathsForUser returns paths accessible to the given email/orgRole. Owner/admin get all paths. Members get only entries where their email is in Members (case-insensitive) or where Members is empty/nil (legacy open entries).
type RelayOwnerBinding ¶ added in v0.149.0
type Remote ¶ added in v0.148.0
type Remote struct {
SSHTarget string `yaml:"ssh_target" json:"ssh_target"`
WTBinary string `yaml:"wt_binary,omitempty" json:"wt_binary,omitempty"`
WingthingDir string `yaml:"wingthing_dir,omitempty" json:"wingthing_dir,omitempty"`
WingID string `yaml:"wing_id,omitempty" json:"wing_id,omitempty"`
ControlSocket string `yaml:"control_socket,omitempty" json:"control_socket,omitempty"`
ControlVersion string `yaml:"control_version,omitempty" json:"control_version,omitempty"`
}
type ToolConfig ¶ added in v0.130.0
type ToolConfig struct {
Name string `yaml:"name"`
Description string `yaml:"description,omitempty"`
Params []ToolParam `yaml:"params,omitempty"`
Run string `yaml:"run,omitempty"`
Context string `yaml:"context,omitempty"`
Env map[string]string `yaml:"env,omitempty"`
Timeout string `yaml:"timeout,omitempty"`
MaxConcurrent int `yaml:"max_concurrent,omitempty"`
}
ToolConfig defines a privileged tool that the wing daemon can execute on behalf of sandboxed agents.
func LoadToolsDir ¶ added in v0.130.0
func LoadToolsDir(dir string) ([]*ToolConfig, error)
LoadToolsDir reads all .yaml files from dir and returns parsed tool configs. Returns nil (no error) if dir doesn't exist. Warns on world-readable files.
func LoadWingTools ¶ added in v0.148.0
func LoadWingTools(dir string, c *ContextConfig) ([]*ToolConfig, error)
LoadWingTools validates the cross-file dependency without reading credentials.
func (*ToolConfig) TimeoutDuration ¶ added in v0.130.0
func (t *ToolConfig) TimeoutDuration() time.Duration
TimeoutDuration parses the Timeout field as a time.Duration. Returns 0 if empty or unparseable.
type ToolParam ¶ added in v0.140.0
type ToolParam struct {
Name string `yaml:"name" json:"name"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Type string `yaml:"type,omitempty" json:"type,omitempty"`
Required bool `yaml:"required,omitempty" json:"required,omitempty"`
Enum []string `yaml:"enum,omitempty" json:"enum,omitempty"`
Examples []any `yaml:"examples,omitempty" json:"examples,omitempty"`
}
ToolParam optionally describes one positional tool argument as a named MCP parameter. Params remain ordered: the MCP adapter maps named arguments back to argv in this order so the existing tool runner and egg socket stay backwards-compatible.
type WingConfig ¶ added in v0.34.0
type WingConfig struct {
WingID string `yaml:"wing_id"`
Label string `yaml:"label,omitempty"` // display name shown in the web UI
Roost string `yaml:"roost,omitempty"`
Org string `yaml:"org,omitempty"`
Paths PathList `yaml:"paths,omitempty"`
Root string `yaml:"root,omitempty"` // compat: folded into Paths on load
Labels []string `yaml:"labels,omitempty"`
EggConfig string `yaml:"egg_config,omitempty"`
Conv string `yaml:"conv,omitempty"`
Audit bool `yaml:"audit,omitempty"`
Debug bool `yaml:"debug,omitempty"`
AllowUnsandboxed bool `yaml:"allow_unsandboxed,omitempty"` // personal local MCP may request the outer host boundary
Locked bool `yaml:"locked,omitempty"` // explicit lock mode toggle
Spectate bool `yaml:"spectate,omitempty"` // allow spectator (read-only) session viewing
AuthTTL string `yaml:"auth_ttl,omitempty"` // passkey auth token duration (default "1h")
AllowKeys []AllowKey `yaml:"allow_keys,omitempty"`
Admins []string `yaml:"admins,omitempty"` // emails with admin role (see all sessions, all paths)
Exports []ExportTarget `yaml:"exports,omitempty"` // explicitly allowed browser export destinations
IdleTimeout string `yaml:"idle_timeout,omitempty"` // kill sessions idle for this long (e.g. "4h")
ConnectionMode string `yaml:"connection_mode,omitempty"` // "relay" (default), "p2p", "p2p_only", "direct"
HostedRelay string `yaml:"hosted_relay,omitempty"` // "allow" (default) or "deny"
Conversations string `yaml:"conversations,omitempty"` // opt-in stable host mailbox: "enabled" or "disabled" (default)
// P2P / Direct mode settings
ICEServers []ICEServer `yaml:"ice_servers,omitempty"` // STUN/TURN servers for WebRTC
DirectPort int `yaml:"direct_port,omitempty"` // port for direct WebSocket connections
DirectTLS bool `yaml:"direct_tls,omitempty"` // enable TLS for direct mode
// JWT signing key for roost mode (base64-DER P-256 private key).
// Auto-generated on first roost start. Server mode uses WT_JWT_KEY env instead.
JWTKey string `yaml:"jwt_key,omitempty"`
// ToolsDir is the directory containing privileged tool YAML configs.
// Defaults to ~/.wingthing/tools/ if empty.
ToolsDir string `yaml:"tools_dir,omitempty"`
Context *ContextConfig `yaml:"context,omitempty"`
// MCP is the optional OAuth-gated remote surface over privileged tools.
MCP *MCPConfig `yaml:"mcp,omitempty"`
DirectMCP *DirectMCPConfig `yaml:"direct_mcp,omitempty"`
}
WingConfig holds wing-specific settings persisted in ~/.wingthing/wing.yaml.
func LoadWingConfig ¶ added in v0.34.0
func LoadWingConfig(dir string) (*WingConfig, error)
LoadWingConfig reads wing.yaml from dir. If the file doesn't exist, it returns a zero-value config (no error). If a legacy wing-id file exists, the wing_id is seeded from it.
func (*WingConfig) Clone ¶ added in v0.145.0
func (c *WingConfig) Clone() *WingConfig
Clone returns an independent runtime snapshot. Wing callbacks outlive config reloads, so sharing slice/map storage would let a SIGHUP or ACL mutation race an already admitted session.
func (*WingConfig) EffectiveHostedRelay ¶ added in v0.145.0
func (c *WingConfig) EffectiveHostedRelay() string
EffectiveHostedRelay returns the additive hosted relay policy. Empty means allow so existing wing.yaml files retain their current behavior.
func (*WingConfig) ExportsForUser ¶ added in v0.148.0
func (c *WingConfig) ExportsForUser(email, _ string) []ExportTarget
ExportsForUser returns only destinations explicitly granted to this caller.
func (*WingConfig) HostedRelayAllowed ¶ added in v0.145.0
func (c *WingConfig) HostedRelayAllowed() bool
func (*WingConfig) IsAdmin ¶ added in v0.63.0
func (c *WingConfig) IsAdmin(email string) bool
IsAdmin returns true if email is in the Admins list (case-insensitive).