Skip to content

cozy:tenant:use:base grants console on every VMI in a tenant namespace, platform-owned included #4173

Open

Description

@myasnikovdaniil

cozy:tenant:use:base grants console, VNC and power control on every VirtualMachineInstance in a tenant namespace, with no resourceNames. That is right for the VMs a tenant created and wrong for the platform-owned ones that also land there.

The rule is at packages/system/cozystack-basics/templates/clusterroles.yaml:165-190 and is bound per namespace by packages/apps/tenant/templates/tenant.yaml:51-61. It was written for the VM catalog, where console and power buttons are the point. Nothing about it is specific to the apps that own the VMs, because RBAC cannot express that: the authorizer answers before the object is read, so it sees the verb, the GVR, the namespace and the name from the request path, and nothing else. No label selectors, no owner references, and no deny rules. resourceNames is the only lever there is.

Three charts create VMs in tenant namespaces today: vm-instance, kubernetes-nodes (which ComputePlane also uses) and site-router. Only the first is tenant-owned in the sense the grant assumes.

Why it matters now

site-router's gateway VM is a platform-owned appliance carrying the guest firewall that compensates for a relaxed OVN port, so the chart always renders its boot disk as the pinned appliance. The console reaching inside it was a real escalation until the bootloader was locked (#3426). That fix removes what the console was worth on that one VM. It does not make the grant correct, and it does not touch the super-admin path below.

ComputePlane is the sharper case and has its own issue: the tenant is explicitly given no admin kubeconfig for that cluster, yet holds console and restart on its nodes.

There is a second tier to the same problem. cozy:tenant:super-admin:base (clusterroles.yaml:293-299) grants kubevirt.io virtualmachines with verb *, bound in every tenant namespace, so that tier does not need the console at all: it can edit a platform-owned VM directly, swap its cloud-init secretRef and have the guest install whatever it names on the next boot. Flux drift correction is off, so the edit persists. Any scoping that covers only the console subresources leaves this open.

Proposal

Drop the blanket rule from cozy:tenant:use:base, and have each chart that creates VMs grant console, VNC, portforward and power on its own VMs by name.

For statically named VMs this is trivial and race free, because the Role ships in the same release as the VM it names. site-router then simply does not emit one, and the grant is absent rather than neutralized.

CAPK-generated worker names are the hard part. They carry a random suffix and resourceNames has no wildcard or prefix match, so those need a controller that watches VMs and rewrites the Role. kubernetes-nodes already runs a reconcile Job, so there is somewhere for it to live. Expect a brief window after a VM is created where the dashboard returns 403 until the Role catches up.

Things that will bite

list cannot be scoped by resourceNames, because a list request carries no name. The current rule grants get and list on the console and VNC subresources; list on a subresource with no collection endpoint looks like carry-over, but that needs checking against virtctl and the dashboard before it is dropped.

This changes RBAC for every tenant in every installation. Getting the scope wrong takes console access away from tenants for their own VMs, so it needs a staged rollout rather than a single flip.

Activity

  1. added
    kind/bugCategorizes issue or PR as related to a bug
    security/mediumMedium severity security finding
    area/platformIssues or PRs related to platform infrastructure (bundle, flux, talos, installer)
    on Sep 9, 2026
  2. added
    area/virtualizationIssues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import)
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/important-longtermImportant over the long term, but may not be staffed and/or may need multiple releases to complete
    and removed
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/platformIssues or PRs related to platform infrastructure (bundle, flux, talos, installer)area/virtualizationIssues or PRs related to virtualization (kubevirt, cdi, vmi, vm-import)kind/bugCategorizes issue or PR as related to a bugpriority/important-longtermImportant over the long term, but may not be staffed and/or may need multiple releases to completesecurity/mediumMedium severity security findingtriage/acceptedIndicates an issue is ready to be actively worked on

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions