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

config

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package config loads tailkeeper's gate configuration (spec §15).

In M1 the configuration holds contexts (tailnet ID plus read credential), local CLI settings, the MCP profile and audit settings. Unknown keys are rejected: a typo must never be silently ignored.

Index

Constants

View Source
const (
	PersonalDataMask = "mask"
	PersonalDataShow = "show"
)

Values of Config.PersonalData.

View Source
const (
	DefaultValidatePerMinute = 30
	MinValidatePerMinute     = 1
	MaxValidatePerMinute     = 120
)

The bounds of ACL.ValidatePerMinute.

View Source
const FileName = "config.hujson"

FileName is the configuration file inside a configuration directory.

View Source
const StrictModeEnforced = true

StrictModeEnforced reports whether CheckOwnership and CheckSecretFile verify ownership and permissions on this platform.

Variables

This section is empty.

Functions

func CheckOwnership

func CheckOwnership(path string, allowOwners ...int) error

CheckOwnership is the default Checker: path must be a regular file (not a symlink) and path and its directory must be owned by one of allowOwners and writable by neither group nor others.

func CheckSecretFile

func CheckSecretFile(path string) error

CheckSecretFile is stricter: owner-only permissions (no group or other access at all).

func OwnedBy added in v0.6.0

func OwnedBy(owners ...int) func(path string, opened os.FileInfo) error

OwnedBy returns the check for safefile.Options.Verify that holds a file to the rule CheckOwnership applies, on the file that was opened: fi is the open file's Stat, so what is judged is the file that is read, not whatever the path names a moment before or after. The file must be regular, and it and its directory must be owned by one of owners and writable by neither group nor others. Windows reads no owner; there it refuses a file that is not a regular one and nothing else.

func ReadSecretFile

func ReadSecretFile(path string) ([]byte, error)

ReadSecretFile is CheckSecretFile and the read in one step: the bytes come from the file that was checked. A file that is not there is the system's own error, with no code, so that the caller can name what to create and give it the code that fits (credential_unavailable, privacy_key_unavailable); a file that is there and cannot be inspected is config_unsafe.

Types

type ACL added in v0.6.0

type ACL struct {
	// InvariantsFile is the absolute path of the invariants file: tests every
	// validation must also pass (a HuJSON object with optional "tests" and
	// "sshTests"). Unset means no invariants. A set path that is missing or
	// unreadable fails every call that uses it; it is never taken for none.
	InvariantsFile string `json:"invariantsFile,omitempty"`
	// ValidatePerMinute is the process's own limit on the policy validation requests
	// tailkeeper decides to send, 1 to 120; a retry of a request takes no token. Unset
	// means DefaultValidatePerMinute.
	ValidatePerMinute *int `json:"validatePerMinute,omitempty"`
}

ACL configures the policy checks (acl validate, acl diff). The keys are read by 0.6.0 and later: a 0.5.0 binary refuses them as unknown (config_invalid), so they belong in a context only 0.6.0 uses.

func (ACL) ValidateRate added in v0.6.0

func (a ACL) ValidateRate() int

ValidateRate is the validation requests per minute this process decides to send.

type Audit

type Audit struct {
	Reads string `json:"reads,omitempty"` // "metadata" (default) or "none"
}

Audit configures tailkeeper's own audit log.

type Checker

type Checker func(path string, allowOwners ...int) error

Checker verifies that path is safe to load. allowOwners lists acceptable owner UIDs.

type Config

type Config struct {
	Contexts       map[string]Context `json:"contexts"`
	DefaultContext string             `json:"defaultContext,omitempty"`
	Local          Local              `json:"local,omitzero"`
	MCP            MCP                `json:"mcp,omitzero"`
	Audit          Audit              `json:"audit,omitzero"`
	ACL            ACL                `json:"acl,omitzero"`
	// PersonalData is "mask" (the default) or "show": whether tool results carry
	// login names, display names, email addresses and public IP addresses whole
	// (spec Appendix C).
	PersonalData string `json:"personalData,omitempty"`
}

Config is the decoded config.hujson.

func Parse

func Parse(data []byte) (Config, error)

Parse decodes HuJSON configuration bytes strictly and validates them.

func (Config) Validate

func (c Config) Validate() error

Validate checks every field that can be checked without touching the system.

type Context

type Context struct {
	TailnetID   string      `json:"tailnetId"`
	Credentials Credentials `json:"credentials"`
}

Context binds one tailnet to its credentials. It never carries gate settings.

type Credentials

type Credentials struct {
	Read Provider `json:"read"`
}

Credentials per class. M1 implements the read class only.

type Dirs

type Dirs struct {
	System string // root-owned gate configuration (wins outright when it has a config)
	User   string // personal-mode configuration
	State  string // plans and other state (later milestones)
	Logs   string // audit log
}

Dirs are the directories tailkeeper reads and writes.

func DefaultDirs

func DefaultDirs() (Dirs, error)

DefaultDirs returns the platform directories of spec §15.

type Loaded

type Loaded struct {
	Config            Config
	Source            Source
	Path              string
	Dirs              Dirs
	IgnoredUserConfig bool // a user config exists but the system config won (spec §15: no merging)
}

Loaded is a configuration together with where it came from.

func Load

func Load(d Dirs, check Checker) (*Loaded, error)

Load reads the configuration. When the system directory has a config file, it is the only configuration used; the user directory is ignored entirely.

func (*Loaded) Select

func (l *Loaded) Select(flagValue string, getenv func(string) string) (string, Context, error)

Select picks the context: the flag value, then TAILKEEPER_CONTEXT, then defaultContext, then the only context if there is exactly one.

type Local

type Local struct {
	TailscaleBinary   string   `json:"tailscaleBinary,omitempty"`
	Socket            string   `json:"socket,omitempty"`
	DNSQueryAllowlist []string `json:"dnsQueryAllowlist,omitempty"`
}

Local configures the local tailscale CLI tools.

type MCP

type MCP struct {
	Profile     string `json:"profile,omitempty"` // "reads" (default), "core", "full"
	EnableAlpha bool   `json:"enableAlpha,omitempty"`
}

MCP configures the stdio MCP server.

type Provider

type Provider struct {
	Provider  string   `json:"provider"`            // "env", "file", "exec" or "oidc"
	Command   []string `json:"command,omitempty"`   // exec: absolute wrapper argv, e.g. ["/path/to/wrapper","--env-file=/etc/tailkeeper/read.env","--"]
	Path      string   `json:"path,omitempty"`      // file: absolute path to a 0600 NAME=value file
	ClientID  string   `json:"clientId,omitempty"`  // oidc: federated identity client ID (not a secret)
	Audience  string   `json:"audience,omitempty"`  // oidc: defaults to api.tailscale.com/<clientId>
	TokenFile string   `json:"tokenFile,omitempty"` // oidc: file holding a platform identity token
}

Provider says where a credential comes from (spec §7.3).

type Source

type Source string

Source says which directory the configuration came from.

const (
	SourceSystem Source = "system"
	SourceUser   Source = "user"
)

Jump to

Keyboard shortcuts

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