Security and data¶
What the image does, what it deliberately does not do, and how each claim is checked.
The image checks many of these claims itself while it is being built, and the build stops, so no image is created, if any of those checks fails. Before each release we also launch the image and check it on a real first boot. Both lists are at the end of this page.
The short version¶
This is a workbench image. It ships a Python environment, a web UI, and nothing that gets between you and your own instance. Security controls live where you already manage them: your security group, your IAM role, and your key pair, rather than inside the image where you cannot see them.
The one exception is a password on the web UI. A Marketplace launch usually opens the UI's port to any address, and without it anyone who found that address could use your instance. It is described below, and you can change it or turn it off.
Your data¶
- Files you upload are held in memory on your instance, not saved to its disk, and never sent anywhere. A copy can stay in memory for up to an hour after you leave, to make reopening the same file quick.
- If something goes wrong, the error's technical details go to the Studio's service log on the instance, and can include column names or values from your file.
- Trained models, scored files and code leave only when you download them, to your own computer.
- The Studio has no accounts, no usage tracking and no licence check, and makes no calls to Software Sushi. Streamlit's own usage statistics are turned off.
No host firewall, on purpose¶
UFW is not enabled, there is no iptables ruleset, and fail2ban is not installed.
An in-instance firewall on a Marketplace AMI is a trap. You open port 8501 in the security group, the UI still does not load, and nothing in the AWS console explains why, because the thing blocking you is a rule inside an image you did not write. Every port change then needs two edits in two places, one of which is undocumented.
The security group is the boundary. It is the control you already understand, it is visible in the console, and it is the one AWS itself evaluates.
fail2ban is absent for a narrower reason: it defends SSH against password guessing, and SSH on this image does not accept passwords.
SSH¶
The image keeps Canonical's Ubuntu 24.04 cloud defaults and does not change them:
| Setting | Value | Effect |
|---|---|---|
PasswordAuthentication |
no |
Key-based login only |
PermitRootLogin |
prohibit-password |
No root password login. cloud-init also turns away root key logins and points you to ubuntu |
ubuntu account password |
locked | Nothing to guess |
The build checks the two SSH settings, and that no account has an empty
password, rather than setting them, so if a future base image changes one, the
build fails instead of the image quietly shipping. The locked ubuntu password
is Canonical's default.
No SSH keys ship inside the AMI. Both authorized_keys files are removed
before the image is captured, and the host keys are deleted so cloud-init
generates a unique set on your instance's first boot. Two instances launched
from this AMI do not share a host identity. The machine ID is reset for the
same reason.
Patching¶
- Every build runs a full
apt-get dist-upgradebefore installing anything, so the image ships with the security updates available on its build date. - Ubuntu's
unattended-upgradesis left on, so a long-running instance keeps receiving security updates. Automatic reboots stay off, which is Ubuntu's default. An update can still restart the Studio's service, which ends any open sessions, so download your work as you go. telnetclients are removed. Nothing here needs a plaintext protocol.
Patching a running instance is yours to own. If it will live longer than a few days, treat it like any other EC2 host you patch.
What ships in the image¶
- Ubuntu 24.04 LTS, fully updated at build time
- A Python 3.12 virtual environment at
/opt/ml/venv, owned byubuntu, so you canpip installwithoutsudo - scikit-learn, pandas, NumPy, SciPy, matplotlib, seaborn, openpyxl, xlrd and joblib
- JupyterLab, installed but not running until you start it
- Sushi ML Studio, running as a system service on port 8501, from its own separate environment
/opt/ml/requirements.lock.txt, the exact version of every package in/opt/ml/venv, and/opt/ml/manifest.json, a summary of the main ones
What does not ship in the image¶
- No SSH keys, authorized or host
- No AWS credentials, and no IAM role is required to run it
- No fixed default password. The web UI's first password is your instance ID, which is unique to your instance, and no password file ships in the image
- No accounts beyond Ubuntu's own
- No telemetry
- Nothing of ours that phones home, and no licence check. Ubuntu's own update services contact Canonical as usual. The one agent present is AWS's SSM agent from Canonical's base image, which cannot connect to anything until you attach an IAM role or enable Systems Manager for your account
- No customer data of any kind
Signing in to the web UI¶
The Studio asks for a password before it shows anything. Until you choose one,
the password is your instance's ID, which starts with i- and is shown on the
instance's page in the EC2 console.
The instance ID is unique to your instance, but anyone who can see your EC2 console can read it. Change it if others will be able to reach the UI, with Change password in the Studio's sidebar, or from a terminal on the instance:
sudo sushi-ml-studio set-password # choose your own, 12 characters or more
sudo sushi-ml-studio reset-password # go back to the instance ID
sudo sushi-ml-studio disable-password # no sign-in at all
Changing it in the Studio asks for the current password first, and refuses the instance ID as the new one. Turning the password off, or back to the instance ID, is only possible from a terminal on the instance, not from the Studio, so someone who only has the web password cannot leave the instance open.
The password is stored as a salted scrypt hash in
/etc/sushi-ml-studio/password. Only root and the ubuntu account can read
or write it. The Studio's service runs as ubuntu, which is also the account
you sign in to a terminal as. A new password applies at once, with no restart,
and anyone signed in with the old one is asked to sign in again when they next
use the Studio.
If that file exists but cannot be read, sign-in is refused rather than falling back to the instance ID, and the sign-in screen says how to repair it. A wrong password is answered after a one-second pause and logged with the visitor's address, never with what they typed. There is no lockout.
Reaching the UI¶
The UI is plain HTTP on port 8501. The password keeps out strangers who find the address, but it does not encrypt anything: on a network you do not trust, such as public wifi, the password and your data can be read in transit. In order of preference:
- Tunnel it over SSH or Session Manager. Everything travels encrypted. See Reach the Studio privately.
- Or open the port in the security group. Restrict it to your office or VPN range where you can. If your address changes too often for that, the password is what protects the instance, so change it from the default.
Turn the password off only when the port cannot be reached from the internet, for example when you use a tunnel.
What answers without signing in. Streamlit's own health check and metrics counts, static files, and connection endpoints. None of them shows your data or runs the Studio. Files you download are served from links that cannot be guessed. A visitor can open connections and send uploads that are held in memory until their connection closes; a restricted security group or a tunnel prevents that.
Checked on every build¶
The build stops, and no image is created, unless all of this passes on the actual image:
- A login shell resolves
pythonto/opt/ml/venv/bin/python, and it is the advertised Python version - The main libraries import in both environments
- matplotlib renders a figure with no display attached
- A model trains, saves through joblib, and reloads to the identical score
- The UI service is enabled, starts, and answers its health check on 8501
- The Studio's environment is separate from yours
- SSH is key-only, root login is restricted, no account has an empty password,
and
rootis the only UID 0
Checked on a real first boot¶
Some claims cannot be checked from inside a builder that has never rebooted. Before each release we launch the image and check, on a real first boot:
- The UI service starts, not merely that it is enabled, and answers through the security group
- SSH host keys were regenerated on this boot, so no two instances share a host identity
- The machine ID is fresh
- cloud-init finished cleanly
authorized_keysholds no more than the launch key- No build log or build files survived into the image
- No web UI password file shipped, and sign-in resolves to this instance's ID
- The SSM agent is present, so Session Manager works once a role is attached
New versions¶
We publish new versions as the base OS and the Python stack receive security updates. AWS Marketplace scans every new version for known vulnerabilities before it can be published.
The release is in /etc/ml-release on the instance, for example
sklearn-1.9.1.
Reporting a vulnerability¶
Email info@softwaresushi.com with the AMI ID, the region, and what you found. Please do not open a public issue. Reports reach the same inbox as everything else, and are read on weekdays.