Request for classic confinement: skuberplus-client

To make the review of your request easier, please use the following template to provide all the required details and also include any other information that may be relevant.


  • name: skuberplus-client
  • description: Skuber+ Client is an Electron-based Kubernetes desktop client / IDE for managing Kubernetes clusters from the Linux desktop (revision 1 uploaded; amd64; base core22).
  • snapcraft: PRIVATE — the snap is produced by electron-builder (no standalone public snapcraft.yaml); the source repository is private.
  • upstream: PRIVATE
  • upstream-relation: The snap publisher is the upstream developer. Wondermove develops and maintains the application.
  • supported-category: kubernetes tools requiring arbitrary authentication agents (the app is also a Kubernetes IDE).
  • reasoning: To connect to clusters the app must honor the user’s kubeconfig, which references arbitrary binaries and files at arbitrary, user-controlled paths that strict confinement and existing interfaces cannot cover:
    • Client cert/key at arbitrary paths — e.g. client-certificate: /home/user/.minikube/client.crt, keys under ~/.config, corporate mounts, etc.
    • exec credential plugins - users.user.exec.command invokes host binaries such as aws, gke-gcloud-auth-plugin, aws-iam-authenticator, az, or custom scripts, located unpredictably across the host.
    • Binaries inside other snaps — e.g. gcloud container clusters get-credentials writes a kubeconfig whose command is /snap/google-cloud-sdk/current/bin/gcloud; a confined snap cannot invoke another snap’s binaries or anticipate theirpaths.
    • Provider credential/config files outside the sandbox — ~/.aws/, ~/.config/gcloud/, etc.

Because the set of auth binaries/paths is chosen by each user’s kubeconfig, we cannot enumerate or bundle them, and the personal-files/home interfaces cannot grant execution of arbitrary host (or other-snap) binaries. This is the same situation for which kontena-lens (another Kubernetes IDE) was granted classic confinement. The snap builds cleanly and passes review-tools.snap-review --allow-classic.

I understand that strict confinement is generally preferred over classic.

I’ve tried the existing interfaces to make the snap to work under strict confinement.

Note that snappy-debug can be used to identify possible required interfaces. See https://snapcraft.io/docs/debug-snaps for more information.

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

Hey @wondermove

Client cert/key at arbitrary paths — e.g. client-certificate: /home/user/.minikube/client.crt, keys under ~/.config, corporate mounts, etc.

Provider credential/config files outside the sandbox — ~/.aws/, ~/.config/gcloud/, etc.

These are certainly not reasons for classic. You can use personal-files or even better, the FileChooser xdg portal (See File Chooser - XDG Desktop Portal documentation)

Binaries inside other snaps — e.g. gcloud container clusters get-credentials writes a kubeconfig whose command is /snap/google-cloud-sdk/current/bin/gcloud; a confined snap cannot invoke another snap’s binaries or anticipate theirpaths.

I think this is clearly an anti-pattern. If you try to run a binary inside a snap using a base different than the host system will possibly cause issues. Perhaps we could consider granting desktop-launch for this

exec credential plugins - users.user.exec.command invokes host binaries such as aws, gke-gcloud-auth-plugin, aws-iam-authenticator, az, or custom scripts, located unpredictably across the host.

I’m not very familiar with the ecosystem. How many credential plugins exists? If there are just few of them, maybe staging them inside the snap is the right choice.

Thanks

Thank you for engaging with each point in detail, @jslarraz — I appreciate the alternatives you suggested. Let me address each one, with concrete data on the ecosystem since you noted you weren’t very familiar with it.

  1. personal-files / FileChooser portal for cert/key paths

You’re right that for user-initiated file selection these are good options, and I appreciate the suggestion. The reason they don’t fit here is the non-interactive nature of the Kubernetes auth flow:

  • personal-files grants access only to paths declared in advance in the snap manifest. Kubeconfig cert/key paths are chosen by the user at runtime (any path under $HOME, /etc/ssl/, corporate mount points, etc.) and cannot be pre-enumerated.
  • The FileChooser portal requires interactive user selection. The app reads certs/keys silently on every list/watch/exec call against the cluster — prompting via a portal on each API call (often many per second on active screens) would make the app unusable.

