Skip to content

🤖 fix: enforce canonical template and workspace leaf names #107

Description

@ThomasK33

Problem

The aggregated API does not verify the template-name segment returned by Coder's case-insensitive lookup. A request for acme.Starter-Template can return metadata.name: acme.starter-template, or delete that canonical template. This is not fixed by #106, whose scope is canonical organization and owner segments.

Evidence and limits

A scratch storage-entrypoint experiment against both baseline cfdd89749111d542e3fc7632ea1b8fa1fae1b49b and #106 candidate ef29d3a598e60e55330ece26c48d641f0c978309 observed identical template GET/DELETE behavior. A no-op UPDATE already rejects the differing request/object names. codersdk.TemplateByName documents case-insensitive lookup (vendor/github.com/coder/coder/v2/codersdk/organizations.go:637). The experiment used a case-folding mock proxy, not a live Coder deployment.

The same experiment models workspace-name casing and observes the analogous GET/delete-build behavior. Verify that lookup against live Coder before claiming the workspace case is reproduced in production.

Kubernetes authorization uses the requested URL name. A grant limited to the exact canonical name does not grant other casing; an explicitly granted alternate-cased URL can resolve to the same backend object. This is a name-to-object consistency concern, not evidence that #106 creates access to another tenant or backend identity. Live resourceNames integration coverage is still needed.

Acceptance criteria

  1. Reproduce with real storage entrypoints and a mock that matches the verified backend lookup semantics. Add failing tests before the fix.
  2. Reject a fetched template/workspace whose own name differs from the requested final segment, before returning it or mutating the backend. Preserve names that are genuinely canonical with mixed casing; do not add a lowercase blacklist.
  3. Cover GET, UPDATE/patch, DELETE, create-on-update, canonical repeated apply, and zero mutation on rejected names. Preserve organization-membership opacity.
  4. Test exact-name RBAC through a real kube-apiserver: canonical-only grant, alternate-case-only grant, no grant, and ordinary namespace-wide grant. Record which layer rejects each request and the backend object identity/state.
  5. Run repository checks and isolated KIND/Coder dogfood with a SHA-bound image. Retain command receipts, screenshots, video, and owned-resource cleanup evidence.

Ownership and trigger

Owner: maintainer desk. Immediate API-correctness follow-up after #106's disposition, before restoring quickstart support or claiming complete canonical-name enforcement. This is deferred work, not fixed work. The remaining import-readiness contract stays in #105.


Generated with xum • Model: coder:openai/gpt-6-astra • Thinking: xhigh

Activity

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

    bugSomething is not working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions