skills/use-s3-rustfs/SKILL.md
Install and run RustFS (S3-compatible object storage in Rust) in a Slicer VM, and talk to it with any S3 client (boto3, aws-cli, mc)
npx skillsauth add slicervm/agent-skills use-s3-rustfsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
RustFS is a high-performance, S3-compatible object storage server written in Rust. Use it when you need a local S3 endpoint for:
mc, Terraform, etc.)Upstream: https://rustfs.com — docs: https://docs.rustfs.com
This skill assumes you also have use-slicer — RustFS runs inside a Slicer microVM so it's isolated and disposable.
# 1. Persistent sandbox VM, tagged so you can find it again
VM_NAME=$(slicer vm add sbox \
--tag "workflow=rustfs" --tag "app=s3" \
| awk '/Hostname:/ {print $2; exit}')
slicer vm ready "$VM_NAME"
# 2. Install prereqs + RustFS (non-interactive)
slicer vm exec "$VM_NAME" --uid 1000 -- \
"sudo apt-get update -qq && sudo apt-get install -y -qq unzip curl"
slicer vm exec "$VM_NAME" --uid 1000 -- \
"curl -sSL -o /tmp/install_rustfs.sh https://rustfs.com/install_rustfs.sh && \
printf '1\n9000\n\n\n\n\n\n\n' | sudo bash /tmp/install_rustfs.sh"
# 3. Forward the S3 API to the host (optional — only if you want host access)
slicer vm forward "$VM_NAME" -L 9000:127.0.0.1:9000 &
slicer vm forward "$VM_NAME" -L 9001:127.0.0.1:9001 & # web console
Service is now listening on port 9000 (S3 API) and 9001 (web console) inside the VM, with default credentials rustfsadmin / rustfsadmin and data at /data/rustfs0.
RustFS wants to bind privileged directories (/data/rustfs0, /var/logs/rustfs) and install a systemd unit. Running it inside a disposable Slicer VM keeps your host clean, lets you snapshot/reset the storage instantly, and matches production-like deployment.
slicer vm add is persistent by default, it survives daemon restarts. Always launch with a descriptive --tags so the VM can be rediscovered:
slicer vm list --json | jq -r '.[] | select(.tags.workflow=="rustfs") | .hostname'
On slicer-mac use the sbox host group explicitly. On Slicer for Linux, list groups first (slicer vm group) or omit the positional to use the default.
The official installer is interactive. Feed it default answers with a printf pipe:
printf '1\n9000\n\n\n\n\n\n\n' | sudo bash /tmp/install_rustfs.sh
The 1 picks "Install"; the remaining blank lines accept defaults for port, console port, data dir, access key, secret key, etc.
After install, config lives at /etc/default/rustfs:
RUSTFS_ACCESS_KEY=rustfsadmin
RUSTFS_SECRET_KEY=rustfsadmin
RUSTFS_VOLUMES="/data/rustfs0"
RUSTFS_ADDRESS=":9000"
RUSTFS_CONSOLE_ADDRESS=":9001"
RUSTFS_CONSOLE_ENABLE=true
Change keys before anything touches real data:
slicer vm exec "$VM_NAME" --uid 1000 -- \
"sudo sed -i 's/=rustfsadmin/=$(openssl rand -hex 16)/' /etc/default/rustfs && \
sudo systemctl restart rustfs"
Service management:
slicer vm exec "$VM_NAME" --uid 1000 -- "sudo systemctl status rustfs --no-pager"
slicer vm exec "$VM_NAME" --uid 1000 -- "sudo journalctl -u rustfs -n 50 --no-pager"
An unauthenticated GET on / returns HTTP 403 when the server is healthy — that's the AWS-compatible "no anonymous access" response, not a failure.
Endpoint http://127.0.0.1:9000 (inside the VM, or via port-forward from the host):
import boto3
s3 = boto3.client(
"s3",
endpoint_url="http://127.0.0.1:9000",
aws_access_key_id="rustfsadmin",
aws_secret_access_key="rustfsadmin",
region_name="us-east-1",
)
s3.create_bucket(Bucket="demo")
s3.put_object(Bucket="demo", Key="hello.txt", Body=b"hello\n")
print(s3.get_object(Bucket="demo", Key="hello.txt")["Body"].read())
Notes for S3 clients:
endpoint_url — without it boto3 hits real AWS.region_name is required by the SigV4 signer, but RustFS ignores the value.--endpoint-url ... --addressing-style path) — virtual-host style requires DNS for every bucket.aws --endpoint-url http://127.0.0.1:9000 \
--no-verify-ssl s3 mb s3://demo
aws --endpoint-url http://127.0.0.1:9000 \
s3 cp ./file.txt s3://demo/
Credentials via env: AWS_ACCESS_KEY_ID=rustfsadmin AWS_SECRET_ACCESS_KEY=rustfsadmin.
mc)mc alias set rustfs http://127.0.0.1:9000 rustfsadmin rustfsadmin
mc mb rustfs/demo
mc cp ./file.txt rustfs/demo/
The console at port 9001 is a browser UI for browsing buckets, users, and policies. Forward it:
slicer vm forward "$VM_NAME" -L 9001:127.0.0.1:9001 &
open http://127.0.0.1:9001 # macOS
Log in with the same access/secret key.
Prefer running tests in-VM — zero network hops and no port-forward juggling:
slicer vm exec "$VM_NAME" --uid 1000 -- \
"pip3 install --quiet --break-system-packages boto3"
slicer vm cp ./rustfs_test.py "$VM_NAME":/tmp/rustfs_test.py --uid 1000
slicer vm exec "$VM_NAME" --uid 1000 -- "python3 /tmp/rustfs_test.py"
| Symptom | Cause / fix |
|---------|-------------|
| curl http://127.0.0.1:9000/ returns 403 | Healthy — S3 requires auth; not a failure |
| Installer hangs on "Please choose an option" | Script is interactive. Pipe printf '1\n9000\n\n\n\n\n\n\n' in. |
| boto3: InvalidAccessKeyId | Keys in /etc/default/rustfs were changed; restart service after edit |
| boto3: Could not connect to endpoint | Port forward not running, or daemon down (systemctl status rustfs) |
| CreateBucket fails with signature error | Virtual-host addressing against 127.0.0.1; switch to path-style |
| Data appears lost after VM delete | You deleted the persistent VM. Snapshot via slicer vm suspend or export disk first. |
# Wipe just the data, keep the VM
slicer vm exec "$VM_NAME" --uid 1000 -- \
"sudo systemctl stop rustfs && sudo rm -rf /data/rustfs0/* && sudo systemctl start rustfs"
# Uninstall RustFS, keep the VM
slicer vm exec "$VM_NAME" --uid 1000 -- "printf '2\n' | sudo bash /tmp/install_rustfs.sh"
# Nuke the whole VM
slicer vm delete "$VM_NAME"
development
Use Slicer to launch Linux microVMs for sandboxed builds, E2E tests, Docker, CI, and isolated dev environments — works from macOS and Linux hosts
development
Move a git worktree or repository into a Slicer microVM with a working, self-contained .git — push code in with `slicer wt push`, let a VM or coding agent work, then pull commits back. The recommended way to put a git project into an agent sandbox.
development
Filter, audit, and inject secrets into HTTP(S) egress from Slicer microVMs with Slicer Proxy — default-deny allow rules, credential injection (Bearer, Basic, OAuth for Claude/Codex/Copilot/xAI), audit and passthrough modes — on Linux and macOS.
tools
Provision K3s clusters with k3sup and k3sup-pro on local, Slicer, and remote VMs.