Approvals and policies
SARA runs commands on your hosts and clusters, so SkyPortal decides for each command whether it runs right away, waits for your approval or is blocked. This page explains those rules and the settings that change them.
How a command is decided
SkyPortal checks every command in this order:
- Blocks. The command is refused, and no approval can override it, when:
- your team role doesn't allow it on that host;
- it is destructive and the host's environment policy is read-only (Production, by default);
- it matches the deny list of the repository selected in the chat.
- Sensitive and destructive commands. They always get an approval card, even when a permit list matches or Read-Only Mode is on. See what a permit list never runs on its own.
- Permit lists. A command that matches a permit list entry runs without asking.
- Read-Only Mode. When it is on, safe reads run without asking.
- Approval card. Everything else waits for you.
The approval card
When a command needs approval, the chat shows a Command Approval card with the command and the hosts it will run on.
| Button | Effect |
|---|---|
| ✓ Approve | Runs this exact command once, on the hosts shown |
| ✓✓ Approve all | Runs it and adds it to the host's permit list, so similar commands run without asking, unless they are sensitive or destructive. See Permit lists |
| ✕ Reject | Cancels the command. SARA is told you rejected it |
Plans get their own card with Approve, Reject and Revise Plan. Revise Plan sends your feedback, and SARA rewrites the plan for a new approval.
If a card shows Timed Out, the command did not run. Ask SARA to try again.
Permit lists
A permit list holds commands that may run on a host without an approval card. A host's list applies to every chat and every user that runs commands on that host.
You can add entries in two ways:
- ✓✓ Approve all on an approval card saves the command's base prefix: the first word, or the first two words for
git,docker,kubectl,npm,yarn,pip,pip3,cargo,go,systemctl,python,python2,python3andnode. Approvinggit log -5this way allows everygit log. Approvingcurl https://example.com/healthallows everycurl. Approvingrm -rf /tmp/oldsavesrmtoo, but destructive commands still ask every time. A compound command (a && b) is saved part by part. You need permission to change the host's settings. - Agent Settings (in the sidebar, or More settings in the chat ⚙ menu) has a Permit List section for each host you own. Type a command in the box, click Add, and click × on an entry to remove it. Entries are saved exactly as you type them.
How entries match
- A command matches when it equals an entry, or starts with the entry followed by a space.
git logdoes not matchgit login. - If the rest of the command contains
>,<,&,$(or a backtick, it doesn't match.2>&1and>/dev/nullare the exceptions. - Every part of a compound command has to match.
- Commands that span several lines never match.
What a permit list never runs on its own
- Kubernetes operations on Secrets or RBAC objects,
kubectl exec,cp,attachandport-forward, and deleting a namespace, PVC or PV. These always need a new approval. - Destructive commands, whatever the host's policy. They are blocked on read-only hosts and need an approval on all others. On a multi-host run, a read-only host in scope blocks the whole run.
- Reads and writes of sensitive files, on one host or many.
Keep entries narrow
An entry matches any arguments. An entry like cat lets SARA read any file on the host without asking, except the sensitive files SkyPortal recognizes. A file it doesn't recognize is read even if it holds secrets. SkyPortal redacts secrets in the output, but the command still runs. Prefer specific entries such as nvidia-smi or df -h.
Removing an entry applies to new chats right away. A chat that is already open can keep using the old list for a while, so start a new chat when the change has to apply at once.
Repository rules
A repository can carry its own allow and deny lists in .skyportal/settings.json:
- The rules apply when the chat has that repository selected on that host.
- A
denymatch blocks the command, even if a host permit list allows it. - Only the first 50 entries of each list are read.
- If the file exists but can't be read, commands need approval.
SkyPortal applies the file as soon as it reads it. Review changes to .skyportal/settings.json as carefully as code that runs on your hosts.
Environment policies
Every host has an environment label: Production, Staging, Dev or Custom. Set it in the Environment field when you add or edit a host. Only the host's owner can change it. New hosts added from the Hosts sidebar start as Production, and a host without a label counts as Custom.
Each label maps to a policy:
| Policy | Default for | What it does |
|---|---|---|
| 🔒 Read-only | Production | Blocks destructive commands. Other commands follow the normal rules |
| ✓ Standard | Staging, Custom | Permit lists can run commands that aren't destructive. Destructive commands always need approval |
| ⚡ Unrestricted | Dev | Same as Standard for commands: a permit list doesn't run destructive commands here either |
"Destructive" means commands on SkyPortal's list of commands that change things: file changes such as rm, mv, cp, chmod, tee or sed, package managers, kill, systemctl, dd, mkfs, output redirection to a file, find -delete, and the write operations of docker, git, kubectl and helm.
Note
A read-only policy blocks the commands SkyPortal recognizes as destructive. A command it doesn't recognize, such as a custom script, still reaches a normal approval card. Read cards for production hosts carefully.
To change a policy, click the Scope pill above the message box. Each environment shows its policy badge. Click ⚙ Edit policy, choose a policy and click Save. The setting is yours, applies to every host with that label and to all your chats. On a team, a role can impose a stricter ceiling (see Team roles).
Read-Only Mode
Read-Only Mode is in the chat ⚙ menu. It is off by default and applies to your whole account. When it is on:
- Safe reads such as
ls,catandgreprun without an approval card. Reads of sensitive files (.env, SSH keys, cloud credentials and similar) and of Kubernetes Secrets still ask. - Destructive commands still get a normal approval card, the same as with the mode off, on one host or many.
- Permit lists still apply, except to sensitive and destructive commands, which always ask.
- Action Approvals switches back to Ask.
Read-Only Mode saves clicks while you investigate. It is not a lock. To make sure nothing changes on a host, give it a read-only environment policy.
Auto-approve
Action Approvals in the chat ⚙ menu has two settings: Ask (the default) and Auto-approve. The same setting applies in the CLI and SDK.
With Auto-approve, every command and plan card in the open chat is approved for you, one at a time. That includes:
- destructive commands on Staging, Custom and Dev hosts;
- Kubernetes operations such as reading Secrets,
kubectl execand deleting a namespace; - file edits;
- commands that run on many hosts at once;
- plans.
It does not get past:
- the blocks described above: read-only environments, team roles and repository deny lists;
- hosts outside the chat's scope;
- agent token requests;
- questions SARA asks you in the chat.
Auto-approve never adds entries to a permit list. In the web app it works while the chat is open in a browser tab. Each decision is recorded as automatic in the audit trail. Turning it on turns Read-Only Mode off.
Team roles
On a team, the Teams page gives each member a role: Admin, Maintainer or Read-only. Roles govern the hosts your teammates share with you. Your own hosts are not affected.
- Each role has a ceiling for each environment. The stricter of the ceiling and your own policy wins, and an environment without a ceiling means no access for that role.
-
New teams start with these ceilings:
Role Production Staging Dev Custom Admin No limit No limit No limit No limit Maintainer Read-only Standard Unrestricted Standard Read-only Read-only Read-only Read-only Read-only -
The Read-only role can only run commands from a list of safe reads. Anything else is refused without a prompt, including reads of sensitive files. It can't use ✓✓ or edit permit lists. Refusals tell the member to ask a team admin.
- Enterprise teams that provision members from Okta through SCIM can map groups to roles. A team admin turns this on with Turn on group roles in the Okta / SCIM groups section of the Teams page. It is off by default.