classic-confinement request for `whisper-cli`

name: whisper-cli

description: The official Whisper CLI. It gives an AI agent a real, routable IPv6 /128 identity (AS219419), verifiable from the outside with standard tools (dig, RDAP), plus safe network egress that leaves from that address. Register, connect, and verify in one command.

snapcraft: https://github.com/whisper-sec/whisper-cli/blob/main/snap/snapcraft.yaml (also reproduced inline at the end of this post)

upstream: https://github.com/whisper-sec/whisper-cli (open source, MIT)

upstream-relation: Publisher is the upstream author and maintainer. Whisper Security (viaGraph B.V.) develops and maintains both the `whisper` CLI and this snap; there is no separate upstream.

supported-category: tools for local, non-root user driven configuration of/switching to development workspaces/environments

reasoning:

`whisper` is a non-root, user-driven developer CLI whose core job is to configure the user's local development workspace. `whisper init` prepares the current project directory so an AI agent working in that project adopts a Whisper network identity: it writes `.claude/settings.local.json`, creates a `.whisper/` directory, and adds entries to the project's `.gitignore`.

Two properties make strict confinement unworkable:

1. The target is the current working directory, chosen by the developer at invocation time. Developers keep projects in arbitrary locations (under `$HOME`, but also `/srv`, `/opt`, `/workspace`, mounted volumes). No strict interface grants read/write to an arbitrary, runtime-chosen path. The `home` interface is limited to `$HOME` and, by documented design, excludes hidden files and directories (dotfiles): https://snapcraft.io/docs/home-interface. The paths `whisper init` must create, `.claude/` and `.whisper/`, are exactly those excluded dotfiles, so the flagship flow fails under `home`.

2. The `personal-files` / `system-files` interfaces can only declare a fixed, enumerated set of paths; they cannot express "the current working directory, wherever the user runs the tool," and they themselves require a manual grant, so they are no lighter than classic while still not solving it.

This maps directly to the supported category "tools for local, non-root user driven configuration of/switching to development workspaces/environments": an unprivileged user runs `whisper init` to configure the workspace they are working in.

For completeness: the CLI also runs a local user-space egress proxy (`whisper connect`) that binds a local port and makes outbound connections sourced from the agent's assigned IPv6, and manages a WireGuard interface in the routed mode. That part can plausibly be expressed with the `network`, `network-bind`, and `network-control` interfaces under strict confinement, so it is NOT the basis of this request. The binding constraint is the arbitrary-workspace file configuration above.

The snap is a single statically linked Go binary (`CGO_ENABLED=0`) built reproducibly from tagged public source, so it is straightforward to audit. Happy to attach a `snappy-debug` trace of the strict-mode `.claude/` write denial if useful.

- [x] I understand that strict confinement is generally preferred over classic.
- [x] I've evaluated the existing interfaces (`home`, `personal-files`, `system-files`, `network*`) and confirmed none can grant read/write to an arbitrary, runtime-chosen working directory including dotfiles.

---

snapcraft.yaml (inline copy):

```yaml
name: whisper-cli
base: core24
version: '0.132.0'
summary: A routable Whisper IPv6 identity and safe egress for agents
description: |
  The official Whisper CLI: give an AI agent a real, routable IPv6 /128 identity
  (AS219419), verifiable from the outside, with safe egress that leaves from that
  address. Register, connect, and verify in one command.
license: MIT
source-code: https://github.com/whisper-sec/whisper-cli
confinement: classic
grade: stable
parts:
  whisper:
    plugin: go
    source: https://github.com/whisper-sec/whisper-cli.git
    source-tag: v0.132.0
    build-snaps: [go]
    build-environment:
      - CGO_ENABLED: "0"
    override-build: |
      go build -trimpath -ldflags "-s -w -X github.com/whisper-sec/whisper-cli/internal/cli.Version=0.132.0" -o "$CRAFT_PART_INSTALL/bin/whisper" ./cmd/whisper
apps:
  whisper:
    command: bin/whisper
```

This request has been added to the queue for review by the @reviewers team.

Hey @whisper-sec

The target is the current working directory, chosen by the developer at invocation time. Developers keep projects in arbitrary locations (under $HOME, but also /srv, /opt, /workspace, mounted volumes). No strict interface grants read/write to an arbitrary, runtime-chosen path.

As per the Process for reviewing classic confinement snaps, "access to arbitrary files on the system due to developer/user inertia " is explicitly unsupported.

The home interface is limited to $HOME and, by documented design, excludes hidden files and directories (dotfiles): https://snapcraft.io/docs/home-interface. The paths whisper init must create, .claude/ and .whisper/, are exactly those excluded dotfiles, so the flagship flow fails under home.

read/write is always allowed to project level .claude , .whisper and .gitignore. If required, Access to the global ~/.whisper via personal-files interface would be an easy +1, while access to the global ~/.claude might be fine after success publisher vetting.

Thanks!

1 Like

@reviewers

Note that the name of this snap clashes with the popular OpenAI-derived voice recognition software, Whisper.cpp’s command-line interface program(also named whisper-cli), which may cause confusion to the users of that software as running the whisper-cli command on a system without it will triggers the recommendation of installation of the whisper-cli snap by the command-not-found mechanism.

As the publisher of the unofficial whisper.cpp snap I would like to express the concern of potential impersonation of the high-profile application names, especially when the age of the belonging projects appearing to be less than a month.

Hi @jslarraz, thank you, that is very helpful and you are right on both counts. We will withdraw the classic request and resubmit whisper-cli under strict confinement.

To confirm we have understood your guidance:

  1. Project files under $HOME (the whisper init flow). whisper init writes project-level .claude/settings.local.json, .whisper/ and .gitignore into the developer’s current project directory. As you point out, the home interface already permits these project-level hidden files (it only excludes dotfiles at the top of $HOME, not inside a project directory), so the flagship flow works under strict for projects under $HOME. We accept that projects outside $HOME (/srv, /opt, mounted volumes) are not covered, that is the arbitrary-path / developer-inertia case which we agree is out of scope.

  2. Global CLI state. One small correction to the paths I mentioned earlier: the CLI’s own global state is not ~/.whisper or ~/.claude, it is ~/.config/whisper/ (identity, key, and the session registry). We have added a personal-files plug for exactly that one namespaced directory under ~/.config:

    plugs:
      dot-config-whisper:
        interface: personal-files
        write:
          - $HOME/.config/whisper
    
  3. Networking (whisper connect). The default egress is a local user-space SOCKS5 proxy, which needs only network + network-bind. The optional routed WireGuard tier uses network-control, connected manually (snap connect whisper-cli:network-control), so it is not auto-connected.

The corrected strict snapcraft.yaml is now committed at whisper-cli/snap/snapcraft.yaml at main · whisper-sec/whisper-cli · GitHub (the earlier link 404’d, apologies, the file had only been inlined here). Please let us know whether the personal-files grant for $HOME/.config/whisper should be a separate store request or whether this thread is sufficient, and if there is anything else you need to close out the classic request in favour of the strict resubmission. Thanks again for the steer.

Whisper Security (viaGraph B.V.), AS219419

1 Like