fix: enforce hierarchical external Workdir permissions

This commit is contained in:
2026-09-30 02:01:12 +09:00
parent 677c7cfed9
commit 39ecd1b239
17 changed files with 510 additions and 243 deletions
+31 -16
View File
@@ -1,34 +1,49 @@
# External Workdir sharing permissions
`yoi workdir share` exposes a client-hosted directory through an authenticated,
outbound Backend connection. The operator grants three independent categories:
outbound Backend connection. The operator selects exactly one permission level:
- **READ**: file reads and read-only discovery operations such as Stat, List,
ViewImage, Glob, and Grep.
- **WRITE**: Write and Edit. WRITE requires READ because updating an existing
file uses the read-before-write content-hash contract. Selecting WRITE never
enables COMMAND.
- **COMMAND**: command start, status, bounded output, and cancellation. COMMAND
does not enable READ or WRITE. It executes on the sharing host with the OS
- **READ** (capability bits `25`): file reads and read-only discovery operations
such as Stat, List, ViewImage, Glob, and Grep.
- **WRITE** (capability bits `31`): READ plus Write and Edit. Including READ
preserves the read-before-write content-hash contract. WRITE never enables
COMMAND.
- **COMMAND** (capability bits `63`): WRITE plus READ plus command start, status,
bounded output, and cancellation. It executes on the sharing host with the OS
authority of the user running the CLI; External Workdir command execution is
**not a sandbox** and does not confine the process to the shared directory.
READ is enabled by default and COMMAND is disabled by default. Interactive mode
asks for a comma-separated category list and shows the exact grant before it is
created. For automation, repeat `--permission`:
In short, `COMMAND ⇒ WRITE ⇒ READ`. READ is the default. Interactive mode asks
for one level and shows its included permissions before creating the grant. For
automation, pass `--permission` once:
```sh
yoi --backend https://example.invalid workdir share ./project \
--workspace-id workspace-a \
--permission read \
--permission write \
--permission command \
--non-interactive
```
`--read-only` remains an alias for READ. `--read-write` remains an alias for
READ+WRITE and never enables COMMAND. These legacy flags conflict with explicit
`--permission` arguments so ambiguous automation fails closed.
`--read-only` remains an alias for the READ level. `--read-write` remains an
alias for the WRITE level and never enables COMMAND. These legacy flags conflict
with `--permission`, and multiple `--permission` arguments are rejected so
ambiguous automation fails closed.
The grant API retains the boolean projection for compatibility, but accepts only
these combinations when creating new grants:
| Level | `read` | `write` | `command` |
|---|---:|---:|---:|
| READ | `true` | `false` | `false` |
| WRITE | `true` | `true` | `false` |
| COMMAND | `true` | `true` | `true` |
Older non-hierarchical grants such as command-only or READ+COMMAND are not
silently widened. The Backend refuses their projection, provider registration,
and subsequent restore/reconnect with guidance to revoke and re-share the
directory at one of the supported levels. General Workdir attachment/session
capability intersections may still produce partial capability sets; that
restriction applies only to External grant authority.
Omitting `--ttl` creates no automatic expiry. An explicit TTL must be between
60 seconds and 24 hours. Ctrl-C, revoke, expiry, provider disconnect, attachment