That said, I want to emphasise that this file-read side is not actually the most fundamental blocker — even if file access were solved, the execution side (point 3) is the harder constraint.

  1. “Other-snap binary execution” and desktop-launch

I understand the concern about cross-snap execution being structurally messy — I share that view from a snap-architecture standpoint. The issue is that we do not create this pattern; the Kubernetes ecosystem (including Canonical’s own google-cloud-sdk snap) writes it into the user’s kubeconfig automatically. When a user runs gcloud container clusters get-credentials after installing google-cloud-sdk via snap, the resulting kubeconfig contains:

users:
 - user:
     exec:
       apiVersion: client.authentication.k8s.io/v1beta1
       command: /snap/google-cloud-sdk/current/bin/gcloud
       args: [config, config-helper, ...]

We consume the user’s existing kubeconfig and cannot rewrite it; if we cannot execute the path it specifies, cluster connection fails.

Regarding desktop-launch: my understanding is that this interface is designed for launching GUI desktop applications, not for invoking a short-lived credential helper as a child process during an API call. Using it for kubectl exec-style credential acquisition would be a semantic mismatch, and it would still need to handle arbitrary paths (point 1) which the interface doesn’t model. Happy to be corrected if I’m misreading the interface.

  1. Number of exec credential plugins / staging them inside the snap

Thanks for asking — here is concrete data. The set is not small and not bounded:

  • Major public plugins already in active use: aws (AWS CLI), gcloud, az, aws-iam-authenticator, gke-gcloud-auth-plugin, doctl (DigitalOcean), ibmcloud, oci (Oracle), linode-cli, plus kubelogin variants for Azure AD / OIDC providers.
  • Enterprise-internal scripts: many organisations ship in-house auth wrappers (Vault-based, SAML, custom mTLS) that we cannot anticipate.
  • The set grows whenever a new cloud or identity provider releases a kubectl exec helper.

Even setting aside the unbounded list, staging them inside the snap would not actually solve the problem:

a) Each helper needs its own credential state — aws reads ~/.aws/, gcloud reads ~/.config/gcloud/, several read the OS keychain — all outside the snap sandbox. Even with the helper bundled, it cannot reach the user’s cloud credentials.

b) Users with an official cloud-SDK snap installed already have kubeconfigs referencing the snap-installed helper (/snap/google-cloud-sdk/current/bin/gcloud). Shipping our own bundled copy at a different path would be ignored — kubectl follows what the kubeconfig says.

c) Staging would also pull large platform-dependent cloud CLIs into our snap unnecessarily, and we would have to re-vendor on every cloud SDK release.

  1. Precedent and supported category

This is the same architectural situation for which kontena-lens ( Classic confinement for kontena-lens ) (another Kubernetes desktop IDE) was granted classic confinement, after the reviwer acknowledged in that thread that “kubernetes authentication helpers are a valid use case for classic.” That use case was subsequently codified as the supported category “kubernetes tools requiring arbitrary authentication agents,” which we are citing. in that thread that “kubernetes authentication helpers are a valid use case for classic.” That use case was subsequently codified as the supported category “kubernetes tools requiring arbitrary authentication agents,” which we are citing.

If it would help, I’m happy to build a strict-confinement revision and attach snappy-debug output showing the specific denials when connecting to a cluster that uses an exec credential plugin with a /snap/… command path. Please let me know if that would be useful.

Thanks again for the careful review.

Hey @wondermove

Thanks for the thoughtful explanation. Regarding “other-snap binary execution”, I still think we need to do something, as it is likely to cause issues in the future; however, it is outside of skuberplus-client’s control.

I agree that the snap matches a supported category for classic confinement and the technical reasons are clear. In order to proceed with this request, the publisher needs to be vetted. Given that the upstream repository is private, the only option to move forward is for you to complete the Verified accounts process.

Thanks

Thank you @jslarraz.

I’ve submitted the Verified accounts request for our publisher account here: Verified account request: Wondermove (skuberplus-client)

We’ll follow up once the verification is complete so this request can proceed.

Thanks again for the review!