Security model
How Quasar contains a station's code, and what it logs.
On this page
A station is code written by someone else, running on your server with the permissions you accepted. These are the protections, from the most important.
- Separate process. The script runs in a new process for each call, with no Docker access, no database, no disk and no network. Every request goes through the dashboard, which checks it against the permissions. Escaping the JavaScript engine gains nothing.
- No markup. The script returns data, never HTML, so it can’t inject anything into the dashboard.
- Nothing by default. A station gets only the permissions it declared and you accepted.
- Narrowed by name. Services for
exec, patterns forfiles, keys forenv, hosts fornet.external, verbs forlifecycle. - Paths checked after resolving links. A symbolic link can’t lead outside the application’s folder.
- Limits enforced from outside. Time and memory are bounded by the dashboard, which kills the process if needed.
- Theme contained. A station can’t restyle the dashboard’s navigation, so it can’t imitate a login page or an update prompt.
- No silent upgrades. A revision that asks for more is held until accepted.
- Everything logged. See below.
Accepting exec from a malicious author. exec is root access to the container, by design, and the install screen says so.
Station activity is recorded in the audit log:
| Event | Recorded when |
|---|---|
station.import |
A station is installed. |
station.permissions.grant |
Permissions are accepted. |
station.revert |
A station is rolled back. |
station.action |
An action runs. |
station.exec |
A command runs in a container. |
station.files.write |
A file is written. |
station.files.delete |
A file is deleted. |
station.env.write |
An environment variable is written. |
station.lifecycle |
The application is started, stopped, restarted… |
station.http.external |
A request is sent to the internet. |
station.hook.fail |
A hook fails. |