Closes [AIGOV-455](https://linear.app/codercom/issue/AIGOV-455/extend-drpc-with-buildproviders).
## Why
The AI Gateway (`aibridged`) is being split into a standalone process that must not touch the database. `coderd` stays the source of truth and seeds the `ai_providers` / `ai_provider_keys` tables from the environment. This PR adds a DRPC call so the gateway fetches provider config from `coderd` instead of reading the DB, for both the embedded and standalone daemons.
## What
- **Proto:** new `ProviderConfigurator` service with a unary `GetAIProviders` RPC, plus `AIProvider` / `AIProviderBedrock` messages. `CurrentMinor` bumped to 1 (additive).
- **Server (`coderd/aibridgedserver`):** `GetAIProviders` runs a read-only `InTx` under `LockIDAIProvidersEnvSeed` so it never returns a mid-seed snapshot, reads providers (incl. disabled) plus keys for enabled ones, and maps to proto under `dbauthz.AsAIBridged`. Unmappable rows are skipped and logged; plaintext keys and Bedrock secrets are never logged.
- **Client:** `DRPCProviderConfiguratorClient` wired into the client union, `dialer.go`, and `CreateInMemoryAIBridgeServer`.
- **cli:** `BuildProvidersFromProto` maps the response through the existing DB-neutral `buildProvider`. A shared `poolRPCReloader` does the fetch/build/replace for both daemons: the embedded daemon reloads on every `ai_providers` change and fails startup if it cannot subscribe; the standalone gateway drives the same reloader once at startup, retrying until success and staying interruptible.
- **Dead code removed:** `BuildProvidersFromConfig`, `ProvidersFromConfig`, `AIProviderFromConfig`, and the DB-read `BuildProviders` path.
Adds a new enterprise-only `GET /api/v2/ai-gateway/serve` endpoint that standalone AI Gateway replicas use to connect to `coderd` over a DRPC-over-WebSocket transport, mirroring the existing in-memory path used by the embedded AI Bridge daemon.
- The endpoint upgrades the HTTP connection to a WebSocket, multiplexes it with yamux, and finally serves the three DRPC services (Recorder, MCPConfigurator, Authorizer).
- The `X-AI-Governance-Gateway-Key` header is used for authentication.
- The key is looked up by its hashed secret
- Missing or revoked keys return `401`.
- API version negotiation is enforced via a new `aibridged/proto` version (`v1.0`).
- Incompatible versions return `400`.
- `FeatureAIBridge` entitlement is required.
- Key liveness (`last_used_at`) is recorded immediately on connection and refreshed every 60 seconds while the session remains open.
- When key liveness detects the key was deleted (no rows where updated) session is closed.
#### Small refactors
* The three DRPC service registrations are extracted into `aibridgedserver.Register`, shared by both the in-memory and WebSocket paths.
* The literal `256 * 1024` used as the yamux-aligned WebSocket read limit is replaced with the named constant `drpcsdk.YamuxDefaultStreamWindowSize` in all call sites.
* as noted in review comment https://github.com/coder/coder/pull/26506#discussion_r3461905223 order of `SetReadLimit` and `WebsocketNetConn` calls was fixed.
## Description
Registers `/api/v2/ai-gateway/*` as the new API path for AI Gateway, replacing `/api/v2/aibridge/*`. Both prefixes share the same route builder (`aiBridgeRoutes`) backed by a single in-memory handler, so existing `/aibridge` endpoints continue to work. New endpoints must be registered on the enterprise API handler under `/api/v2/ai-gateway` only.
Swagger annotations now point to `/api/v2/ai-gateway` paths with a backward-compatibility note referencing `/aibridge`. The legacy `/aibridge` routes are skipped in the swagger documentation test.
## Changes
- Store one raw handler (`aiGatewayHandler`) instead of two prefix-stripped handlers
- Register `/ai-gateway` and `/ai-gateway/proxy` route aliases alongside legacy `/aibridge` routes
- Move `/aibridge/keys` to `/ai-gateway/keys`
- Update in-process transport to use `/api/v2/ai-gateway` prefix
- Update SDK client URLs and proxy forwarding URL
- Swap `@Router` and `@Tags` annotations from `aibridge`/`AI Bridge` to `ai-gateway`/`AI Gateway`
- Rename user-facing error messages from "AI Bridge" to "AI Gateway"
- Define consts for route prefixes (`AIGatewayRootPath`, `AIBridgeRootPath`)
- Update tests and comments to use new paths
Note: the following will be addressed in follow-up PRs:
- Frontend API URLs
- Frontend routes and redirects
- Dogfood main.tf updates
- Hand-written documentation URL updates
- aibridge internal comments and nits
- Scale tests path updates
Refs https://linear.app/coder/issue/AIGOV-230
> Generated with the assistance of Coder Agents (@ssncferreira)
> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.
Part 4 of DEVEX-277 (POST /api/v2/templatebuilder/compose).
Adds the HTTP handler, route wiring, and integration tests for the
compose endpoint.
The handler accepts a JSON request with a base template ID and optional
modules with variable overrides, renders them via `Compose`/`BundleTar`,
and returns the tar archive directly with `Content-Type:
application/x-tar`. The registry URL comes from the deployment config
(`CODER_TEMPLATE_BUILDER_REGISTRY_URL`).
RBAC uses `policy.ActionCreate` on
`rbac.ResourceTemplate.AnyOrganization()`.
Integration tests cover: base-only compose, base with modules, unknown
base/module errors, missing base template ID, and feature-disabled 404.
Adds `coder exp chat context add` and `coder exp chat context clear`
commands that run inside a workspace to manage chat context files via
the agent token.
`add` reads instruction and skill files from a directory (defaulting to
cwd) and inserts them as context-file messages into an active chat.
Multiple calls are additive — `instructionFromContextFiles` already
accumulates all context-file parts across messages.
`clear` soft-deletes all context-file messages, causing
`contextFileAgentID()` to return `!found` on the next turn, which
triggers `needsInstructionPersist=true` and re-fetches defaults from the
agent.
Both commands auto-detect the target chat via `CODER_CHAT_ID` (already
set by `agentproc` on chat-spawned processes), or fall back to
single-active-chat resolution for the agent. The `--chat` flag overrides
both.
Also adds sub-agent context inheritance: `createChildSubagentChat` now
copies parent context-file messages to child chats at spawn time, so
delegated sub-agents share the same instruction context without
independently re-fetching from the workspace agent.
<details><summary>Implementation details</summary>
**New files:**
- `cli/exp_chat.go` — CLI command tree under `coder exp chat context`
**Modified files:**
- `agent/agentcontextconfig/api.go` — `ConfigFromDir()` reads context
from an arbitrary directory without env vars
- `codersdk/agentsdk/agentsdk.go` — `AddChatContext`/`ClearChatContext`
SDK methods
- `coderd/workspaceagents.go` — POST/DELETE handlers on
`/workspaceagents/me/chat-context`
- `coderd/coderd.go` — Route registration
- `coderd/database/queries/chats.sql` — `GetActiveChatsByAgentID`,
`SoftDeleteContextFileMessages`
- `coderd/database/dbauthz/dbauthz.go` — RBAC implementations for new
queries
- `coderd/x/chatd/subagent.go` — `copyParentContextFiles` for sub-agent
inheritance
- `cli/root.go` — Register `chatCommand()` in `AGPLExperimental()`
**Auth pattern:** Uses `AgentAuth` (same as `coder external-auth`) —
agent token via `CODER_AGENT_TOKEN` + `CODER_AGENT_URL` env vars.
</details>
> 🤖 Generated by Coder Agents
---------
Co-authored-by: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com>
Adds the following debug routes for people with the `debug_info:read`
permission:
- `/api/v2/debug/pprof` for `net/http/pprof`
- `/`
- `/cmdline`
- `/profile`
- `/symbol`
- `/trace`
- `/*`
- `/api/v2/debug/metrics` for Prometheus metrics
# Add support for low-level API key scopes
This PR adds support for fine-grained API key scopes based on RBAC resource:action pairs. It includes:
1. A new endpoint `/api/v2/auth/scopes` to list all public low-level API key scopes
2. Generated constants in the SDK for all public scopes
3. Tests to verify scope validation during token creation
4. Updated API documentation to reflect the expanded scope options
The implementation allows users to create API keys with specific permissions like `workspace:read` or `template:use` instead of only the legacy `all` or `application_connect` scopes.
Fixes#19847
This pull request introduces support for external workspace management, allowing users to register and manage workspaces that are provisioned and managed outside of the Coder.
Depends on: https://github.com/coder/terraform-provider-coder/pull/424
* GET /api/v2/init-script - Gets the agent initialization script
* By default, it returns a script for Linux (amd64), but with query parameters (os and arch) you can get the init script for different platforms
* GET /api/v2/workspaces/{workspace}/external-agent/{agent}/credentials - Gets credentials for an external agent **(enterprise)**
* Updated queries to filter workspaces/templates by the has_external_agent field
- Update go.mod to use Go 1.24.1
- Update GitHub Actions setup-go action to use Go 1.24.1
- Fix linting issues with golangci-lint by:
- Updating to golangci-lint v1.57.1 (more compatible with Go 1.24.1)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <claude@anthropic.com>
Aims to resolve#15605
There's currently one option valid for the `@Security` tag in
swaggerparser - which fails in the CI if we try to put any other value.
At least one of our endpoints does not accept `CoderSessionToken` as an
option for the authentication and so we need to add new possibilities in
order to keep the documentation up-to-date.
In this PR , I added `ProvisionerKey` which is the way our provisioner
daemon can authenticate to the backend - also modified a bit the code to
simplify other options later.
Relates to https://github.com/coder/coder/issues/14232
This implements two endpoints (names subject to change):
- `/api/v2/users/otp/request`
- `/api/v2/users/otp/change-password`