{"id":15649122,"url":"https://github.com/benwr/soanm","last_synced_at":"2026-03-11T16:41:43.988Z","repository":{"id":62261213,"uuid":"558095777","full_name":"benwr/soanm","owner":"benwr","description":"Shell Of A New Machine: Quickly configure new environments","archived":false,"fork":false,"pushed_at":"2022-10-30T13:23:11.000Z","size":65,"stargazers_count":40,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-27T06:51:51.497Z","etag":null,"topics":["configuration","dotfiles","provisioning","remote-administrative-tool","remote-management"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benwr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-26T22:18:49.000Z","updated_at":"2023-08-18T07:33:37.000Z","dependencies_parsed_at":"2023-01-20T15:35:40.029Z","dependency_job_id":null,"html_url":"https://github.com/benwr/soanm","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwr%2Fsoanm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwr%2Fsoanm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwr%2Fsoanm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benwr%2Fsoanm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benwr","download_url":"https://codeload.github.com/benwr/soanm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251099735,"owners_count":21536153,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","dotfiles","provisioning","remote-administrative-tool","remote-management"],"created_at":"2024-10-03T12:28:05.521Z","updated_at":"2026-03-11T16:41:43.705Z","avatar_url":"https://github.com/benwr.png","language":"Rust","readme":"# Shell Of A New Machine\n\n`soanm` is a dead-simple tool for easily configuring new UNIX machines, with\nalmost zero prerequisites on the target machine. All it needs is `curl`.\n\nRight now it works on MacOS and Linux on both aarch64 and x86_64, and OpenBSD\non x86_64. These are the systems I typically use and can easily build on, but\nporting it to new platforms is as simple as compiling a new static Rust binary\nand adding it to the release on Github. If you want support for a new platform,\nadd an issue and I'll be happy to get it ported.\n\n## The Basic Idea\n\nWhen you install a new operating system on some machine, whether it's a server,\na laptop, a desktop, or a VM, it can be a hassle to get to the point of feeling\ncomfortable on that machine: You use dozens of tools that need to be installed,\nand many of these need to be configured. You need to set up Tailscale, and SSH\nkeys, and API keys.\n\nWouldn't it be great if you could just do this all at once, in a totally custom\nway? Well, now you can!\n\nYou'll need two computers: One \"sponsor\", which is equipped with any resources\nneeded for provisioning the other machine (the \"enrollee\"). For example, if you\nwant your new machines to have access to GitHub, your sponsor computer should have\nthe ability to add ssh keys to GitHub.\n\nTo configure `soanm`, you'll also want a directory that describes the configuration\nphases: It should have a subdirectory `enroll`, with programs that will be run\non the enrollee, a subdirectory `sponsor` with programs that will be run on the\nsponsor, and a subdirectory `results`, where output from the enrollee will be\nstored. There must be the same number of programs in the `sponsor` and `enroll`\ndirectories, and these all must be set as executable.\n\nOnce you have created this configuration directory, the provisioning process is\nbegun by running `soanm sponsor [conf_directory]`. This will print a\ncorresponding command for you to run on the enrollee (this command will include\na secret used to securely connect the computers to one another).\n\nThe program pairs will be run in order, sorted by filename. For each pair, the\n`sponsor` program is run first, and its output is sent over a [Magic\nWormhole](https://github.com/magic-wormhole/magic-wormhole.rs). That output is\nthen used as the input to the corresponding `enroll` program. The `enroll`\noutput, in turn, is sent back to the sponsor and saved in the `results`\ndirectory, where it can be used by subsequent `sponsor` programs.\n\nNote that on the sponsor machine, the stdin of the configuration programs is\ninherited from the top-level programs, allowing for user input. And on both\nsponsor and enrollee machines, stderr is printed to the corresponding terminal.\n\n## How to use it\n\nThe sponsor machine needs a relatively recent rust version, and a directory\nwith a subdirectory for the `sponsor` programs, one for the `enroll` programs,\nand an empty one called `results`.\n\n```bash\ncargo install soanm\nsoanm sponsor config_dir\n```\n\nThis will print out a command, which should be run on the enrollee.\n\n## Security considerations\n\nUnder some assumptions, it should be relatively safe to use this tool to pass\nsecrets around.\n\nYou obviously have to trust that the release binaries provided here are not\nmalicious. I hereby stake my reputation on the claim that I built them myself\nfrom the sources contained in this repository, which (of course) does not\ncontain malicious code. But if you don't trust me, or the tree of dependencies\nI used to build these binaries, you should verify that the release binaries\nlook safe. This also requires trusting GitHub to faithfully serve binaries that\nhave been uploaded, as well as trusting that no one has unauthorized access to\nmy Github account. For obvious reasons I try hard to protect my Github account,\nand I promise that I will never hand control of this repository to anyone else.\n\nYou also need to trust the `magic-wormhole` protocol. We use the default\nmagic-wormhole rendezvous server (`ws://relay.magic-wormhole.io:4000/v1`) to\nestablish a secure peer-to-peer connection, over which files are transmitted.\nWe default to using a 128-bit passphrase (16 words) for the initial rendezvous,\nthough this is configurable on the sponsor command line. We have chosen to use\nvery long passphrases by default, since we want an extremely low probability of\nbeing man-in-the-middled, and since the usual scenario is that you're\ncopy/paste-ing the passphrase from one shell to another.\n\n## Why not just use [a different tool]?\n\nThere are lots of tools that could be used for parts of this task. Foremost\namong them is [Nix](https://nixos.org). If you only use Linux, MacOS, or\n*maybe* FreeBSD, Nix can do everything you need: Just write a quick script that\ninstalls nix, grabs your nix configuration, and instantiates it into your\nprofile, and then you can `curl -L [myscript] | bash` to magically set\neverything up. But if you use any other platforms, like (say) OpenBSD, Nix\nisn't currently viable.\n\nOther possibilities:\n\n* You could write a script that uses SCP to send your files and configuration\n  scripts to the remote host, and then runs them. This would work fine, but it\n  requires that you have SSH access to the new host, which isn't typically the\n  case by default on a new laptop, for example.\n* You could use Ansible, or Puppet, or Terraform. But then you need to have the\n  tool installed on the host, and of course you need to learn how to use these\n  systems, which can be complicated. `soanm` doesn't require anything fancier\n  than shell scripting, and lets you write code in any language you want as\n  long as you ensure it's installed properly by an earlier stage. With most of\n  these other tools, you'll likely need an additional tool for managing your\n  secrets, while with `soanm` you can pipe them safely to the new host from\n  the old one.\n* You could use a dotfiles manager, like `chezmoi`. These typically won't\n  install packages for you, or run arbitrary code, though.\n\nYou can easily combine `soanm` with any of these other methods, if that's what\nyou'd like to do.\n\nThere are probably a thousand ways to do this kind of task. I couldn't find one\nI liked, so I wrote one that I do. Maybe you'll like it too.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenwr%2Fsoanm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenwr%2Fsoanm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenwr%2Fsoanm/lists"}