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

tinfoilconfig

package module
v0.1.18 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

README

tinfoil-config

Canonical Go types and validation for the measured Tinfoil workload YAML format.

Go API

cfg, err := tinfoilconfig.Decode(data, tinfoilconfig.Options{})

Use HostDebugMode for trusted debug-toolbox configuration. It permits the reserved toolbox's runtime socket mounts; all other validation still applies.

CLI

go run ./cmd/tinfoil-config config.yml

The command exits non-zero and prints the schema or policy violation for invalid input.

Model grants

containers[].models grants isolated named model mounts. Encrypted models require an explicit grant; plaintext models without grants use shared mounts.

Local attestation

containers[].attestation: true grants access to the local attestation socket. Access defaults to false.

GPU security

security.allow-unencrypted-nvlink permits multi-GPU Hopper workloads (H100 and H200), whose NVLink traffic is unencrypted. It defaults to false. The CVM enforces this measured policy before enabling GPUs and starting workloads; opting in keeps GPU, NVSwitch, and topology attestation checks enabled.

gpus: 8
security:
  allow-unencrypted-nvlink: true

CVM administration

containers[].cvm_admin: true grants administration of the entire CVM, including other workloads and their secrets. The profile uses UID/GID 0, privileged execution, and no-new-privileges disabled. The rootfs is writable unless read_only: true is set. Admin access does not enable debug mode.

Admin containers use declared bridge networks and ports. Writable layers and Docker state are ephemeral across CVM reboot; declared volumes provide persistent storage.

Direct SSH

Direct SSH requires cvm-network.inbound-ports to include 22 and one container publishing guest port 22 on an attached network. For example, ports: ["22:2223"] exposes a non-root SSH server listening on container port 2223. It does not grant cvm_admin or change the container's user or privileges. The existing AdminSSH(cfg) helper returns that mapping, or nil when none is enabled; its name is retained for compatibility. Other published ports remain private, and the debug toolbox suppresses the production SSH mapping.

Attested boot keys

Declare keys and assign each to a container:

attested-keys:
  - id: host-ssh
    key: ecdsa-p256
containers:
  - name: workspace
    keys: [host-ssh]
    # Image and other required configuration omitted.

Supported algorithms are ecdsa-p256, ed25519, and x25519 (key agreement). Up to 32 keys can be declared, each with exactly one container grant. IDs match ^[a-z][a-z0-9-]{0,62}$; tls and hpke are reserved. Optional numeric uid and gid default to 0 and range from 0 to 65534.

