@ai-ecoverse/slicc-spectrum 1.111.1 → 1.111.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/dist/slicc-ui.js +1658 -1402
- package/dist/slicc-ui.js.map +3 -3
- package/dist/types/app/approvals.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -678,16 +678,20 @@ const name = await prompt({ title: 'New cone', label: 'Name', action: 'Create',
|
|
|
678
678
|
### Secret rules check
|
|
679
679
|
|
|
680
680
|
`secretRules(command, cwd)`, exported from `dist/slicc-ui.js` (`@ai-ecoverse/slicc-spectrum/ui`), is the check behind the sudo dialog's secret-rules warning.
|
|
681
|
-
It takes a sudo request's command (without `sudo` and its options) and working folder, and returns `{ certain, maybe }`:
|
|
681
|
+
It takes a sudo request's command (without `sudo` and its options) and working folder, and returns `{ certain, maybe, once }`:
|
|
682
682
|
|
|
683
683
|
- `certain` is an absolute path when the command names a file or folder holding SLICC's secret rules (`/etc/fnox`, `/etc/fnox/config.toml`, `/etc/slicc/secrets-policy.toml`), a folder above them it changes as a whole (`/`, `/etc`, `/etc/slicc`), a glob or brace that matches one, or a file named like them (`fnox`, `secrets-policy`) anywhere, as `/tmp/fnox/config.toml`.
|
|
684
684
|
It sees through quotes, backslashes, `$'…'` and `$"…"`, `cd` and `pushd` (also inside `bash -c`), relative paths and `..`, extglobs, `/proc/self/root` and `/proc/self/cwd`, option clusters like `-t/etc/fnox`, and comma lists.
|
|
685
685
|
When every command in it is read-only and nothing in it expands, quoted text is data: a jq or yq program such as `'.a // .b | {x: .y}'` isn't split into paths, and `*`, `?`, `[` and `{` in quotes (and `$` in single quotes) are literal, as the shell treats them. Other commands, such as `sh -c '…'`, are still looked into.
|
|
686
686
|
- `maybe` is the token when the command may reach one of them and the check can't tell where it leads: an expansion (`$X`, `$(…)`, backticks), a `~user/..`, `~+` or `~-` path, a `/proc/<pid>/cwd` or `/dev/fd` path, or a command over 4096 characters (its first 40 followed by `…`).
|
|
687
|
+
It's also set, only when nothing above applies (a separate check that never clears or changes those verdicts), when an explicit write names its target from data the check can't see: `yq -s`, `--split-exp` or `--split-exp-file` (`yq -s`), or `xargs` running a command that can write or run others, such as `xargs rm < list` (`xargs rm`). `xargs` running a read-only command (`xargs cat < list`, `xargs grep x -- < list`, `xargs --replace=X cat X < list`, and `xargs sort`, `xargs find`, `xargs uniq -c` or `xargs yq .` with no write flag in the command; with `--replace` or `--eof` split from its value, both readings must be read-only) is a plain read and stays clean.
|
|
688
|
+
- `once` is set, when the other two are `null`, to `xargs` and the program when `xargs` runs a program that's read-only only without its write flags (`sort`, `find`, `file`, `tree`, `base64`, `uniq`, `xxd`, `yq`) and shows none: `xargs sort < list` gives `once: 'xargs sort'`. The command is a plain read, but `xargs` adds arguments from its input, which could be a write flag (`printf -- '-o\n/etc/slicc/secrets-policy.toml\n' | xargs sort`) or, for `uniq` and `xxd`, an output file. So it can be allowed once but not always. `xargs cat`, `xargs grep` and other programs without write flags leave it `null`. No other read-only program takes arguments from data.
|
|
689
|
+
Leading assignments (`A=1`, `A+=1`, `a[1]=x`) and the wrappers `command`, `env`, `exec`, `ionice`, `nice`, `nohup`, `setsid`, `stdbuf`, `time` and `timeout`, with their options (abbreviated long ones too), don't hide `xargs` or `yq` (`command xargs rm < list`, `env -i A=1 nice -n 5 xargs rm < list`, `timeout --sig KILL 5 xargs rm < list`); `env -S`/`--split-string` is split into the command it runs (`env -S'xargs rm'`; one with a `\` escape or `$` gives `env -S`), a string run by a shell's `-c` (also in a cluster, `bash -lc '…'`, after `sh`, `bash`, `dash`, `zsh`, `ksh` or `fish`) or by `eval` is looked into, the word after `!`, `{`, `if`, `then`, `else`, `elif`, `do`, `while`, `until` and `coproc` is a command, and `command -v xargs` runs nothing.
|
|
687
690
|
|
|
688
|
-
|
|
691
|
+
All three are `null` for a clean command, and at most one is set.
|
|
689
692
|
The dialog shows "This changes secret rules" for `certain` and "This may change secret rules" for `maybe`, and offers no Always allow for either.
|
|
690
|
-
|
|
693
|
+
For `once` it shows no notice and offers no Always allow, with "Always allow isn’t offered: xargs adds arguments from its input, and they could include a write flag." (`[data-once-only]`, the program in the attribute) when the request has `always`.
|
|
694
|
+
An embedder that records "always" decisions itself, such as slicc-bios, must refuse "always" (answer "once" at most) whenever any of the three is set, so a decision sent without the dialog can't add a rule that runs it unasked.
|
|
691
695
|
|
|
692
696
|
```js
|
|
693
697
|
import { secretRules } from './dist/slicc-ui.js';
|
|
@@ -696,7 +700,7 @@ secretRules("bash -c 'rm /etc/fn\\ox/config.toml'");
|
|
|
696
700
|
secretRules('rm -rf $TARGET', '/home/cone');
|
|
697
701
|
```
|
|
698
702
|
|
|
699
|
-
The first gives `{ certain: '/etc/fnox/config.toml', maybe: null }`, the second `{ certain: null, maybe: '$TARGET' }`. The result's type is `SecretRulesVerdict`.
|
|
703
|
+
The first gives `{ certain: '/etc/fnox/config.toml', maybe: null, once: null }`, the second `{ certain: null, maybe: '$TARGET', once: null }`. The result's type is `SecretRulesVerdict`.
|
|
700
704
|
|
|
701
705
|
### Sprinkle bridge
|
|
702
706
|
|
|
@@ -966,13 +970,13 @@ Later backed by: BIOS.
|
|
|
966
970
|
`list()` returns waiting `Approval`s; emit `approvals` when the list changes.
|
|
967
971
|
A `sudo` approval has `id`, `requester` (`kind` `agent` or `user`, `name`, optional `agentId` and `where`, such as a terminal's title), `command` (without `sudo`; bios joins the kernel's argv shell-quoted), optional `target` (the user to run as; shown as `sudo -u {target}` unless `root`), optional `cwd` and `verdict` (`{ decision: 'allow' | 'deny' | 'unsure', reason }`, the automatic check’s view), `createdAt`, `expiresAt` (epoch ms) and `always` (offer Always allow, which covers the requester's user and this exact command).
|
|
968
972
|
With `decide(id, 'once' | 'always' | 'deny')`, which resolves once the decision is recorded and then drops the request from `list()`, the tab shows a warning alert dialog (`dialog[data-approval][data-kind][data-requester]`): "Allow sudo?", "{name} wants to run this with sudo[ in {where}]:" for an agent or "You ran this with sudo[ in {where}] (as {name}):" for a user, the command, "In {cwd}", a notice when the command changes secret rules, what Always allow does, "Denied automatically in m:ss." and how many more wait, with **Deny** (`data-action="deny"`, focused; Escape also denies), **Always allow** (`always`) and **Allow once** (`once`).
|
|
969
|
-
A command that names `/etc/fnox` (or anything in it) or `/etc/slicc/secrets-policy.toml`, resolved against `cwd`, globs included (with quotes and backslashes removed, operands after `--` included; a path with `[`, `{` or `$` counts when the part before it could lead to them), or that names `/`, `/etc` or `/etc/slicc` in a command other than a read-only one (such as `ls`, `cat`, `stat`, `grep`, `jq`, `cut`, `od`, `sha256sum` or `md5sum
|
|
973
|
+
A command that names `/etc/fnox` (or anything in it) or `/etc/slicc/secrets-policy.toml`, resolved against `cwd`, globs included (with quotes and backslashes removed, operands after `--` included; a path with `[`, `{` or `$` counts when the part before it could lead to them), or that names `/`, `/etc` or `/etc/slicc` in a command other than a read-only one (such as `ls`, `cat`, `stat`, `grep`, `jq`, `cut`, `od`, `sha256sum` or `md5sum`, and coreutils' pure output programs, which take no output file and run nothing: `basename`, `dirname`, `printf`, `seq`, `tr`, `fold`, `paste`, `comm`, `join`, `expand`, `unexpand`, `fmt`, `numfmt`, `pr`, `expr`, `factor`, `sum`, `tsort`, `pathchk`, `base32`, `basenc`, `true`, `false`, `id`, `groups`, `whoami`, `logname`, `printenv`, `uname` and `nproc`, so `ls | xargs -n1 basename` is a read; `find` without `-exec`, `-execdir`, `-ok`, `-okdir`, `-delete` or `-fprint`/`-fls`; `sort` without `-o`, `-T` or `--compress-program`; `yq` without `-i`, `-s` or `--split-exp-file`; `base64` without `-o`; `tree` without `-o` or `-R`; `file` without `-C`; `uniq` and `xxd` with one operand at most, counting everything after `--`; a flag counts inside a short cluster, with a value attached (`-o/x`, `-i.bak`), as `--name=value` and abbreviated (the data-write check below reads clusters more exactly: there a cluster ends at `=` or at an option that takes a value, so `yq -o=json` isn't `yq -s`, and an option's value isn't a `uniq` or `xxd` operand); `less` and other pagers aren't, since they run commands), or runs with `cwd` in `/etc/fnox`, or names a relative path with `fnox` or `secrets-policy` in it wherever `cd` may have led, gets "This changes secret rules." with the path (`[data-secret-rules]`, the path in the attribute).
|
|
970
974
|
Read-only commands count only by bare name or from `/bin` and `/usr/bin`.
|
|
971
975
|
In a command made only of read-only commands and with no live expansion, the quoted words count whole: `jq '.a // .b' f` doesn't name `/`, and `jq '{a: .b}' f` in `/etc` isn't a brace that could lead to the rules.
|
|
972
976
|
`/proc/<pid>/root` counts as `/` and `/proc/self/cwd` as `cwd`.
|
|
973
|
-
Otherwise a command with a parameter expansion or command substitution (`$…`, backticks), a `~+` or `~-` path or a `~` path that climbs with `..`, a path through another process's `/proc/<pid>/cwd`, `fd` or `map_files` or through `/dev/fd`, or more than 4096 characters, gets "This may change secret rules." with the first such part in the attribute.
|
|
977
|
+
Otherwise a command with a parameter expansion or command substitution (`$…`, backticks), a `~+` or `~-` path or a `~` path that climbs with `..`, a path through another process's `/proc/<pid>/cwd`, `fd` or `map_files` or through `/dev/fd`, an explicit write whose target comes from data (`yq -s`, `--split-exp`, `--split-exp-file`, or `xargs` running a command that isn't read-only), or more than 4096 characters, gets "This may change secret rules." with the first such part in the attribute.
|
|
974
978
|
Other symlinks aren't followed.
|
|
975
|
-
Either way there's no Always allow, even when `always` is `true` (`decide(id, 'always')` isn't called for it), so each change to the rules is asked for.
|
|
979
|
+
Either way there's no Always allow, even when `always` is `true` (`decide(id, 'always')` isn't called for it), so each change to the rules is asked for. The same goes for `xargs` running a gated read-only program (`once`), which shows no notice but says why Always allow isn’t offered.
|
|
976
980
|
For half a second after a request shows, only Deny works, so a double-click can't approve it.
|
|
977
981
|
A rejected `decide` shows its message in the dialog (`[data-error]`, `dialog[data-rejected]`) in place of the countdown, with only **Close** (`data-action="close"`, focused; Escape also closes), which moves on to the next waiting request or closes the dialog.
|
|
978
982
|
Pass `decide` in every tab: the first decision wins.
|