Box Images
Which image a new box starts from, and what an image you save holds, refuses and gives each box made from it (Security).
A box's image
Each OS is an image from a fixed table, found by its publisher, never
by searching image names, which anyone can publish under: Canonical's
SSM parameters on AWS and its ubuntu-os-cloud project on Google
Cloud. A box with GPUs gets NVIDIA's driver from AWS's Deep Learning
Base AMI (AWS's own SSM parameter) or Canonical's
ubuntu-os-accelerator-images project.
Images you save
lnk box image create keeps a box's disk as an image in its cloud
account, for lnk box create --image.
What it holds
Everything on the box's disk, but its lnk login: lnk box image create
signs the box's lnk out first (lnk auth logout there), asks it
again, and refuses to save a box still signed in. Anything else you put
on the box is in the image, and in every box made from it.
The old login's blocks
The old token's file is deleted, and fstrim -a (with sudo) drops
the disk's freed blocks before it's saved, where the disk takes it; on
one that doesn't, the old file's blocks can stay in the image until
written over.
Fails closed
Every check on the box (its agents, its secrets, its login) refuses the
save when the box's answer fails or isn't what lnk prints: an SSH
error is never taken for "none".
Consistent
The box is stopped while its disk is saved, so no file is saved half-written, and started again after.
Cost
The question before saving says the image is billed every month by its
size. lnk uninstall deletes no image: it says they stay in your
accounts.
What saving refuses
A box holding secrets where they're usually left, Link's own stores, or agents is refused, and nothing on it is removed.
Secrets where they're usually left
Before it changes anything, save runs a script over SSH that looks in
ubuntu's home folder, and refuses the box, listing what it found:
~/.git-credentials, ~/.config/git/credentials, a ~/.netrc with a
password, the GitHub CLI's login, an SSH private key (~/.ssh/id_* but
.pub), and the AWS, gcloud, Azure, Docker and Kubernetes logins.
Package registries' tokens
A token in an .npmrc, .yarnrc.yml or .pypirc in the home folder or
up to three folders down (but in node_modules, .git and .venv)
refuses it too; one written as ${VARIABLE} is read from the
environment, and isn't one.
Link's own, as each plugin says
It asks the box's lnk what each of Link's plugins there keeps (lnk uninstall --parts --json, each plugin's own answer), and refuses the
box when any part's secret paths hold anything: a folder with anything
in it, or a file that isn't empty. A part's secret paths are those it
names, else all of its paths, so a plugin that says nothing more is
checked whole. Only Link's own plugins are asked, as lnk uninstall
asks them.
What that refuses
lnk cloud's, lnk box's and each cloud adapter's folders (accounts,
logins, the SSH key), lnk bucket's (keys and encryption passwords)
and ~/Link/Personal, the agents' folders, settings and notes
(~/Link/Agents, ~/Link/History/Agents) are refused wherever their
plugin keeps them; lnk measure's numbers aren't secrets. Its login
(relay) is signed out instead, above.
A path it can't read
A box whose lnk doesn't answer is refused, and
so is a path that isn't absolute or holds a control character. A secret
path the box's user can't look into (a folder above it, or itself, not
its to search or read) is taken as holding something, so a store a part
keeps in another user's home, as a keeper of secrets does, refuses the
box rather than passing unseen.
No agents
A box with agents on it is refused, since each box from the image would run them as themselves, with their keys and connections.
It removes nothing
The box is yours, and still in use. A secret anywhere else, under
another name, or in another user's home (root's) isn't looked for.
Against a mistake
It's a check the box makes of itself, against a mistake, not a defence against the box's root: whatever root mounts over a store's path (an empty folder bound over it) hides the store from the check, and the image keeps what's under the mount.
A box from an image
What a box made from an image you saved keeps of it, and what it gets of its own.
Its own identity
A box from an image signs in as any new box, with a token of its own.
Before lnk is set up there, the saved box's machine ID is deleted, and
the box gets an ID of its own.
The image's lnk
A box from an image runs the lnk this computer checked: one of another
version is replaced by the checked install.sh, and the new lnk
brings the image's plugins to its version (lnk upgrade, with its own
keys).
The image's SSH keys
The box keeps the image's ~/.ssh/authorized_keys: a key removed from
boxes after the image was saved still opens every box made from it.
Save the image again after removing a key.
Its own host keys
Ubuntu's cloud-init deletes an image's SSH host keys and makes new ones
at the first boot of each new machine (ssh_deletekeys, run once per
instance), and prints them on its console, where lnk box create reads
them as for any box.
Never the saved box's
They're pinned under the new box's own name (lnk-<cloud>-<its id>),
so the saved box's keys are never trusted for it. Nothing Link keeps on
the saved box's instance (its host keys, its tags) is in the image.
Yours only
An image is tagged lnk-image=<name> and lnk-owner=acct-<id> (on AWS
its snapshot too). lnk box image list lists only yours. A box is made
only from the account's own image (--owners self on AWS, the
project's own on Google Cloud), never a public one by the same name.
lnk box image delete deletes an image only when it's tagged as Link's
for you.
Hashes
An image saved with --hash is tagged lnk-hash=<hash> too. The hash
is yours, made from what you choose; Link checks only that it's a tag's
lowercase letters, digits and dashes. lnk box create --image-hash
takes the newest ready image of yours with that tag, as --image takes
one by name: the tag is as trusted as the account, where anyone who can
tag images could make one answer a hash.