Each grant provides read-only files at /run/tinfoil/keys/<id>/: owner-only private_key.pem (PKCS#8) and public_key.pem (SPKI). A parent /run tmpfs is allowed; mounts overlapping the key subtree are rejected. Keys last for one CVM boot, surviving container and shim restarts. V3 attestation endorses their public SPKI under the declared ID. Applications handle protocol-specific formats.

Documentation

Overview

Package tinfoilconfig defines and validates the measured Tinfoil workload configuration format.

Index

Constants

View Source
const (
	ReservedDebugContainerName = "tinfoil-debug-toolbox"
	ReservedDebugPort          = "2222/tcp"
	ReservedDebugHostPort      = 2222
	AttestedKeysContainerDir   = "/run/tinfoil/keys"
	KeyECDSAP256               = "ecdsa-p256"
	KeyEd25519                 = "ed25519"
	KeyX25519                  = "x25519"
)
View Source
const (
	MaxModelDisks   = 24
	MaxAttestedKeys = 32
)
View Source
const AdminSSHGuestPort = 22
View Source
const MaxConfigBytes = 1 << 20
View Source
const MinVolumeSize = 64 << 20

MinVolumeSize is the smallest volume a config may declare: dm-integrity and ext4 need room for their own metadata before any file fits.

Variables

This section is empty.

Functions

func HasReservedDebugContainer

func HasReservedDebugContainer(config *Config) bool

func ModelIsIsolated added in v0.1.3

func ModelIsIsolated(config *Config, name string) bool

func ParseSize added in v0.1.10

func ParseSize(text string) (int64, error)

ParseSize converts a size such as "30GiB", "16TB", "1.5T" or "512m" to bytes. The unit is required, the number may carry a decimal fraction, and the result must be a whole multiple of 512 bytes of at least MinVolumeSize.

func ReservedDebugRuntimeEnabled

func ReservedDebugRuntimeEnabled(containerName string, options Options) bool

func ShimUpstreamSet

func ShimUpstreamSet(config *Config) bool

func Validate

func Validate(config *Config, options Options) error

func ValidateAttestedKeys added in v0.1.13

func ValidateAttestedKeys(config *Config) error

ValidateAttestedKeys checks declarations, exclusive grants, ownership and generated mount destinations. It is also used by the boot key store before deriving filesystem paths from a config.

func ValidateBytes

func ValidateBytes(data []byte, options Options) error

Types

type AdminSSHMapping added in v0.1.13

type AdminSSHMapping struct {
	Container     string
	GuestPort     int
	ContainerPort int
}

AdminSSHMapping identifies the direct SSH mapping. The legacy name does not imply administrator privileges.

func AdminSSH added in v0.1.13

func AdminSSH(config *Config) (*AdminSSHMapping, error)

AdminSSH resolves an explicitly allowed guest port 22 to its container port. SSH exposure is independent of cvm_admin. Callers must use a validated config and suppress this mapping in the debug-toolbox profile.

type AttestedKey added in v0.1.13

type AttestedKey struct {
	ID  string `yaml:"id" json:"id"`
	Key string `yaml:"key" json:"key"`
	UID int    `yaml:"uid,omitempty" json:"uid"`
	GID int    `yaml:"gid,omitempty" json:"gid"`
}

AttestedKey declares a boot-generated key. The runtime exports PKCS#8 private and SPKI public PEM, and endorses full public SPKI DER in v3 attestation. UID and GID are measured numeric file ownership, defaulting to root.

type CVMNetworkConfig

type CVMNetworkConfig struct {
	InboundPorts []int `yaml:"inbound-ports"`
}

type Config

type Config struct {
	CVMVersion   string                  `yaml:"cvm-version"`
	ShimRaw      yaml.Node               `yaml:"shim"`
	ShimCfg      *ShimConfig             `yaml:"-"`
	CVMNetwork   CVMNetworkConfig        `yaml:"cvm-network"`
	Networks     map[string]*NetworkSpec `yaml:"networks"`
	CPUs         int                     `yaml:"cpus"`
	Memory       int                     `yaml:"memory"`
	GPUs         int                     `yaml:"gpus"`
	Security     SecurityConfig          `yaml:"security,omitempty"`
	Models       []ModelSpec             `yaml:"models"`
	Volumes      []VolumeSpec            `yaml:"volumes"`
	AttestedKeys []AttestedKey           `yaml:"attested-keys,omitempty"`
	Containers   []Container             `yaml:"containers"`
	KeyserverURL string                  `yaml:"keyserver-url,omitempty"`
}

func Decode

func Decode(data []byte, options Options) (*Config, error)

type Container

type Container struct {
	Name              string            `yaml:"name"`
	Image             string            `yaml:"image"`
	CVMAdmin          bool              `yaml:"cvm_admin,omitempty"` // Delegates administration of the entire CVM.
	SealRegister      bool              `yaml:"seal_register,omitempty"`
	Attestation       bool              `yaml:"attestation,omitempty"`
	Command           []string          `yaml:"command,omitempty"`
	Entrypoint        []string          `yaml:"entrypoint,omitempty"`
	WorkingDir        string            `yaml:"working_dir,omitempty"`
	User              string            `yaml:"user,omitempty"`
	Env               []interface{}     `yaml:"env,omitempty"`
	Secrets           []string          `yaml:"secrets,omitempty"`
	Models            []string          `yaml:"models,omitempty"`
	Keys              []string          `yaml:"keys,omitempty"`
	Volumes           []string          `yaml:"volumes,omitempty"`
	PersistentVolumes []string          `yaml:"persistent_volumes,omitempty"`
	Devices           []string          `yaml:"devices,omitempty"`
	CapAdd            []string          `yaml:"cap_add,omitempty"`
	Runtime           string            `yaml:"runtime,omitempty"`
	Networks          []string          `yaml:"networks,omitempty"`
	Ports             []string          `yaml:"ports,omitempty"`
	IPC               string            `yaml:"ipc,omitempty"`
	PidMode           string            `yaml:"pid,omitempty"`
	GPUs              interface{}       `yaml:"gpus,omitempty"`
	ShmSize           string            `yaml:"shm_size,omitempty"`
	Memory            string            `yaml:"memory,omitempty"`
	CPUs              float64           `yaml:"cpus,omitempty"`
	Tmpfs             map[string]string `yaml:"tmpfs,omitempty"`
	ReadOnly          *bool             `yaml:"read_only,omitempty"`
	PidsLimit         *int64            `yaml:"pids_limit,omitempty"`
	Restart           string            `yaml:"restart,omitempty"`
	StopSignal        string            `yaml:"stop_signal,omitempty"`
	StopTimeout       *int              `yaml:"stop_timeout,omitempty"`
	Healthcheck       *Healthcheck      `yaml:"healthcheck,omitempty"`
	// contains filtered or unexported fields
}

func (*Container) UnmarshalYAML

func (c *Container) UnmarshalYAML(node *yaml.Node) error

type Healthcheck

type Healthcheck struct {
	Test        []string `yaml:"test"`
	Interval    string   `yaml:"interval,omitempty"`
	Timeout     string   `yaml:"timeout,omitempty"`
	Retries     int      `yaml:"retries,omitempty"`
	StartPeriod string   `yaml:"start_period,omitempty"`
}

func (*Healthcheck) UnmarshalYAML

func (h *Healthcheck) UnmarshalYAML(node *yaml.Node) error

type ModelSpec

type ModelSpec struct {
	Name      string `yaml:"name,omitempty"`
	Repo      string `yaml:"repo,omitempty"`
	MPK       string `yaml:"mpk,omitempty"`
	MWP       string `yaml:"mwp,omitempty"`
	EMWP      string `yaml:"emwp,omitempty"`
	KeySecret string `yaml:"key-secret,omitempty"`
	// Weights are never programs, so a pack is noexec unless declared otherwise.
	Exec bool `yaml:"exec,omitempty"`
	// Schema is the pack schema the pinned artifact was built with (0 = schema 1,
	// the original layout). Declarative for now; no consumer reads it yet.
	Schema int `yaml:"schema,omitempty"`
}

type NetworkSpec

type NetworkSpec struct {
	Egress string   `yaml:"egress"`
	Allow  []string `yaml:"allow"`
}

func (*NetworkSpec) UnmarshalYAML

func (n *NetworkSpec) UnmarshalYAML(node *yaml.Node) error

type Options

type Options struct {
	Mode ValidationMode
}

type PortMapping added in v0.1.4

type PortMapping struct {
	Host      int
	Container int
}

func ParsePorts added in v0.1.4

func ParsePorts(ports []string) ([]PortMapping, error)

ParsePorts parses compose-style "<host>:<container>" entries, so no host-IP prefix, no ranges, no /udp suffix.

type SecurityConfig added in v0.1.18

type SecurityConfig struct {
	AllowUnencryptedNVLink bool `yaml:"allow-unencrypted-nvlink,omitempty"`
}

type ShimConfig

type ShimConfig struct {
	UpstreamPort      int      `yaml:"upstream-port"`
	UpstreamContainer string   `yaml:"upstream-container,omitempty"`
	Paths             []string `yaml:"paths"`
	OriginDomains     []string `yaml:"origins"`

	TLSMode          string `yaml:"tls-mode" default:"cert-proxy"`
	TLSEnv           string `yaml:"tls-env" default:"production"`
	TLSChallengeMode string `yaml:"tls-challenge" default:"dns"`
	TLSWildcard      bool   `yaml:"tls-wildcard" default:"false"`
	TLSOwnSANDomain  bool   `yaml:"tls-own-san-domain" default:"false"`

	ControlPlane           string    `yaml:"control-plane" default:"https://api.tinfoil.sh"`
	ATC                    string    `yaml:"atc" default:"https://atc.tinfoil.sh"`
	Authenticated          bool      `yaml:"authenticated" default:"false"`
	AuthenticatedEndpoints *[]string `yaml:"authenticated-endpoints"`
	RateLimit              float64   `yaml:"rate-limit"`
	RateBurst              int       `yaml:"rate-burst"`
	Email                  string    `yaml:"email" default:"tls@tinfoil.sh"`
	PublishAttestation     bool      `yaml:"publish-attestation" default:"true"`
	DummyAttestation       bool      `yaml:"dummy-attestation" default:"false"`
	ExpectedGPUs           int       `yaml:"expected-gpus" default:"0"`
}

func DecodeShim

func DecodeShim(node *yaml.Node) (*ShimConfig, error)

func (*ShimConfig) Validate

func (c *ShimConfig) Validate() error

type ValidationMode

type ValidationMode uint8

ValidationMode selects which producer is allowed to construct the config. WorkloadMode is for user-supplied measured YAML. HostDebugMode is only for YAML after tinfoild has injected its reserved debug toolbox.

const (
	WorkloadMode ValidationMode = iota
	HostDebugMode
)

type VolumeOverlay added in v0.1.8

type VolumeOverlay struct {
	Model  string `yaml:"model"`
	Source string `yaml:"source"`
	Target string `yaml:"target"`
}

VolumeOverlay stacks a model pack under a writable directory on the volume: Source is a subtree of the Model pack, taken as the read-only lower layer, and the merged tree appears at Target inside the volume. Both paths are measured here rather than chosen at unlock, so no runtime caller can steer the mount.

type VolumeSpec added in v0.1.7

type VolumeSpec struct {
	Name      string          `yaml:"name"`
	Exec      bool            `yaml:"exec,omitempty"`
	Owner     string          `yaml:"owner,omitempty"`
	KeySecret string          `yaml:"key-secret,omitempty"`
	Overlays  []VolumeOverlay `yaml:"overlays,omitempty"`
	// Size is the capacity of the disk backing the volume, such as "500GiB"
	// or "16TB" (see ParseSize). Empty leaves the size to the host's default.
	// The host allocates the disk once, on first launch; changing the size
	// afterwards does not resize it.
	Size string `yaml:"size,omitempty"`
}

func (*VolumeSpec) OwnerIDs added in v0.1.15

func (v *VolumeSpec) OwnerIDs() (uid, gid int, err error)

OwnerIDs returns the uid and gid declared as Owner "uid:gid" or "id" for both, or root when Owner is empty.

func (*VolumeSpec) SizeBytes added in v0.1.10

func (v *VolumeSpec) SizeBytes() (int64, error)

SizeBytes returns the declared Size in bytes, or 0 when the host default applies.

Directories

Path Synopsis
cmd
tinfoil-config command

Jump to

Keyboard shortcuts

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