Commit Graph
14732 Commits
Author SHA1 Message Date
McKayla はな f242ef0799 feat(site): copy PR branch name from git panel (#25589) 2026-06-08 13:21:18 -06:00
Susana Ferreira 18919425f9 fix(aibridge): initiate SSE stream before agentic continuation to avoid IsStreaming race (#26139)
The agentic loop has a race between the main goroutine and the `Start`
goroutine on the shared `ResponseWriter`. When an iteration's response
contains only injected-tool events (no text to relay), `Start` may not
have called `InitiateStream` by the time main reaches the `IsStreaming`
check on the next iteration. The `IsStreaming` check then returns false,
main writes a JSON error via `writeUpstreamError`, and `Start` later
writes SSE headers and events on top, producing a malformed JSON+SSE
response:

```
{\"error\":{\"message\":\"all configured keys are rate-limited\",\"type\":\"rate_limit_error\"},\"request_id\":\"\",\"type\":\"error\"}event: message_start\n..."
```

Fix: explicitly call `events.InitiateStream(w)` at the agentic
continuation point so the SSE stream is committed before the next
iteration runs. Keeps `messages` consistent with the pattern already
used in `chatcompletions/streaming.go`. `sync.Once` makes the double
call safe.

Related: coder/internal#1524
Related: coder/coder#25654
Closes:
https://linear.app/codercom/issue/AIGOV-336/flake-teststreaminginterception-agenticloopfailoveragentic-all-keys

> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by
@ssncferreira
2026-06-08 20:13:13 +01:00
Kyle Carberry cd3692c0c2 feat: add agent-side workspace context sources and Agent API v2.10 PushContextState (#25983)
Adds the agent half of the workspace context sources RFC. The agent now
resolves instruction files, skills, and MCP configs into a typed
`Snapshot`, watches the relevant paths recursively, exposes the source
list over a workspace-agent HTTP API, and pushes each `Snapshot` to
coderd over a new `PushContextState` RPC on Agent API v2.10.

The coderd-side handler is a stub returning `Unimplemented` for now.
Real persistence to `workspace_agent_context`, chatd hydration on dirty
events, and the `KindMCPServer` MCP provider are tracked by
[CODAGT-569](https://linear.app/codercom/issue/CODAGT-569/enable-agent-api-v210-pushcontextstate-bump-currentminor-wire-coderd).
This matches the pattern used for v2.7 `ReportBoundaryLogs` in
[#21293](https://github.com/coder/coder/pull/21293), which bumped the
version and shipped a stub server so the wire and client could iterate
before the persistence layer landed.

## What ships

### agent/agentcontext (new package)

- `Source`, `Resource` (kinds `instruction_file`, `skill`, `mcp_config`,
`mcp_server` plus reserved `plugin`/`hook`/`subagent`/`command`),
`ResourceStatus`, `Snapshot`, `ComputeAggregateHash`.
- `Manager` owns the in-memory source list, performs the initial resolve
synchronously in `NewManager`, runs a re-resolve/watcher loop in `Run`,
exposes
`AddSource`/`RemoveSource`/`Sources`/`HasSource`/`Snapshot`/`SubscribeChanges`/`Resync`/`SeedSources`/`Close`.
- `Resolver` walks scan roots, classifies recognized files, enforces 64
KiB per-resource, 2 MiB aggregate, and 500-resource caps with
`StatusOversize`/`StatusExcluded`/`StatusUnreadable`/`StatusInvalid`
outcomes, skips `node_modules`/`vendor`/etc., validates symlink targets
stay inside the scan root, stamps `SourcePath` on user-derived
resources, and optionally pulls MCP server tool lists via an
`MCPProvider` interface. MCP config resources ship metadata only (size,
hash) so secrets in env blocks never leave the agent.
- `Watcher` is a recursive `fsnotify` wrapper with a 250 ms debounce,
dynamic arming of newly created directories, and an ENOSPC-tolerant
degraded mode that no-ops further syncs until the manager resyncs
explicitly.
- HTTP API for `GET/POST /sources`, `GET/DELETE /sources/{path}`, `POST
/resync` mounted at `/api/v0/context`.
- `Pusher` interface plus `RunPush` goroutine with exponential backoff
capped at 30 s. `DRPCPusher` adapts the generated `DRPCAgentClient210`
to `Pusher` and translates `drpcerr.Unimplemented` to
`ErrPushUnimplemented` so the push loop exits cleanly when talking to
coderd deployments that have not enabled the real handler.

### agent/proto (v2.10)

- New messages `ContextResource`, `PushContextStateRequest`,
`PushContextStateResponse` and the `PushContextState` RPC on `service
Agent`.
- Generated `DRPCAgentClient210` interface and
`codersdk/agentsdk.Client.ConnectRPC210` / `ConnectRPC210WithRole`.
- `tailnet/proto.CurrentMinor` bumped from `9` to `10`.

### Agent wiring

- `agent.Options.Client` declares both v2.9 and v2.10 connectors;
`run()` dials with `ConnectRPC210WithRole`.
- `apiConnRoutineManager` holds a `DRPCAgentClient210`. Existing v2.8
routines keep their narrower `DRPCAgentClient28` signature thanks to
interface embedding.
- `startAgentAPI210` is the v2.10 counterpart to `startAgentAPI` for
routines that need the new client. The push context state routine uses
it.
- A `contextManager` is constructed in `agent.init()`, seeded from the
existing `CODER_AGENT_EXP_*_DIRS` env vars, started in its own goroutine
under `gracefulCtx`, and closed in `agent.Close`.
- `handleManifest` calls `Manager.SeedSources` for sources rooted at the
manifest directory, then `Resync` after `manifest.Swap`, so the snapshot
reflects the workspace working directory immediately instead of waiting
for the next filesystem event.
- HTTP routes mounted at `/api/v0/context` when the manager is up.

### Coderd stub

`coderd/agentapi/context.go` returns `drpcerr.Unimplemented` for
`PushContextState`. The real handler that persists
`workspace_agent_context` rows, hydrates chats, and emits dirty events
lives in CODAGT-569.

## Tests

24 tests across `agent/agentcontext` cover types, paths, resolver
behavior with file caps, skill containers, MCP secret omission, symlink
target validation, the recursive watcher firing on real fsnotify events,
manager source CRUD / `Resync` / `SeedSources` / `Run` lifetime, the
HTTP API, the DRPC adapter, and the push retry / initial-flag /
unimplemented paths. Passes `go test -race -count=2`.

`TestAgent_ContextStatePushed` boots a full agent against
`agenttest.FakeAgentAPI` (which now records `PushContextState` traffic)
and asserts the seeded `AGENTS.md` appears in a snapshot push with
`schema_version = 1`.

<details>
<summary>Notes for reviewers</summary>

- Source CRUD is workspace-agent-token only; coderd is not in the path
for source mutation.
- Per-resource cap 64 KiB, aggregate 2 MiB, count cap 500; resources
past the cap ship with `StatusExcluded` and an empty payload so the
aggregate hash still detects content edits. MCP-emitted resources
enforce both a per-provider count cap and the aggregate byte cap.
- Symlinks inside the scan root are followed; symlinks pointing outside
(or broken) are rejected with `StatusExcluded` so credentials reachable
via a stray symlink stay off the wire.
- The initial push gates `lifecycle = ready` in the eventual full
design. For this PR the `SeedSources` plus `handleManifest`-driven
`Resync` keeps the snapshot fresh; the live push loop ships now and
DRPCPusher translates the coderd `Unimplemented` stub into a clean exit.
- The `PLUGIN`/`HOOK`/`SUBAGENT`/`COMMAND` kinds are reserved in proto
and Go enums but unused; the Claude Code plugin resolver ships in a
follow-up that does not need a schema migration.
- Two follow-ups remain, both tracked by
[CODAGT-569](https://linear.app/codercom/issue/CODAGT-569/enable-agent-api-v210-pushcontextstate-bump-currentminor-wire-coderd):
(1) the chatd-side handler that persists snapshots and dirties chats;
(2) the `coder exp chat context` CLI command set for
`list`/`show`/`add`/`remove`/`refresh`.

</details>

_This PR was authored by Coder Agents on Kyle Carberry's behalf._
2026-06-08 12:08:40 -07:00
Andrew Aquino d85211685b feat: add group avatar to GroupPage (#25878)
ref DEVEX-24

Figma:
https://www.figma.com/design/KWMwUzDZtd5U0aU9xCdFR2/Service-accounts---user-driven-access-controls?node-id=129-2158&m=dev

<img width="1840" height="1191" alt="image"
src="https://github.com/user-attachments/assets/5164ba3b-f967-49ab-a5d4-a8c2f9f0b973"
/>
2026-06-08 09:13:01 -07:00
Danny Kopping 8b5e1cac08 fix(aibridge): check x-session-affinity header for OpenCode sessions (#26140)
## Summary

`X-OpenCode-Session` is only set by the OpenCode "Zen" provider. Other
providers use `x-session-affinity` instead. This change falls back to
`x-session-affinity` when `X-OpenCode-Session` is not present, so
sessions are correctly identified regardless of the provider used.

Ref: https://github.com/coder/coder/pull/26128

## Changes

- `aibridge/session.go`: Prefer `X-OpenCode-Session` (Zen), fall back to
`x-session-affinity` (other providers).
- `aibridge/session_test.go`: Add tests for precedence and fallback
behavior.

> Generated with [Coder Agents](https://coder.com) by @dannykopping
2026-06-08 17:44:13 +02:00
Cian Johnston 3052089c4d test: fix transport error flake (#26132)
`TestResolveWorkspace/TransportError` could sometimes observe an HTTP
404 from a closing test server instead of a transport error.

Make the test deterministic by injecting a failing `http.RoundTripper`,
and add `testutil.RoundTripperFunc` for reuse.

Generated by Coder Agents.

<details>
<summary>Implementation plan</summary>

# Plan: Deterministic ResolveWorkspace transport error test

## Context

`TestResolveWorkspace/TransportError` relied on closing an
`httptest.Server` before making a request. CI showed this can race with
the request path and produce an HTTP 404 instead of a transport error.
The test should inject a transport failure directly.

## Red

1. Update the transport-error case to use a custom `http.RoundTripper`
that returns an error.
2. Confirm the test fails to compile until the reusable
`testutil.RoundTripperFunc` helper exists.

## Green

1. Add `testutil.RoundTripperFunc` in `testutil/http.go`.
2. Implement `RoundTrip` so the function type satisfies
`http.RoundTripper`.
3. Add a compile-time interface assertion for the helper.
4. Update `codersdk/workspaces_test.go` to inject a client using
`testutil.RoundTripperFunc`.
5. Keep the existing assertion that transport errors do not become
`*codersdk.Error`.

## Refactor

1. Run `gofmt` on touched Go files.
2. Check import cleanup and variable names after the implementation
compiles.
3. Keep the change limited to the reusable helper and this test.

## Verification

1. `go test ./codersdk -run TestResolveWorkspace -count=100`
2. `go test ./testutil ./codersdk -run TestResolveWorkspace -count=1`
3. `git diff --check`

</details>
2026-06-08 15:11:36 +01:00
Danielle Maywood d751b46a19 fix: scope combined chat source filters (#26137) 2026-06-08 15:05:27 +01:00
Jaayden Halko 9db70b6ec8 fix(site): prevent chat search filter pills from overflowing the dialog (#26095)
Long filter values (for example diff URLs) were widening the chat search
dialog instead of staying inside the search box, and some passthrough
filters did not round-trip cleanly through the backend query parser.

This fixes the filter pills so long values truncate inside the search
box
(with the full value available via a hover tooltip), and normalizes
passthrough filters so values containing spaces or colons are quoted and
re-parse identically.

closes CODAGT-556
2026-06-08 14:53:29 +01:00
fff58bdc13 feat(site): create Template Builder components (#25123)
This PR introduces several components used in the Template Builder
designs:

Base template card
<img width="364" height="248" alt="Screenshot 2026-05-11 at 10 10 49 AM"
src="https://github.com/user-attachments/assets/a948acef-46ba-4b91-adb9-acb3c905f0ab"
/>

Base template customization
<img width="858" height="401" alt="Screenshot 2026-05-11 at 10 11 55 AM"
src="https://github.com/user-attachments/assets/bd688291-00b5-4d9d-b98e-a9887cd97067"
/>

Module card
<img width="406" height="226" alt="Screenshot 2026-05-11 at 10 17 43 AM"
src="https://github.com/user-attachments/assets/7fa0b515-921b-47aa-a451-07a8be7356f7"
/>

Module customization
<img width="859" height="374" alt="Screenshot 2026-05-11 at 10 11 20 AM"
src="https://github.com/user-attachments/assets/c9327da4-7539-4456-b2fc-331de40b4779"
/>

Selection overview
<img width="258" height="528" alt="Screenshot 2026-05-11 at 10 11 02 AM"
src="https://github.com/user-attachments/assets/ddab9fe3-2b45-4204-98c2-d39fd454e969"
/>



> Parts of this PR were written by Claude Code 🤖 and other parts by
yours truly 👨‍💻

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Andrew Aquino <dawneraq@gmail.com>
2026-06-08 08:59:49 -04:00
Jaayden Halko 70c0ffcfb5 fix(site/src): horizontally scroll wide code blocks in agent chat (#26016)
closes CODAGT-467

 ## Problem

In the agent chat timeline, wide tool-preview code blocks did not wrap
**and** had no usable horizontal scroll. Long lines were clipped and
unreachable for mouse users.

Root cause: file/code/JSON previews (`read_file`, generic & MCP tool
input/output) and markdown fenced code blocks render through
`@pierre/diffs`, whose `[data-code]` grid grows to its content width
(`align-self: flex-start`). The wrapping `ScrollArea` only rendered a
**vertical** scrollbar, so although the viewport was horizontally
scrollable, there was no scrollbar affordance and the overflow was
clipped.

## Fix

Render a horizontal scrollbar on these previews via `ScrollArea
orientation="both"`, exposing the already-scrollable viewport with a
visible 6px bar (consistent with the existing hover scrollbars). For
markdown, let `[data-code]` size to its content so the outer
`ScrollArea` owns the scroll.

Shell/log output (`execute`, `process_output`) and diffs (`write_file`,
`edit_files`) intentionally keep **wrapping**.

| Preview type | Behavior |
| --- | --- |
| `read_file`, generic/MCP input & output, markdown fenced code |
horizontal **scroll** (new) |
| `execute`, `process_output` (shell/logs) | wrap (unchanged) |
| `write_file`, `edit_files` (diffs) | wrap (unchanged) |

## Changes

- `ScrollArea`: add `horizontalScrollBarClassName` to size the
horizontal bar independently of the vertical bar (avoids a `twMerge`
width/height conflict).
- `ReadFileTool`, generic `ToolFileViewer` (`Tool.tsx`):
`orientation="both"` + thin horizontal bar.
- `Response.tsx`: wrap fenced code in a both-axis `ScrollArea`; let
`[data-code]` size to content.
- Long-line regression stories for the file viewer, generic tool, and
markdown.
- Change scrollbar color to accessible contrast ratio
- Increase hit area for scroll bars to 24px which is minimim for wcag
2.2 accessibility requirements

<details>
<summary>Implementation notes & decisions</summary>

- The `@pierre/diffs` `File` viewer only supports `overflow: "scroll" |
"wrap"`. Its `[data-code]` element is a grid with `overflow: scroll
clip` that grows to content width instead of scrolling, so the outer
container must provide the scroll affordance.
- Chosen approach: surface the **outer** `ScrollArea`'s horizontal
scrollbar (the viewport was already scrollable) rather than fighting the
library's internal per-block scroll. This yields a single, unified
horizontal scrollbar and guarantees the timeline never exceeds the
viewport (the `ScrollArea` root is `overflow: hidden`).
- Scroll vs wrap was chosen per content type: code/JSON/file structure
benefits from scrolling (wrapping breaks indentation and line-number
alignment), while shell/log output keeps wrapping. Precedent for visible
horizontal scrollbars already exists in `GitPanel`/`TaskApps`.

</details>

---

_Generated by Coder Agents on behalf of @jaaydenh._
2026-06-08 12:56:19 +01:00
Mathias Fredriksson 3955df796e fix(agent): unify working directory resolution (#26102)
agentssh's CommandEnv, sftpHandler, and agentproc each resolved the
session working directory on their own and had drifted: sftpHandler used
the configured directory without checking it exists and bypassed the
injected EnvInfoer, while the others stat-checked and fell back to home.
Home and shell lookups could also skip the EnvInfoer seam through the
exported usershell.HomeDir and Get.

Resolve through a single usershell.ResolveWorkingDirectory and confine
host home and shell lookups to usershell, so SSH sessions, the process
API, and tests can no longer diverge and the injected environment is
always honored. This also fixes SFTP landing in a configured directory
that no longer exists.

Refs coder/coder#26099
2026-06-08 14:24:32 +03:00
Danielle Maywood 1e5dd83a95 fix: limit shared chats to ACL grants (#26123) 2026-06-08 12:21:16 +01:00
Cian Johnston 8ae1a5c766 fix(dogfood/coder): disable gh terminal color probes (#26114)
Newer GitHub CLI versions probe terminal colors before interactive
prompts, which can leave OSC responses in dogfood web terminal stdin and
break `gh auth login`.

Default `NO_COLOR=1` inside the dogfood `/usr/local/bin/gh` wrappers
when callers have not set it themselves. This avoids the color probe
without pinning or downgrading `gh`, and keeps the existing Coder
external-auth wrapper behavior intact.

Refs ENG-2842.

> 🤖 Generated by Coder Agents on behalf of @johnstcn.
2026-06-08 09:31:31 +01:00
Danny Kopping 9afd3d0bea feat: track OpenCode sessions (#26128)
This follows #26098 by teaching AI Bridge to read OpenCode session IDs
from the X-OpenCode-Session header, so OpenCode requests are grouped
consistently in interception logs.

Adds unit and integration test coverage for the new header.

<details>
<summary>Coder Agents generated</summary>

This pull request was generated with Coder Agents assistance.
</details>
2026-06-08 10:12:03 +02:00
Atif Ali 2211f9ce4b docs(docs/ai-coder/ai-gateway/clients): update VS Code to reflect 1.122 Custom Endpoint support (#26126)
Updates the VS Code AI Gateway client docs to reflect the Custom
Endpoint provider introduced in VS Code 1.121 (Insiders) and promoted to
Stable in 1.122.

## Changes

**`docs/ai-coder/ai-gateway/clients/vscode.md`**
- Replace the deprecated `customoai` vendor with `customendpoint`
- Add the required `apiType` field (`responses` for OpenAI, `messages`
for Anthropic)
- Add Anthropic provider setup (Messages API type, base URL
`…/aibridge/anthropic`)
- Note GitHub sign-in is no longer required — works in
air-gapped/restricted environments
- Add limitation callout: inline suggestions and NES still require
GitHub Copilot
- Reflect the UI-first API key entry flow (VS Code stores the token
securely; do not paste into JSON directly)
- Drop the Centralized/BYOK split — VS Code has no template injection
path, so both scenarios follow the same user-driven UI flow

**`docs/ai-coder/ai-gateway/clients/index.md`**
- VS Code compatibility row: Anthropic ``
- Updated Notes column

<details>
<summary>Research notes</summary>

- VS Code 1.121 shipped the Custom Endpoint provider (Insiders),
replacing the legacy OpenAI Compatible (`customoai`) provider which is
now deprecated.
- VS Code 1.122 promoted Custom Endpoint to Stable and removed the
GitHub sign-in requirement for BYOK.
- Anthropic support confirmed working: `apiType: "messages"` + base URL
`…/api/v2/aibridge/anthropic` (Coder's gateway accepts the Coder session
token as `x-api-key`).
- OpenAI uses `apiType: "responses"` + base URL
`…/api/v2/aibridge/openai`.
- API keys must be entered via the Manage Language Models UI — VS Code
stores them securely and references them as
`${input:chat.lm.secret.XXXXX}` in the JSON.
</details>

> This PR was drafted by Coder Agents on behalf of @matifali.
2026-06-08 07:35:20 +00:00
Danny Kopping 47a8c9572f feat: add OpenCode AI Bridge client support (#26098)
Adds OpenCode to AI Bridge client detection so requests with user agents
like `opencode/1.16.0 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14`
show up as a first-class client instead of `Unknown`.

This also wires the existing OpenCode frontend asset into the AIBridge
UI, adds a Storybook story for the client icon, and updates the
monitoring docs list of supported client values.

<details>
<summary>Coder Agents generated</summary>

This pull request was generated by Coder Agents.

</details>
2026-06-08 06:26:30 +02:00
Steven Masley 69f9b0e535 feat(site): show org default roles in member role editor (#26107)
Surfaces the org's `default_org_member_roles` inside the org members role editor. These roles are implied, not physically assigned to any member. Just like the `member` role.
2026-06-05 20:51:20 -05:00
Danielle Maywood fa56224eda feat: show shared chats in agents sidebar (#26056) 2026-06-06 00:12:20 +01:00
Steven Masley 4124d5be1e feat(site): add Default Roles section to organization roles page (#26028)
Adds a `Default Roles` section to the org Roles page that edits an org's `default_org_member_roles` via the existing PATCH endpoint.
2026-06-05 17:47:56 -05:00
Nick Vigilante 9d85eb2fa0 docs(docs/tutorials/quickstart.md): recommend free container runtimes besides Docker Desktop (#26106)
Replaces the quickstart's "Install Docker" step with a runtime-agnostic
"Install a container runtime" step, and switches the per-platform
defaults
to free, lightweight options that avoid Docker Desktop's cost and
overhead.

A callout above the OS tabs names Colima, Rancher Desktop, Podman, and
Docker Desktop as valid runtimes and tells readers to skip ahead if they
already have one running. The default install path per platform is now:

- Linux: Docker Engine (unchanged from the previous doc)
- macOS: Colima with the Docker CLI
- Windows: Podman Desktop

The "Cannot connect to the Docker daemon" troubleshooting subsections
are
updated to match the new defaults.

Closes
[DEVREL-22](https://linear.app/codercom/issue/DEVREL-22/recommend-orbstackcolimarancher-desktoppodman-as-docker-desktop).

A follow-up Linear issue will track a deeper "Docker runtime
alternatives"
reference page covering OrbStack (with its commercial-license caveat),
Rancher Desktop, and CLI Podman.

<details>
<summary>Implementation proposal and pre-mortem</summary>

# DEVREL-22 proposal: Replace "Install Docker" with "Install a container
runtime"

Linear:
[DEVREL-22](https://linear.app/codercom/issue/DEVREL-22/recommend-orbstackcolimarancher-desktoppodman-as-docker-desktop)
Repo: `coder/coder`
Branch:
`vigilante/devrel-22-recommend-orbstackcolimarancher-desktoppodman-as-docker`
Primary file: `docs/tutorials/quickstart.md`

## Summary

Rename Step 1 of the quickstart from "Install Docker and set up
permissions" to "Install a container runtime", add a callout that any
Docker-compatible runtime works, and switch the per-platform default to
the lightest free path on each OS. Keep Docker Desktop, OrbStack, and
Rancher Desktop as documented alternatives, but not as the primary
recommendation. The deeper "alternatives" reference page is a follow-up.

## Why

- Docker Desktop is slow on macOS/Windows and requires a paid license
for most commercial use.
- The Coder Quickstart template only needs the Docker daemon, not Docker
Desktop's GUI.
- No single tool satisfies "curl install + cross-platform + free +
minimal setup", so a per-platform recommendation is the honest answer.

## Per-platform defaults

| Platform | Default in quickstart | Why |
|----------|----------------------|-----|
| Linux | Docker Engine via `curl -sSL https://get.docker.com \| sh` |
Already in the doc, already a curl one-liner, already free. No change. |
| macOS | Colima | Two commands (`brew install colima docker`, `colima
start`), free for commercial use, exposes `/var/run/docker.sock` so the
Coder template needs zero env vars. |
| Windows | Podman Desktop | Free, handles WSL2 prereq and `podman
machine` setup through the GUI, sets up Docker socket compatibility.
Lighter than Docker Desktop, simpler than CLI Podman + `DOCKER_HOST`. |

## Pre-mortem

1. **Coder Quickstart template assumes `/var/run/docker.sock`.** Colima
symlinks it on macOS. Podman Desktop on Windows enables Docker socket
compatibility by default, so the template's Docker provider should reach
the daemon without `DOCKER_HOST` gymnastics.
2. **External links into
`quickstart#step-1-install-docker-and-set-up-permissions`.** A grep of
`docs/` and `site/` found no internal references to the old anchor. Blog
posts or external links may land at the top of the page after the
rename; acceptable for this scope.
3. **Brew assumption on macOS.** Recommending `brew install colima
docker` assumes Homebrew. The callout links to brew.sh so users without
it can install Homebrew first.
4. **WSL2 on Windows.** Podman Desktop's onboarding installs WSL2 if
missing. Corporate-managed machines that block WSL2 can fall back to
other runtimes named in the callout.
5. **Onboarding tone shift.** "Container runtime" is more abstract than
"Docker." The callout names Docker Desktop as a runtime first, so the
unfamiliar phrase is anchored immediately.
6. **OrbStack license trap.** OrbStack is intentionally not in the
quickstart's default path because it is paid for commercial use. It will
be mentioned on the future alternatives page with the license caveat
called out explicitly.

## Out of scope (follow-up issues)

- New "Docker runtime alternatives" reference page covering OrbStack,
Rancher Desktop, CLI Podman, with license and compatibility notes.
- `docs/install/docker.md` updates. That page is about installing Coder
server in a Docker container, which is a separate concern.
- Updating the `coder/skills` `setup` skill if its install steps drift
from the new quickstart.
- Updating the Coder Quickstart template's description in
`coder/registry` if it links to the renamed section.

</details>

This pull request was generated by a Coder agent on behalf of
@nickvigilante.
2026-06-05 22:03:51 +00:00
Steven Masley f17f8392bd feat(coderd): gate org-member workspace elevation behind experiment (#26027)
Gates the workspace-ops elevation on `organization-member` and `organization-service-account` behind the `minimum-implicit-member` experiment.
2026-06-05 15:31:33 -05:00
Steven Masley 8a5e04e90f test: include per-org default roles in rbac user subjects (#26003)
Aligns the `coderdtest` user subject helper with production so per-org default member roles surface in tests.
2026-06-05 15:01:45 -05:00
Steven Masley 938c2080f3 feat: configurable default org member roles (#25994)
Refs #25936. 
Adds a configurable per-org default member role set. Unioned into each member's effective roles at read time.

<sub>with Coder Agents on behalf of @Emyrk.</sub>
2026-06-05 14:33:13 -05:00
Andrew Aquino 2ef468ef76 test: reset pointer-events before each Storybook story (#26081)
fixes DEVEX-402

Alternative to #26077, which aimed to address this flake in
UsersPage.stories.tsx only:

>Unable to perform pointer interaction as the element has
`pointer-events: none`

In the original PR I was going to "fix" the flake by adding
`pointerEventsCheck: Never` like we have in 2 other tests. However,
resetting `pointer-events` during `beforeEach` in our global Vitest
setup removes the need for that `pointerEventsCheck` workaround. 🙂

tl;dr: Each of these 3 tests were failing because of an immediately
preceding test which opens a Radix Dialog, setting `pointer-events:
none` on the body element.

Co-written with Coder Agents. Relevant chat responses:

>**The actual root cause is story isolation.** The previous story
(`UpdateUserRoleSuccess`) opens a Radix Dialog, which triggers Radix's
`DismissableLayer` to set `document.body.style.pointerEvents = "none"`.
When that story completes, Storybook unmounts the React tree, but the
cleanup of `body.style.pointerEvents` is tied to a `useEffect` cleanup
in `DismissableLayer`. If Storybook begins the next story's play
function before the browser has fully flushed the previous unmount
cycle, `document.body.style.pointerEvents` is still `"none"`. The "Open
menu" button, which is a plain table button with no Radix modal layer
above it providing `pointer-events: auto`, inherits `"none"` from body,
and the first click fails.
>
>**Why it's flaky:** The Storybook Vitest plugin
(`@storybook/addon-vitest`) runs stories sequentially in the same
browser page. When `UpdateUserRoleSuccess` finishes, React unmounts the
tree, and `DismissableLayer`'s `useEffect` cleanup should restore
`body.pointerEvents`. But there's a race between unmount cleanup
completing and the next story's play function starting. Sometimes
cleanup wins (test passes), sometimes the play function wins (test
fails).
>
>**[#26077]'s `pointerEventsCheck: Never`** works but is a workaround.
It doesn't address the leaked state, and `UpdateUserRoleSuccess` itself
could be flaky too (if whatever story precedes it leaves the same stale
state). The other stories in the same file (Suspend, Delete, Activate,
ResetPassword) all open Radix Dialogs too, so any of them could leak
this state to the next story.
2026-06-05 12:05:28 -07:00
Jessica Winters e21e3e5826 chore: add attributions to Discord links in README.md (#26113)
Got a request to update the Discord links with an attribution so we can track where customers are coming from when joining!
2026-06-05 12:00:42 -07:00
Mathias Fredriksson d00ffbd828 feat(agent): unify session env via EnvInfoer (#26099)
The agent resolved the session home directory two ways. agentssh went
through usershell, while agentproc called os.UserHomeDir directly and
skipped its user.Current fallback. Routing both through a single
usershell.EnvInfoer makes the resolution consistent, and agentproc
now gets the same fallback as the rest of the agent.

The shared seam is injectable, so SSH session tests can drive
environment resolution without touching real system state.
2026-06-05 21:22:23 +03:00
Mathias Fredriksson 578793be1d fix(coderd/x/chatd): disclose execute shell is POSIX sh (#26101) 2026-06-05 19:02:52 +03:00
Zach d1f2dec4ff fix: align autostart tests with persisted next_start_at (#26037)
`TestExecutorAutostartOK` and its sibling positive autostart tests
compute the autobuild tick from
`sched.Next(workspace.LatestBuild.CreatedAt)`, but the server persists
`next_start_at` from the build's completion time. When build creation
and completion straddle the schedule's next fire time, the persisted
value advances past the test's tick, the executor's eligibility query
(`next_start_at <= tick`) drops the workspace, and the test fails with
an empty transitions map. This surfaced in flaky test runs.

Add `coderdtest.NextAutostartTick(t, workspace)` which returns
`*workspace.NextStartAt`, and use it across the affected positive
autostart paths in `coderd/autobuild`, `coderd`, and
`enterprise/coderd`.

Generated with assistance from Coder Agents.
2026-06-05 09:55:32 -06:00
Jon Ayers 1f8a8e8356 fix: fix flakiness in nats localsub test (#26084)
fixes https://github.com/coder/internal/issues/1552
2026-06-05 10:47:36 -05:00
Steven Masley bec2115e75 refactor: extract organization-workspace-access role (#25929)
<!-- Authored by Coder Agents on behalf of @Emyrk. -->

Refs
[PLAT-217](https://linear.app/codercom/issue/PLAT-217/rfc-for-gateway-accounts).

Extracts an `organization-workspace-access` role so workspace elevation
can be split off the organization-member floor without changing
behavior.

- New role holds the workspace-side resources currently granted by
`organization-member`.
- The `MinimumImplicitMember` floor preserves the existing behavior
until #26027 shrinks it.
- Prebuilds orchestrator inserts memberships via
`dbauthz.AsSystemRestricted` and no longer needs `OrganizationMember` or
`AssignOrgRole` grants.

<details><summary>Agent context</summary>

- `coderd/rbac/roles.go`: `OrgWorkspaceAccessMemberPerms()` grants
`Workspace`, `WorkspaceDormant`, `File` (Create+Read),
`ProvisionerDaemon` (Create+Read), and `Task`. Deliberate omissions
(`Template`, `Group`, `WorkspaceProxy`, etc.) are documented inline.
- `coderd/rbac/roles_test.go`: `orgWorkspaceAccessUser` is added to
`requiredSubjects`. `UserProvisionerDaemons` is split into
`UserProvisionerDaemonsCreate` and `UserProvisionerDaemonsUpdateDelete`
because the new role grants Create+Read only and the test framework
requires uniform pass/fail per case.
- `codersdk/rbacroles.go`: exposes `RoleOrganizationWorkspaceAccess`.
- `enterprise/coderd/prebuilds/membership.go`:
`InsertOrganizationMember` runs under `dbauthz.AsSystemRestricted`. The
orchestrator never acts with the elevation role; the membership row only
exists so prebuilt workspaces have a valid owner.
- `coderd/database/dbauthz/dbauthz.go`: drops the now-dead
`OrganizationMember` and `AssignOrgRole` permissions from the
prebuilds-orchestrator role and the orchestrator's entry in
`assignRoles`.

</details>

---

<sub>Coder Agents on behalf of @Emyrk.</sub>
2026-06-05 10:30:31 -05:00
Cian Johnston 63cd8a8c01 fix: clamp template port sharing level in SubAgentAPI (#26061)
Fixes an issue where sub-agent apps created via CreateSubAgent would
bypass the check for the template's max port sharing level:

- Clamps dynamically inserted `workspace_apps` to the template max
sharing level in `coderd.agentapi.SubAgentAPI`.
- Emits a warning when clamping occurs.
- Adds unit test coverage for the max sharing level matrix.
- Adds an integration-ish test through the devcontainer sub-agent client
path.

> 🤖 Generated by Coder Agents with guidance from a human.
2026-06-05 16:30:15 +01:00
dependabot[bot] 5d8cd2ea7c chore: bump go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from 0.68.0 to 0.69.0 (#26042)
Bumps
[go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib)
from 0.68.0 to 0.69.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/releases">go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp's
releases</a>.</em></p>
<blockquote>
<h2>v1.44.0/v2.5.1/v0.69.0/v0.37.1/v0.24.0/v0.19.0/v0.16.1/v0.16.0</h2>
<h3>Added</h3>
<ul>
<li>Add <code>error.type</code> attribute to
<code>http.client.request.duration</code> for transport failures in
<code>otelhttp</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8801">#8801</a>)</li>
<li>Add examples for prometheus compatibility document. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8716">#8716</a>)</li>
<li>Add support for <code>cardinality_limits</code> in
<code>PeriodicMetricReader</code> in <code>otelconf</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8885">#8885</a>)</li>
<li>Add <code>Resource</code> method to <code>SDK</code> in
<code>go.opentelemetry.io/contrib/otelconf/x</code> to expose the
resolved SDK resource from declarative configuration. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8913">#8913</a>)</li>
<li>Add <code>go.opentelemetry.io/contrib/detectors/hetzner</code>, a
new resource detector for Hetzner Cloud servers, ported from
<code>github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/hetzner</code>.
Detects <code>cloud.provider</code>, <code>cloud.platform</code>,
<code>cloud.region</code>, <code>cloud.availability_zone</code>,
<code>host.id</code>, and <code>host.name</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8979">#8979</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Set error field as <code>record.SetErr</code> instead of a plain
attribute in
<code>go.opentelemetry.io/contrib/bridges/otellogrus</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8776">#8776</a>)</li>
<li>Set the &quot;error&quot; field (e.g. created via
<code>zap.Error</code>) as <code>record.SetErr</code> instead of a plain
attribute in <code>go.opentelemetry.io/contrib/bridges/otelzap</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8719">#8719</a>)</li>
<li>Set fields implementing <code>error</code> interface from
<code>slog</code> records as <code>record.SetErr</code> instead of plain
attributes in <code>go.opentelemetry.io/contrib/bridges/otelslog</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8774">#8774</a>)</li>
<li>Set emitted errors in
<code>go.opentelemetry.io/contrib/bridges/otellogr</code> as record
errors (<code>Record.SetErr</code>) instead of
<code>exception.message</code> attributes. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8775">#8775</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix header attributes lost when using sub-spans in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8797">#8797</a>)</li>
<li>Validate <code>encoding</code> configuration for OTLP HTTP exporters
in <code>go.opentelemetry.io/contrib/otelconf</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8772">#8772</a>)</li>
<li>Remove the custom body wrapper from the request's body after the
request is processed to allow body type comparisons with the original
type in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code>
and
<code>go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/6914">#6914</a>)</li>
<li>Unknown or empty HTTP methods now report &quot;_OTHER&quot; instead
of &quot;GET&quot; across all HTTP instrumentations to align with
OpenTelemetry semantic conventions. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8868">#8868</a>)</li>
<li>The default span name formatter in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code>
now conforms to the OpenTelemetry HTTP semantic conventions for server
span names. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8871">#8871</a>)
<ul>
<li>The default span name is now <code>{method} {route}</code> (e.g.
<code>GET /foo/{id}</code>) when a route pattern is available, or
<code>{method}</code> (e.g. <code>GET</code>) otherwise.</li>
</ul>
</li>
</ul>
<h3>Removed</h3>
<ul>
<li>Remove the deprecated <code>WithSpanOptions</code> option in
<code>go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8991">#8991</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>otelconf: validate encoding configuration for OTLP HTTP exporters by
<a href="https://github.com/sonalgaud12"><code>@​sonalgaud12</code></a>
in <a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8772">open-telemetry/opentelemetry-go-contrib#8772</a></li>
<li>fix(deps): update module github.com/aws/aws-sdk-go-v2/service/s3 to
v1.99.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8780">open-telemetry/opentelemetry-go-contrib#8780</a></li>
<li>chore(deps): update prom/prometheus docker tag to v3.11.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8779">open-telemetry/opentelemetry-go-contrib#8779</a></li>
<li>otellogrus: Set error field as <code>record.SetErr</code> by <a
href="https://github.com/sonalgaud12"><code>@​sonalgaud12</code></a> in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8778">open-telemetry/opentelemetry-go-contrib#8778</a></li>
<li>chore(deps): update module golang.org/x/sys to v0.43.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8783">open-telemetry/opentelemetry-go-contrib#8783</a></li>
<li>chore(deps): update golang.org/x/telemetry digest to 93c7c8a by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8786">open-telemetry/opentelemetry-go-contrib#8786</a></li>
<li>chore(deps): update module github.com/mattn/go-isatty to v0.0.21 by
<a href="https://github.com/renovate"><code>@​renovate</code></a>[bot]
in <a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8787">open-telemetry/opentelemetry-go-contrib#8787</a></li>
<li>chore(deps): update module github.com/mattn/go-runewidth to v0.0.23
by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8788">open-telemetry/opentelemetry-go-contrib#8788</a></li>
<li>chore(deps): update golang.org/x by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8791">open-telemetry/opentelemetry-go-contrib#8791</a></li>
<li>chore(deps): update actions/github-script action to v9 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8795">open-telemetry/opentelemetry-go-contrib#8795</a></li>
<li>fix(deps): update golang.org/x by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8794">open-telemetry/opentelemetry-go-contrib#8794</a></li>
<li>otelzap: set error field as record.SetErr by <a
href="https://github.com/iblancasa"><code>@​iblancasa</code></a> in <a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8719">open-telemetry/opentelemetry-go-contrib#8719</a></li>
<li>fix(deps): update golang.org/x to 746e56f by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8796">open-telemetry/opentelemetry-go-contrib#8796</a></li>
<li>chore(deps): update module golang.org/x/arch to v0.26.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8798">open-telemetry/opentelemetry-go-contrib#8798</a></li>
<li>Check if otelgrpc metrics are enabled by <a
href="https://github.com/dashpole"><code>@​dashpole</code></a> in <a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8792">open-telemetry/opentelemetry-go-contrib#8792</a></li>
<li>chore(deps): update actions/upload-artifact action to v7.0.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8800">open-telemetry/opentelemetry-go-contrib#8800</a></li>
<li>Check instrument enabled in deprecatedruntime by <a
href="https://github.com/dashpole"><code>@​dashpole</code></a> in <a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8793">open-telemetry/opentelemetry-go-contrib#8793</a></li>
<li>chore(deps): update module github.com/ashanbrown/forbidigo/v2 to
v2.3.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8804">open-telemetry/opentelemetry-go-contrib#8804</a></li>
<li>chore(deps): update module github.com/ashanbrown/makezero/v2 to
v2.2.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8802">open-telemetry/opentelemetry-go-contrib#8802</a></li>
<li>chore(deps): update module github.com/manuelarte/funcorder to v0.6.0
by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/pull/8803">open-telemetry/opentelemetry-go-contrib#8803</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md">go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp's
changelog</a>.</em></p>
<blockquote>
<h2>[1.44.0/2.5.1/0.69.0/0.37.1/0.24.0/0.19.0/0.16.1/0.16.0] -
2026-05-28</h2>
<h3>Added</h3>
<ul>
<li>Add <code>error.type</code> attribute to
<code>http.client.request.duration</code> for transport failures in
<code>otelhttp</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8801">#8801</a>)</li>
<li>Add examples for prometheus compatibility document. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8716">#8716</a>)</li>
<li>Add support for <code>cardinality_limits</code> in
<code>PeriodicMetricReader</code> in <code>otelconf</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8885">#8885</a>)</li>
<li>Add <code>Resource</code> method to <code>SDK</code> in
<code>go.opentelemetry.io/contrib/otelconf/x</code> to expose the
resolved SDK resource from declarative configuration. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8913">#8913</a>)</li>
<li>Add <code>go.opentelemetry.io/contrib/detectors/hetzner</code>, a
new resource detector for Hetzner Cloud servers, ported from
<code>github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/hetzner</code>.
Detects <code>cloud.provider</code>, <code>cloud.platform</code>,
<code>cloud.region</code>, <code>cloud.availability_zone</code>,
<code>host.id</code>, and <code>host.name</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8979">#8979</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Set error field as <code>record.SetErr</code> instead of a plain
attribute in
<code>go.opentelemetry.io/contrib/bridges/otellogrus</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8776">#8776</a>)</li>
<li>Set the &quot;error&quot; field (e.g. created via
<code>zap.Error</code>) as <code>record.SetErr</code> instead of a plain
attribute in <code>go.opentelemetry.io/contrib/bridges/otelzap</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8719">#8719</a>)</li>
<li>Set fields implementing <code>error</code> interface from
<code>slog</code> records as <code>record.SetErr</code> instead of plain
attributes in <code>go.opentelemetry.io/contrib/bridges/otelslog</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8774">#8774</a>)</li>
<li>Set emitted errors in
<code>go.opentelemetry.io/contrib/bridges/otellogr</code> as record
errors (<code>Record.SetErr</code>) instead of
<code>exception.message</code> attributes. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8775">#8775</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix header attributes lost when using sub-spans in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8797">#8797</a>)</li>
<li>Validate <code>encoding</code> configuration for OTLP HTTP exporters
in <code>go.opentelemetry.io/contrib/otelconf</code>. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8772">#8772</a>)</li>
<li>Remove the custom body wrapper from the request's body after the
request is processed to allow body type comparisons with the original
type in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code>
and
<code>go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/6914">#6914</a>)</li>
<li>Unknown or empty HTTP methods now report &quot;_OTHER&quot; instead
of &quot;GET&quot; across all HTTP instrumentations to align with
OpenTelemetry semantic conventions. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8868">#8868</a>)</li>
<li>The default span name formatter in
<code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code>
now conforms to the OpenTelemetry HTTP semantic conventions for server
span names. (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8871">#8871</a>)
<ul>
<li>The default span name is now <code>{method} {route}</code> (e.g.
<code>GET /foo/{id}</code>) when a route pattern is available, or
<code>{method}</code> (e.g. <code>GET</code>) otherwise.</li>
</ul>
</li>
</ul>
<h3>Removed</h3>
<ul>
<li>Remove the deprecated <code>WithSpanOptions</code> option in
<code>go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc</code>.
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8991">#8991</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/03b2bcdb54b3dde73c9ff91ae216aec262f6c8f5"><code>03b2bcd</code></a>
Release v1.44.0/v2.5.1/v0.69.0/v0.37.1/v0.24.0/v0.19.0/v0.16.1/v0.16.0
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9033">#9033</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/80c46d4037d5991ce324216a52cf7e8d7f2d81fa"><code>80c46d4</code></a>
chore(deps): update module github.com/alecthomas/chroma/v2 to v2.26.0
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9034">#9034</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/51f292197d33b84a21b3c70ae21cb185a2570d5e"><code>51f2921</code></a>
fix(deps): update module github.com/hetznercloud/hcloud-go/v2 to v2.41.2
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9026">#9026</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/db82162f1b642bb6dca7fa5be48045315bb466d6"><code>db82162</code></a>
fix(deps): update aws-sdk-go-v2 monorepo (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9031">#9031</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/5a3e533d8cd4045128e61a966f6dad58964a78ea"><code>5a3e533</code></a>
fix(deps): update module github.com/aws/smithy-go to v1.26.0 (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9032">#9032</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/c67843c753a924faef17bc4aa63c138aa9472477"><code>c67843c</code></a>
otelhttp: Remove custom wrapper after handling request (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/6914">#6914</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/c0a41352283151ab6655e88120e4ff4f0a917a2e"><code>c0a4135</code></a>
docs(otelhttptrace): add performance guidance for WithoutSubSpans (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8785">#8785</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/a51a86790e1f4df231a70bb5fecc72b95d3c1bf0"><code>a51a867</code></a>
otelconf: implement cardinality_limits support in PeriodicMetricReader
(<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8885">#8885</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/dead6e50fc0b5b3dc4aea288df207953dae5afe7"><code>dead6e5</code></a>
chore(deps): update module go.yaml.in/yaml/v2 to v2.4.4 (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/8994">#8994</a>)</li>
<li><a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/979ce1857524394d0884fd7c491722c5bcb43d50"><code>979ce18</code></a>
chore(deps): update module github.com/jgautheron/goconst to v1.10.2 (<a
href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/9030">#9030</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.68.0...zpages/v0.69.0">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-05 12:37:40 +00:00
dependabot[bot] 7e3ac4a85e chore: bump google.golang.org/api from 0.280.0 to 0.283.0 (#26045)
Bumps
[google.golang.org/api](https://github.com/googleapis/google-api-go-client)
from 0.280.0 to 0.283.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's
releases</a>.</em></p>
<blockquote>
<h2>v0.283.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.282.0...v0.283.0">0.283.0</a>
(2026-06-01)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3609">#3609</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ed84bb800c56d3f7fee4c11f96673114e94a8cc2">ed84bb8</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3611">#3611</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3855346eda7f4ba6c844d86de5de493d3e395f00">3855346</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3612">#3612</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/32624d32240ec8e5997810fb9cb54f8000b6c7f8">32624d3</a>)</li>
</ul>
<h2>v0.282.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.281.0...v0.282.0">0.282.0</a>
(2026-05-27)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3607">#3607</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3c139a07f71096667d5a623591ddb37dacd38d55">3c139a0</a>)</li>
</ul>
<h2>v0.281.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.280.0...v0.281.0">0.281.0</a>
(2026-05-26)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3600">#3600</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/bcaee85f93824a21f5441c2ccd3b4d4811d97de7">bcaee85</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3602">#3602</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f0071d379f4443ffdae9994fe141b1b5e0c18a62">f0071d3</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3603">#3603</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/b1aa9dea8c3c0e539c8d9687c99c55ec3679c996">b1aa9de</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3604">#3604</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/711e008d9caf16e6fb68c860f83a28fd0a8c0f98">711e008</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3606">#3606</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3ad8e8e2ab4ae50862c0fc5b17efa2d3cda33d9a">3ad8e8e</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.282.0...v0.283.0">0.283.0</a>
(2026-06-01)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3609">#3609</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ed84bb800c56d3f7fee4c11f96673114e94a8cc2">ed84bb8</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3611">#3611</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3855346eda7f4ba6c844d86de5de493d3e395f00">3855346</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3612">#3612</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/32624d32240ec8e5997810fb9cb54f8000b6c7f8">32624d3</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.281.0...v0.282.0">0.282.0</a>
(2026-05-27)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3607">#3607</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3c139a07f71096667d5a623591ddb37dacd38d55">3c139a0</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.280.0...v0.281.0">0.281.0</a>
(2026-05-26)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3600">#3600</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/bcaee85f93824a21f5441c2ccd3b4d4811d97de7">bcaee85</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3602">#3602</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f0071d379f4443ffdae9994fe141b1b5e0c18a62">f0071d3</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3603">#3603</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/b1aa9dea8c3c0e539c8d9687c99c55ec3679c996">b1aa9de</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3604">#3604</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/711e008d9caf16e6fb68c860f83a28fd0a8c0f98">711e008</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3606">#3606</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3ad8e8e2ab4ae50862c0fc5b17efa2d3cda33d9a">3ad8e8e</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/f6726366ff2f0b8fc82cec6f063dc9beb3ab1377"><code>f672636</code></a>
chore(main): release 0.283.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3610">#3610</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/32624d32240ec8e5997810fb9cb54f8000b6c7f8"><code>32624d3</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3612">#3612</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/3855346eda7f4ba6c844d86de5de493d3e395f00"><code>3855346</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3611">#3611</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/ed84bb800c56d3f7fee4c11f96673114e94a8cc2"><code>ed84bb8</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3609">#3609</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/60aebbd7406af09eb63866ff79f0dbd40cccecbb"><code>60aebbd</code></a>
chore(main): release 0.282.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3608">#3608</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/3c139a07f71096667d5a623591ddb37dacd38d55"><code>3c139a0</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3607">#3607</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/8f434ff91fe8dc299942ecd7c87ebab151ff38e5"><code>8f434ff</code></a>
chore(main): release 0.281.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3601">#3601</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/57f4b28d8c80b464f7f0b486a555de528fb89c4e"><code>57f4b28</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3605">#3605</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/3ad8e8e2ab4ae50862c0fc5b17efa2d3cda33d9a"><code>3ad8e8e</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3606">#3606</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/711e008d9caf16e6fb68c860f83a28fd0a8c0f98"><code>711e008</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3604">#3604</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-api-go-client/compare/v0.280.0...v0.283.0">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-05 12:37:19 +00:00
Ehab Younes 38ae92b6b7 chore: upgrade slog to 3.1.0 (#26096)
Changes from https://github.com/coder/slog/releases/tag/v3.1.0

This also carries the transitive dependency versions required by
`cdr.dev/slog/v3@v3.1.0`, including OpenTelemetry `v1.44.0`, Cloud
Logging `v1.18.0`, and the updated `google.golang.org/genproto` modules.
2026-06-05 15:23:04 +03:00
Ehab Younes eac7ee4975 fix(cli): discard log writes to closed pipes during shutdown (#26082)
Add clilog.DiscardOnPipeError, an io.Writer wrapper that drops writes
failing with io.ErrClosedPipe or syscall.EPIPE, and apply it to the
clilog stdout/stderr sinks and the port-forward verbose sink.

Background goroutines (e.g. port-forward -v tailnet goroutines) keep
logging after the reader on the log destination is gone. slog reports
those failed writes to stderr, which is noise and can interleave with
and corrupt go test/test2json output, misreporting passing tests as
failed. os.ErrClosed and all other errors are still returned, so writes
to a writer we closed ourselves are not hidden, and normal CLI pipe
semantics are unchanged.
2026-06-05 14:33:15 +03:00
Jaayden Halko 8883a793f7 fix(site/src/pages/AgentsPage): prevent narrow chat input overlap (#25894)
closes CODAGT-296

When both Agents side panels are open and resized wide, the chat column
could shrink below the input controls and let the mic, context, and send
actions overlap.

Keep the desktop chat panel at a 360px minimum width, keep the input
action group from shrinking, and add a Storybook regression story for
the narrow right-panel layout.
2026-06-05 11:50:34 +01:00
Jake Howell 97038ee2ef fix(site): restrict pinned chats drag to vertical-only (#26050) 2026-06-05 20:39:34 +10:00
Danielle Maywood 245a1944ea fix(site): dedupe agent tool timeline entries (#25970) 2026-06-05 11:38:07 +01:00
Michael Suchacz c4792cf104 fix: show Anthropic Opus 4.7+ thinking (#26026)
## Summary

- Updates Coder's pinned `github.com/coder/fantasy` fork to include
coder/fantasy#39.
- Exposes Anthropic `thinking_display` as a typed chat model provider
option with `summarized` and `omitted` values.
- Validates configured `thinking_display` values and maps them to
`fantasyanthropic.ProviderOptions.ThinkingDisplay`.
- Regenerates the API/UI option schemas so the admin model config form
gets a generated select field.

## Tests

- `go mod tidy`
- `make gen`
- `go test ./codersdk ./coderd/x/chatd/chatprovider ./coderd -run
'TestChatModelProviderOptions|TestAnthropicThinkingDisplayFromChat|TestProviderOptionsFromChatModelConfig_AnthropicThinkingDisplay|TestMergeMissingProviderOptions_AnthropicThinkingDisplay|TestValidateChatModelProviderOptions_AnthropicThinkingDisplay'`
- `go test ./coderd/x/chatd/... ./codersdk`
- `go test ./coderd -run
'TestValidateChatModelProviderOptions_AnthropicThinkingDisplay'`
- `pnpm --dir site exec -- biome lint --error-on-warnings
src/api/chatModelOptionsGenerated.json src/api/typesGenerated.ts`
- pre-commit hook, including fmt, lint, and slim build

> Mux working on behalf of Mike.
2026-06-05 08:37:54 +02:00
Ethan 5578ac5f3d fix(cli): bound Coder Connect SSH probe (#26090)
Coder Connect DNS should answer from the local Coder Connect resolver,
so `coder ssh --stdio` now gives the optional DNS availability probe a
100ms budget and falls back to the normal tunnel when DNS paths
blackhole absolute `.coder.` lookups instead of answering NXDOMAIN.

Closes https://github.com/coder/coder/issues/22581.
2026-06-05 16:08:20 +10:00
Callum StyanandMux 4627b01415 fix: reduce agentfake manager startup time (#25669)
Signed-off-by: Callum Styan <callumstyan@gmail.com>
Co-authored-by: Mux <noreply@coder.com>
2026-06-04 15:28:13 -07:00
Andrew AquinoandCarolina Urrea 6dedae4858 fix(site): count workspaces to delete scoped to organization (#25943)
ref DEVEX-268

branched from #24799 

^Modifies that PR to include a Storybook test to verify correct behavior
when deleting a template that's attached to a workspace

---------

Co-authored-by: Carolina Urrea <73137943+canourrea23@users.noreply.github.com>
2026-06-04 15:18:05 -07:00
Michael Suchacz 242c4d791b fix(coderd): isolate OIDC fake IDP in parallel subtests (#26075) 2026-06-04 23:03:02 +02:00
Zach 45475b803e test(agent): remove race in TestAgent_Session_TTY_QuietLogin/Hushlogin (#25865)
The subtest previously called session.Shell(), wrote "exit 0" through a
client-side PTY, and then waited indefinitely on session.Wait(). Under
the race detector the byte stream occasionally arrived at the agent
before the remote shell was in its read loop and was silently discarded;
the shell never exited, session.Wait() blocked until the go-test
watchdog kicked in and killed the test binary.

The agent writes the message of the day announcement banner
synchronously in agentssh.startPTYSession before forking the user shell.
The subtest now repeatedly sends "exit 0" and the writes/waiting on
session.Wait are time bound.

Also fixes a pre-existing test bug where the empty bytes intended to
create ~/.hushlogin were written to the MOTD path. The previous test
passed only because the MOTD file ended up empty, not because the
hushlogin code path was exercised. With the file now placed at the
correct path, the assertion genuinely validates isQuietLogin.

Generated with assistance from Coder Agents.
2026-06-04 13:52:51 -06:00
Garrett Delfosse b95697a370 ci: rewrite release workflow to be fully GitHub Actions-driven (#25162)
Replace the local interactive release CLI and legacy shell scripts with
a non-interactive Go tool (`scripts/release-action/`) and a rewritten
`release.yaml` workflow. Release managers trigger releases from the
GitHub Actions UI by selecting a branch, picking a release type (`rc`,
`release`, or `create-release-branch`), and optionally providing a
commit SHA.

The Go tool has four subcommands: `calculate-version` (computes next
version from git state), `generate-notes` (release notes from commit log
and PR metadata), `publish` (creates GitHub release with checksums), and
the workflow handles tag creation, branch creation, building, and
downstream publishing.

`scripts/version.sh` fallback now uses `git describe` (nearest ancestor
tag) instead of global latest so dev builds on release branches show the
correct version series.
2026-06-04 14:38:48 -04:00
Garrett Delfosse d5b0e93c6c fix!: reject OIDC login when email_verified claim is non-bool or absent (#25713)
## Problem

The OIDC callback checks `email_verified` via a Go type assertion
(`verifiedRaw.(bool)`). When an IdP returns the claim as a string
(`"false"`), a number, or omits it entirely, the assertion fails
silently and the email is implicitly treated as verified. Several real
IdPs (SAML-to-OIDC bridges, certain Azure AD B2C configurations) emit
string-typed booleans, making this reachable in practice.

## Fix

Add `coerceEmailVerified()` to handle `bool`, `string`
(`"true"`/`"false"`/`"1"`/`"0"` via `strconv.ParseBool`), `float64`,
`json.Number`, and `int`/`int64` variants. Rewrite the check to be
fail-closed: an absent claim, an unrecognized type, or any non-truthy
value is treated as unverified and rejected. The existing
`IgnoreEmailVerified` config option remains as an escape hatch.

Fixes https://linear.app/codercom/issue/PLAT-228

> Generated with [Coder Agents](https://coder.com) by @f0ssel

<details><summary>Implementation plan</summary>

### Production code (`coderd/userauth.go`)
- Added `encoding/json` import
- Added `coerceEmailVerified(v interface{}) (verified bool, ok bool)`
helper near EOF
- Replaced the type-assertion block (lines ~1342-1363) with fail-closed
logic that uses `coerceEmailVerified`

### Unit tests (`coderd/userauth_internal_test.go`, new file)
- Table-driven test covering: `bool`, `string` (`"true"`, `"false"`,
`"1"`, `"0"`, `"TRUE"`, `"t"`, `"f"`, `"invalid"`, `""`), `json.Number`,
`float64`, `int`, `int64`, `nil`, `[]string{}`, `map[string]string{}`

### Integration tests (`coderd/userauth_test.go`,
`coderd/users_test.go`)
- Added 3 new test cases: `EmailVerifiedMissingIgnored` (200),
`EmailVerifiedAsStringTrue` (200), `EmailVerifiedAsStringFalse` (403)
- Updated existing test cases that omitted `email_verified` and expected
success to include `"email_verified": true`

### FakeIDP (`coderd/coderdtest/oidctest/idp.go`)
- `encodeClaims` now defaults `email_verified` to `true` (like `exp`,
`aud`, `iss`) so tests that don't care about the verification flow are
unaffected
</details>
2026-06-04 14:37:19 -04:00
Garrett DelfosseandCoder Agents 53d287a139 fix(coderd)!: restrict OIDC email fallback to first-time account linking (#25712)
## Problem

`findLinkedUser` in `coderd/userauth.go` falls back to email-based user
lookup when no `linked_id` match is found. This fallback was used for
**all logins**, not just first-time linking. An attacker who registers
the victim's email at the IdP (with a different OIDC subject) bypasses
the `linked_id` check and gets matched to the victim's Coder account.

Combined with the `email_verified` type assertion bypass (PLAT-228),
this creates a chained account-takeover vector.

## Fix

Restrict the email fallback in `findLinkedUser` so that when a user
found by email already has a `user_link` with a non-empty `linked_id`
that **differs** from the current login's `linked_id`, the function
returns no user. This blocks account takeover while preserving:

- **First-time linking**: No existing `user_link` exists, email fallback
works as before.
- **Legacy links**: Empty `linked_id` (pre-migration), email fallback
still works.
- **Normal logins**: Matching `linked_id` resolves via the primary path,
no fallback needed.

Also adds a `UpdateUserLinkedID` query to backfill `linked_id` on legacy
links (only when currently empty) during login, gradually migrating them
to the secure path.

The `findLinkedUser` signature now accepts `loginType` explicitly
instead of relying on `user.LoginType`, ensuring the correct link is
checked in the legacy lookup.

## Breaking change

Marked `release/breaking`. An account whose `user_link` already has a
populated `linked_id` that does not match the subject the IdP presents
will now be denied login (403) instead of silently resolving via the
email fallback. The most likely trigger is changing
`CODER_OIDC_ISSUER_URL` (the `linked_id` is `issuer||subject`), or two
identities sharing one email. Accounts with an empty (legacy)
`linked_id` are unaffected and are backfilled on their next login.

Fixes: https://linear.app/codercom/issue/PLAT-229

<details><summary>Implementation details</summary>

### Files changed

- `coderd/userauth.go`: Core fix in `findLinkedUser` + backfill logic in
`oauthLogin`
- `coderd/database/queries/user_links.sql`: New `UpdateUserLinkedID`
query
- `coderd/database/dbauthz/dbauthz.go`: Authorization for new query
(`ActionUpdate` on the user object, matching `InsertUserLink`)
- `coderd/userauth_test.go`: New OIDC and GitHub tests
- Generated files: `queries.sql.go`, `querier.go`, `dbmock.go`,
`querymetrics.go`

### New tests

- `TestUserOIDC/OIDCEmailFallbackBlockedByExistingLink`: Attacker with a
different `sub` but the same email is rejected (403) when the victim has
an existing link (covers signups enabled and disabled).
- `TestUserOIDC/OIDCFirstTimeLinkByEmailAllowed`: User created via
SCIM/API (no `user_link`) can still link via email on first OIDC login,
and the `linked_id` is populated.
- `TestUserOIDC/OIDCLegacyLinkBackfill`: User with empty `linked_id` can
login and their `linked_id` is backfilled with the correct value.
- `TestUserOIDC/OIDCEmailFallbackBlockedByIssuerChange`: Existing link
recorded under a previous issuer is rejected (403) after the issuer
changes (documents the breaking behavior).
- `TestUserOAuth2Github/EmailFallbackBlockedByExistingLink`: GitHub
attacker with a different user ID but the victim's email is rejected
(403).

</details>

> [!NOTE]
> This PR was authored by Coder Agents on behalf of @f0ssel.

---------

Co-authored-by: Coder Agents <agents@coder.com>
2026-06-04 14:36:56 -04:00
Garrett Delfosse 76bf462bbf fix(coderd): prevent user-admin from resetting owner password (#25709)
`PUT /api/v2/users/{user}/password` was protected only by
`ActionUpdatePersonal`, which the built-in `user-admin` role holds
site-wide. No guard prevented targeting an owner. The old-password check
is skipped for non-self resets, so a user-admin could reset any owner's
password and authenticate as them, gaining full deployment control.

Add an owner-role guard to `putUserPassword` that refuses password-reset
requests when the target holds the owner role unless the caller is also
an owner. This is modeled on the guard in `putUserStatus`, but differs
in that it conditionally allows owner-to-owner resets (whereas
`putUserStatus` blocks all suspension of owners regardless of caller).

Fixes https://linear.app/codercom/issue/PLAT-227

<details><summary>Implementation details</summary>

- Guard inserted after the `Authorize` check, before `httpapi.Read`
- `apiKey.UserID != user.ID` gates the check so self-password-change is
unaffected
- Acting user's roles fetched from DB to verify owner status (same
pattern as `putUserStatus`)
- Returns HTTP 400 consistent with sibling handler error style
- Two new test cases: `UserAdminCannotResetOwnerPassword`,
`OwnerCanResetOwnerPassword`

</details>

> Generated with [Coder Agents](https://coder.com) by @f0ssel
2026-06-04 14:36:25 -04:00
Mathias Fredriksson 20d678b886 fix(agent): install connstats callback at statsReporter creation (#25819)
The stats reporter only installed the connstats callback on the TUN
device after the report loop negotiated an interval with the server.
Traffic that flowed before that point (e.g. an SSH handshake) was
silently dropped because the TUN wrapper's stats.Load() returned nil.

We now install the connstats callback immediately and we no longer
re-install the callback every interval unless the interval changed.

Fixes flaky TestAgent_Stats_SSH, TestAgent_Stats_ReconnectingPTY,
and TestAgent_Stats_Magic by ensuring the connstats callback is
always installed before network traffic can flow.

Closes coder/internal#505
Closes CODAGT-517
2026-06-04 21:16:26 +03:00
Andrew Aquino 6bd413163f fix(coderd): update references to workspace's include_deleted query param (#25826)
fixes DEVEX-206
2026-06-04 09:12:45 -07:00