Installation config file
The file an installation starts from - installation_config in Terraform. It seeds the control plane’s database once; after that the dashboard edits the installation, and a later change to the file shows up there as a proposal to apply or dismiss. Every block is optional. Check a file before applying it with controlplane config check <file>.
# An installation's configuration, as a file to keep in git.## controlplane config check spin.yaml # what it declares; opens no database## The file seeds an installation: when a control plane starts, each item here the installation# does not have yet is created from it, once. From then on the installation is its database, and# the dashboard edits all of it. A later file that says something else of an item - a changed# default, a policy taken out - is not written: the dashboard shows it as a change to apply or# dismiss, and remembers the answer until the file changes again.## Every block is optional.
settings: # What a workspace may be created from. Declared and empty is refused: it would allow # nothing at all. Leave the key out for the installation's default. allowed_images: - ghcr.io/acme/sandbox:v1 # Zero is no limit. max_workspaces_per_user: 10 # Who a workspace's identity token may be for - a cloud's STS, a Vault, a cluster's API server. # Leave the key out for anybody; a relying party still decides which workspaces it admits. identity_audiences: - sts.amazonaws.com # How many days a deleted workspace stays in the trash - its disk, snapshots and keys kept - for # its owner to undelete, before it is erased. 0 is no trash: a delete erases at once. At most 90. workspace_trash_days: 7 # How far behind the object store a workspace's disk may fall, in seconds, where its preset does # not say: what a host lost without warning may lose of a workspace that writes. 300 where left # out; 0 commits on size and snapshots alone; otherwise 60 to 86400. volume_rpo_seconds: 300 # How a host's disk is lent. A disk holds what its workspace wrote, not its size: a host is # charged this percent of each new disk's size until it writes more, and takes workspaces up to # 80% of its device. 1 to 100; 100 charges every disk its full size. disk_reserve_percent: 50 # How much of its device a host may be promised, its disks' sizes summed: what it would need if # every one filled at once. 100 to 400; 100 promises nothing past the device. disk_commit_max_percent: 200 # Whether the object store's garbage collection, a daily job, only says what nothing reaches # rather than deleting it. The delete is a marker the bucket expires after its Object Lock. storage_gc_report_only: false # Whether a team's admins may declare egress policies of their own, for the team's workspaces: # named and only allowing - nothing brokered. Any team may then reach past what the policies # below allow, so it is off unless decided. team_network_policies: false # Whether the control plane fetches VS Code servers from Microsoft on its own: the newest stable # release, looked for daily, and the server of a client's commit the installation has not # released. Off, it fetches none, and workspaces get the server the image carries or one an # administrator published. vscode_fetch: false # Whether the control plane fetches the agent CLIs - Claude Code and Codex - from their # publishers on its own: the newest release of each, looked for daily. Off, it fetches none, # and workspaces get the pair the image carries or one an administrator published. agents_fetch: false # The IAM role a team's secret kept in Secrets Manager or Parameter Store is read under, in a # session tagged spin-team-id with the team; it reads only a secret or a parameter tagged the # same. Unset, a team's secrets are sealed in the database and none is a reference. # team_secrets_role: arn:aws:iam::123456789012:role/spin-team-secrets # What a workspace created without a tag of its own runs under, by policy name - the # network_policies block below, or a host's own. Unset, it is "offline", the policy every # host has and which allows nothing: a workspace nobody chose a policy for reaches nothing # past its own namespace. An agent creating its own workspaces is exactly the caller that # names no tag, so this is where an installation decides what that one may reach. # # Declared empty it is "offline" as well: no spelling of this setting means open. An # installation that wants such a workspace to reach the internet declares a policy that says # so - allow: ["0.0.0.0/0"], which the node's own drops still come before - and names it # here, so what a workspace may reach always has a name somebody chose. default_network_tags: - agent # Moving a workspace off a host that stopped answering, without anybody asking. # # A host that *stops* says so and is emptied first. This is the other one: the machine that # lost power, or its network, and said nothing. Its workspaces stay where they are until # somebody runs `spin workspace recover --accept-data-loss`, which means noticing. # # rehome_after_seconds is how long the silence has to last; unset or zero, nothing is ever # moved and this whole thing is off, which is what an installation starts as. A move gives # up whatever the host had not published, so it is not a default. # # rehome_max_unpublished_bytes is how much of that this installation gives up on its own. # The number is what the silent host last reported it had not sent to the object store - # for a host that is gone, what it never will. Over it, the workspace waits for a person. # A host that never reported at all also waits: nothing known is not the same as nothing # to lose. rehome_after_seconds: 900 rehome_max_unpublished_bytes: 67108864 # Where this installation keeps its logs and traces: a bucket of its own, never the volumes', # in the same account and region as theirs. The control plane that leads runs the store over # it; a change of bucket is applied by restarting it. How many days each index keeps what it # holds is read again every minute; 30, 7 and 7 where a key is left out. logs_bucket: acme-spin-logs # Which of the cloud's costs are this installation's, and its budget, as the cloud names them: # on AWS the value of its spin:installation tag and the budget's ARN, which spin-terraform-aws # writes. The control plane reads the bill a few times a day for Admin → Costs; without a scope # it reads none. bill_scope: acme-spin bill_budget: arn:aws:budgets::123456789012:budget/acme-spin-monthly logs_platform_retention_days: 30 logs_workspace_retention_days: 7 traces_retention_days: 7 # Keep what every workspace writes - its machine's console, and what its own services write to # the guest's journal - searchable by whoever may read the workspace for # logs_workspace_retention_days. Off unless declared: that output leaves its workspace only # when the installation decides it does. Each workspace may have logs_workspace_daily_mb of it # kept a UTC day (100 where this says nothing); past it, the rest of the day is dropped and one # line says so. collect_workspace_logs: false logs_workspace_daily_mb: 100
registration: # open, whitelist or closed. mode: whitelist # Addresses and domains the whitelist admits. An entry with an @ is an address; without # one, a domain. emails: - acme.com - contractor@example.com
# What a person may choose when creating a workspace. One preset may be the default.# burst says how a workspace of it grows: fixed (the default) runs at its size; to_preset# starts at the floor (burst_floor_cpu, burst_floor_memory_mb; 1 and 1024 if left out) and# grows to its size; to_host starts at the floor and grows to what its host has.# bandwidth_mbps is what its network carries each way (left out: unshaped); ssh, the editor# and forwarded ports are not held to it. rpo_seconds is how far behind the object store its# disk may fall (left out: the installation's volume_rpo_seconds).presets: - name: small description: For an agent doing one task at a time cpu: 2 memory_mb: 4096 disk_gb: 20 bandwidth_mbps: 100 default: true - name: large cpu: 8 memory_mb: 16384 disk_gb: 100 burst: to_preset burst_floor_cpu: 2 burst_floor_memory_mb: 4096
# Egress policies, by name. A workspace created with --network-tag agent runs under this one.## Carrying a tag is the deny. A workspace with no tag reaches anything beyond the node's own# networks; a workspace with any tag reaches what its tags allow and nothing else. So every# policy here is an allowlist.## "offline" is not declared here and cannot be: every host installs it, it allows nothing, and# it is what default_network_tags means when it is unset.## Tags compose as a union: a workspace created with two of them reaches everything either one# allows, and the order they are named in does not change that.## A policy is a list of rules, and allows what any of them allows. A rule is destinations on# ports, each destination on each port: allow is IPv4 prefixes; allowNames are names, each# exact or with a single leading "*.", enforced through the workspace's own lookups - the host# opens the address its resolver answered that workspace with, for as long as the answer# lives. ports are destination ports, "443" being TCP, which is what a bare number means; UDP# is asked for by name ("53/udp"), because opening UDP to anywhere is the shape of a tunnel; a# range is "8000-8100" or "8000-8100/udp"; and "icmp" is a ping - an echo request, no other# ICMP type. A rule with no destination is its ports anywhere, and one with no port is every# port at its destinations. Two things on two sets of ports are two rules: one rule of both# would open each port at each destination. A workspace needs no port for DNS: its resolver is# the host's, which answers under every policy.## A policy is as exact as DNS: an address serving several names is open to all of them once# one is allowed - unless the rule says verifySNI: true, which passes a TLS connection only when# its hello names one of the rule's names (TCP only, 443 where it names no port). That holds a# client that says which host it wants, not one that lies. See docs/network/README.md.network_policies: - name: agent rules: - allowNames: - github.com - "*.githubusercontent.com" - registry.npmjs.org allow: - 140.82.112.0/20 # The web and nothing else: no address at all, so it composes with any other tag. - name: web rules: - ports: - 80 - 443 # A resolver of the workspace's own on UDP, and ping anywhere: two rules, not their product. - name: diagnostics rules: - allow: [1.1.1.1/32] ports: ["53/udp"] - ports: [icmp]Generated by task reference from spin/configs/spin-example.yaml at 8eee32b9d.
Documents Spinbox v20261019.02. This page as Markdown, for a model or a terminal.

