Commit Graph
46 Commits
Author SHA1 Message Date
Michael SuchaczandEthan Dickson 0ef331fcd0 feat!: scope chat model override settings to organizations (#28442)
Moves chat model override settings from deployment scope to organization
scope, following the org-scoping of chat model configs in #28440.

Depends on #28440 (based on
`ethan/chat-models-availability-consolidation`).

Remote dogfood UAT passed on this change, including multi-organization
scenarios on a licensed deployment with real models.

## Problem

Chat model configs are now owned by organizations, but the override
settings that reference them stayed deployment-wide: admin
subagent/title/compaction overrides in `site_configs`, personal
overrides in `user_configs`, and the advisor model embedded in the
advisor runtime JSON. A single deployment-level override can only point
at one organization's model config, so overrides effectively worked for
the default organization only, and title generation had to soften its
hard-failure contract to tolerate unusable overrides.

## Fix

Admin overrides (general, explore, title generation, compaction,
advisor) and personal overrides (root, general, explore) become
organization-scoped rows in two new typed tables,
`chat_organization_model_overrides` and `chat_user_model_overrides`.
Composite foreign keys on `(organization_id, model_config_id)` make
cross-organization model references unrepresentable. The migration
deletes the legacy serialized `site_configs`/`user_configs` override
keys instead of migrating them; admins and users re-select models in the
new organization-scoped settings.

New endpoints live under
`/api/experimental/organizations/{organization}/chats/model-overrides`
(admin defaults) and
`/api/experimental/organizations/{organization}/members/{user}/chats/model-overrides`
(personal overrides); the legacy deployment-level routes are removed.
chatd resolves overrides via the chat's organization, restoring the
hard-failure contract for configured-but-unusable title generation
overrides. The deployment-level `AllowUsers` switch and advisor runtime
limits stay deployment-scoped.

The Coder Agents settings UI gains a per-organization "Defaults &
overrides" page under AI Settings > Models, and the personal overrides
page gains an organization selector for users in multiple organizations.
Advisor telemetry now reports per-organization override rows.

**BREAKING CHANGE**: Existing deployment-level overrides are dropped,
not migrated. Every organization starts with no overrides after upgrade,
and model selections must be re-applied in the new settings. The legacy
deployment-level override endpoints are removed.

Closes https://linear.app/coder/issue/CODAGT-872

> [!NOTE]
> Xum (AI agent) authored this PR on behalf of @ibetitsmike.

<!-- xum-attribution: model=claude-opus-4-6 thinking=high -->

---------

Co-authored-by: Ethan Dickson <ethan@coder.com>
2026-08-24 11:20:26 +01:00
Ethan f32592ec6b feat!: scope chat model configs to organizations (#27955)
## Summary

Scope chat model configurations and runtime model resolution to
organizations. Each model configuration now belongs to exactly one
organization, each organization can have its own default model, and
Chatd only uses models that belong to the chat's organization.

Depends on #27968.

## Problem

Chat model configurations are currently deployment-wide even though
chats belong to organizations. A default model, explicitly selected
model, or configured model override can therefore reference the same
model configuration from every organization. This prevents model
catalogs and defaults from being isolated by organization and allows a
chat to retain or select a model that its organization does not own.

Existing model configurations also have no organization ownership or
organization-scoped ACL data, and the database enforces a single live
default across the entire deployment.

## Fix

Add required organization ownership and ACL storage to chat model
configurations. The migration assigns every existing configuration to
the default organization, seeds organization-wide read access, and
replaces the deployment-wide default constraint with a per-organization
constraint.

Scope Chatd lookup, admission, fallback, and queue-promotion behavior to
the chat's organization:

- New chats use the usable default model from their organization.
- Explicit model selections from another organization are rejected.
- Deployment or personal overrides that point to a foreign model are not
used for the chat.
- Historical cross-organization model references remain unchanged in the
database, but runtime generation falls back to a usable local default.
- Queue promotion resolves unavailable, disabled, missing, or foreign
stored models to the usable local default and fails when no usable local
default exists.

The existing model configuration management and availability routes
remain compatibility routes for the default organization in this layer.
A later layer in the stack adds organization-scoped management routes
and updates clients to use them.

## Breaking change

This changes chat model behavior from deployment-wide to
organization-scoped. Existing configurations are migrated only to the
default organization; they are not copied into every organization.

As a result:

- A non-default organization no longer inherits the deployment's
existing default model.
- Creating a chat in an organization without a usable local default
fails with `400: No default chat model config is configured.`
- Explicitly selecting a configuration owned by another organization
fails with `400: Model config does not belong to the specified
organization.`
- Existing chats whose stored model belongs to another organization can
generate only if a usable local default is available; otherwise
generation fails.

Deployments using Agents in non-default organizations must configure a
usable default chat model separately for each organization after the
organization-scoped management layers in this stack are available.

_This pull request description was generated by Coder Agents._
2026-08-24 09:30:01 +00:00
Michael Suchacz 7ca7c30f40 feat: add group and user ACLs to MCP server configs (#27944)
Adds group and user ACLs to org-scoped MCP server configs so
organizations can restrict specific MCP servers to subsets of members,
mirroring the template ACL pattern.

## Summary

- Migration adds `group_acl`/`user_acl` JSONB columns (nested `{"<id>":
{"permissions": [...]}}` shape) and seeds every existing config with its
organization's Everyone group read entry (the Everyone group ID equals
the org ID), so member access is unchanged by default. Creation seeds
the same entry.
- The blanket org-member read grant from the base PR is replaced by ACL
evaluation: Rego requires org membership for every ACL grant, and
`GetAuthorizedMCPServerConfigs` compiles ACL-aware SQL filters.
- New `ActionShare` (org admins) gates `GET|PATCH
/api/experimental/organizations/{organization}/mcp-servers/{mcpserverconfig}/acl`
(nested under the organization like the rest of the config surface).
PATCH validates principals against the config's organization, merges
sparse updates under a row lock, stamps `updated_by`/`updated_at`, and
is audited as a Write with `Old` captured before authorization. A config
deleted concurrently between the middleware fetch and the locked
re-fetch is concealed as 404, matching the update and delete handlers.
ACL columns are tracked in the audit table.
- ACL management is available in all editions (no enterprise
entitlement), documented in the MCP servers page. Revoking an ACL does
not retro-strip already-selected configs from existing chats; new
selection is blocked at chat create.
- Force On respects the ACL: the forced set is loaded as the chat owner,
so a `force_on` server whose ACL denies the owner never attaches at
create, send, or generation time.
- No rolling-upgrade machinery: upgrades run in scheduled maintenance
downtime, so the migration only backfills existing rows; the API sets
the Everyone read grant explicitly on every insert.

Stacked on #27943. Part of the MCP org-separation stack.

Closes https://linear.app/codercom/issue/CODAGT-712

UAT: verified on a dogfood instance with two members and a custom group:
Everyone-seed default visibility, group grant with Everyone removal
(non-member loses list/fetch/selection), foreign-principal rejection,
non-admin share denial (audited 403 / concealed 404), user_acl restore,
and audited ACL diffs.

> Mux (AI agent) authored this PR on Mike's behalf.

<!-- mux-attribution: model=claude-fable-5 thinking=high -->
2026-08-19 19:25:18 +00:00
Michael SuchaczandMathias Fredriksson 443e3b9b80 feat!: org-scope MCP server configs with RBAC (#27942)
Moves `mcp_server_configs` from deployment scope to organization scope
so each organization fully controls the MCP servers its members can use
with Coder Agents.

## Summary

- Migration: adds `organization_id` (NOT NULL, FK) and keeps existing
rows as the default organization's originals with credentials intact.
Other organizations start with no MCP servers and configure their own;
nothing is copied across organizations. Chats outside the default
organization keep any now-cross-organization `mcp_server_ids` entries;
the runtime already ignores IDs that do not resolve in the chat's
organization, so no data rewrite is needed. Slug uniqueness becomes
`(organization_id, slug)`.
- RBAC: new org-scoped `ResourceMCPServerConfig` with regosql converter
and `GetAuthorizedMCPServerConfigs`; org admins get in-org CRUD, org
members get read (replaced by ACL evaluation in the follow-up ACL PR in
this stack).
- API: all config routes nest under the organization, matching
templates: `POST|GET
/api/experimental/organizations/{organization}/mcp-servers` and
`GET|PATCH|DELETE .../mcp-servers/{mcpserverconfig}` (plus
`oauth2/connect`), resolved by a read-only param middleware that
conceals read-denied and cross-organization access as 404. Two routes
stay on the frozen `/api/experimental/mcp/servers/{mcpServer}` block:
the OAuth2 callback (the redirect URI baked into existing AS-side client
registrations) and `oauth2/disconnect`, which must remain reachable by
users removed from the organization so they can still revoke their token
grant.
- Chat runtime: selection validation and generation resolve configs
strictly by IDs, enabled state, and the chat's organization in SQL;
requested duplicates are normalized; invalid or cross-org IDs are
rejected with the precise ID list. IDs already persisted on a chat are
exempt from message-time rejection so disabling a selected server never
blocks sends; generation skips servers that are no longer usable.
- Frontend: API layer and admin settings pages target the new endpoints.
The admin page manages the default organization's servers; the org
picker is tracked separately (CODAGT-714).

- Security hardening from review: OAuth user grants are additionally
bound to `oauth2_revocation_url` (changing it invalidates grants, and a
racing OAuth callback gets 409 instead of recreating a grant).
Stack-wide SSRF protection for MCP config-directed traffic was split
into its own PR at the top of this stack (#28242) to keep this diff
reviewable; this PR keeps main's existing discovery IP-range guard.
OAuth2 auto-discovery now completes before the config row is inserted: a
failed discovery persists nothing, and there is no provisional row that
concurrent updates could race against.

Two follow-up PRs in this stack were split out to keep this diff
reviewable: #28064 completes the swagger annotations for the moved
routes (main already ships these experimental MCP handlers unannotated),
and #28065 carries hardening fixes and regression pins on top of the
cutover.

- Force On enforcement (landed on main mid-review) is org-scoped: the
forced set is read per chat organization
(`GetForcedMCPServerConfigsByOrganization`), so another organization's
`force_on` server never attaches to a chat.

## Breaking changes (experimental API)

The MCP server config endpoints move from the deployment-scoped
`/api/experimental/mcp/servers` block to organization-nested paths:
`POST|GET /api/experimental/organizations/{organization}/mcp-servers`
and `GET|PATCH|DELETE
/api/experimental/organizations/{organization}/mcp-servers/{mcpserverconfig}`
(plus `oauth2/connect`). The old paths are removed, so API consumers
must supply an organization. Two routes intentionally stay on the frozen
`/api/experimental/mcp/servers/{mcpServer}` block: the OAuth2 callback
(its redirect URI is baked into existing AS-side client registrations)
and `oauth2/disconnect` (must remain reachable by users removed from the
organization). These endpoints are under `/api/experimental`, so no
deprecation window is provided.

## Rolling upgrades

During a rolling deploy, an old replica creating an MCP config can fail
the new `NOT NULL organization_id` constraint until it is upgraded
(reads are unaffected: old binaries' generated queries select their own
column lists). This matches the repo's existing precedent for additive
NOT NULL migrations (000562) and affects only the admin config-create
path in the upgrade window.

Upgrades are expected to run in scheduled maintenance downtime with the
database locked during migration, so the migration ships no
rolling-upgrade compatibility machinery. The down migration deletes
organization-created configs (their chat references are cleaned by the
000510 delete trigger) and restores deployment-wide slug uniqueness.

Part of the MCP org-separation stack (CODAGT-711 -> CODAGT-717 audit ->
CODAGT-712 ACLs -> CODAGT-806 token RBAC).

Closes https://linear.app/codercom/issue/CODAGT-711

UAT: validated end to end on a two-org dogfood deployment, including a
real pre-migration to post-migration upgrade, cross-org isolation
(404s), same-slug-two-orgs, chat selection gating, and a live MCP tool
call through the org-scoped generation path. The migration was later
revised to keep existing rows in the default organization only (no
per-organization copies); that revision is covered by the migration test
suite.

> Mux (AI agent) authored this PR on Mike's behalf.

<!-- mux-attribution: model=claude-fable-5 thinking=high -->

---------

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2026-08-19 18:04:13 +00:00
Bobby HoandClaude Opus 5 16c58770f8 feat: constrain the OAuth2 client type column (#27931)
Extracted from #27873 so the schema change can be reviewed for migration
safety on its own. #27873 will rebase onto this.

`client_type` decides whether the token endpoint validates a client
secret at all, and the column accepts any text: nullable, no `CHECK`, no
enum. No Go path can write a bad value today, and `IsPublic` fails
closed on anything unrecognized, so the read side is safe. What the
schema still permits is the problem: a future migration writing
`'public'` onto a row that holds a secret turns off client
authentication for that app with nothing to catch it, no constraint, no
log, no audit entry, no test.

`000565` adds `CHECK (client_type IN ('confidential', 'public'))` and
`NOT NULL`. The `UPDATE` ahead of it should touch zero rows, since
migration `000344` added the column with a default of `'confidential'`
and backfilled with `COALESCE`; it is there so `SET NOT NULL` cannot
fail on an unexpected row. Both `ALTER`s take `ACCESS EXCLUSIVE` and
scan a table holding one row per registered OAuth2 client, so the lock
is brief.

## The second migration, and why it aligns the way it does

Two columns describe the same fact and can currently contradict each
other.

`token_endpoint_auth_method` is the client's own declaration: registered
client metadata under RFC 7591 §2, where `"none"` is defined to mean the
client is public and has no secret. `client_type` is Coder's derived
copy, and it is what the token endpoint enforces on. RFC 7591 defines no
`client_type` metadata field; the column exists only as a
denormalization.

Registration used to persist the declaration verbatim while hardcoding
`client_type` to `'confidential'`, so rows exist declaring `"none"` on a
client stored confidential that was issued, and still requires, a real
secret. A client that reads its own metadata and believes it is public
will drop that secret and stop being able to exchange codes.

`000566` aligns the declaration to what is enforced, not the reverse.
Deriving enforcement from the declaration would reclassify every such
client as public and stop requiring the secret it holds, which is a
silent authentication downgrade. The down migration is deliberately
empty: the previous values are not recorded, and restoring them would
only reinstate metadata that tells a client to authenticate in a way the
server rejects.

## Application changes

`SET NOT NULL` changes the generated field from `sql.NullString` to
`string`, so the three write sites are updated to match. That is the
entire application diff and no behavior depends on it.

Refs
https://linear.app/codercom/issue/ENG-3029/oauth2-support-public-client

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 10:49:02 -07:00
Ethan b3485d9b3a chore: add agents_allowed to templates (#27284)
Relates to CODAGT-713

This adds `templates.agents_allowed` as a default-true, auditable template attribute, along with nullable database filtering. Migration `000562` translates the effective legacy `agents_template_allowlist` state for existing templates: a valid nonempty list allows matching templates and blocks the rest, missing or empty values leave templates allowed, whilst corrupt values fail closed by blocking all existing templates. As per the linear issue, new templates deliberately default to allowed under the per-template model.

This is the database-only first PR in the stack. #27285 makes the field authoritative in the API and chatd whilst temporarily retaining the compatibility routes needed by the shipped frontend. Later PRs migrate the UI, remove the legacy storage, routes, SDK types, and utility, then add CLI flags.
2026-08-06 14:04:23 +10:00
Bobby HoandClaude Sonnet 5 d814dfad88 feat(coderd): support public OAuth2 client tokens at the schema layer (#27712)
Layer 1 of a multi-PR split of #27195 (public/secretless PKCE-only
OAuth2 clients), broken up for easier review: **database schema (this
PR)** → oauth2provider handler logic → API/e2e integration tests.

## Goal

Coder's OAuth2 provider only works correctly for confidential clients
today. Public clients — native apps that can't safely hold a shared
secret, such as the CLI's browser-based login flow, IDE plugins (VS
Code, JetBrains), desktop apps, and MCP clients — cannot complete a real
OAuth2 flow against Coder, even though OAuth 2.1 §2.1 explicitly defines
this client type and RFC 8252 §8.5 requires PKCE alone to be sufficient
authentication for it. Every MCP client, CLI login flow, and IDE plugin
is a public client by construction, and none of them can complete a
secretless flow against Coder today: dynamic registration always
classifies a client as confidential regardless of what it asks for, the
token endpoint unconditionally requires a `client_secret`, and discovery
metadata never advertises `"none"` as a supported auth method.

Full write-up:
[ENG-3029](https://linear.app/codercom/issue/ENG-3029/oauth2-support-public-client)

### Overall design (end state across the full PR stack)

`[PR2]` marks handler-layer changes landing in the next PR in this
stack. The green box is what this PR implements.

```mermaid
sequenceDiagram
    autonumber
    participant C as Public Client (CLI/MCP/IDE plugin)
    participant S as coderd (chi router)
    participant H as oauth2provider handlers
    participant DB as PostgreSQL

    Note over C,S: Discovery
    C->>S: GET /.well-known/oauth-authorization-server
    S->>H: GetAuthorizationServerMetadata()
    Note over H: [PR2] add "none" to<br/>the returned auth methods list
    H-->>C: [PR2] 200 { token_endpoint_auth_methods_supported:<br/>[..., "none"] }

    Note over C,S: Dynamic Client Registration
    C->>S: POST /oauth2/register<br/>{redirect_uris, token_endpoint_auth_method: "none"}
    S->>H: CreateDynamicClientRegistration()
    Note over H: [PR2] client type now reads<br/>the request -> "public"
    Note over H: [PR2] skip secret generation<br/>for public clients
    H->>DB: [PR2] INSERT app row<br/>(client_type = 'public')
    DB-->>H: app row
    Note over H: [PR2] skip secret insert entirely
    H-->>C: [PR2] 201 { client_id }<br/>(no client_secret field)

    Note over C,S: Authorization Code + PKCE flow
    C->>S: GET /oauth2/authorize?client_id=...&code_challenge=...
    C->>S: POST /oauth2/tokens (grant_type=authorization_code)<br/>no client_secret
    S->>H: extractTokenRequest()
    Note over H: [PR2] client_secret no longer required<br/>for public clients
    H->>H: authorizationCodeGrant()
    Note over H: [PR2] skip secret lookup for public clients
    Note over H: PKCE verification — already mandatory, unchanged
    rect rgb(198, 239, 206)
    Note over H,DB: [THIS PR] oauth2_provider_app_tokens.app_id<br/>column added (NOT NULL, populated at insert<br/>time from app.ID) and app_secret_id loosened<br/>to nullable. Revocation now checks app_id<br/>directly. Confidential-client behavior is<br/>unchanged — no public client can be created yet.
    H->>DB: [PR2] INSERT refresh token row<br/>(no secret reference, for public clients)
    end
    DB-->>H: token row
    H-->>C: 200 { access_token, refresh_token }
```

## This PR: database schema

A public client has no `client_secret`, so it has nothing to put in
`oauth2_provider_app_tokens.app_secret_id`, which was `NOT NULL`. This
PR makes that column nullable and instead attributes a token to its
owning app through a new, always-populated `app_id` column — so
ownership checks (e.g. revocation) work identically for public and
confidential clients without joining through a secret that may not
exist.

| Column | Before | After (this PR) |
|---|---|---|
| `app_secret_id` | `uuid NOT NULL` | **nullable** |
| `app_id` | — | **new**: `uuid NOT NULL`, `FOREIGN KEY →
oauth2_provider_apps(id) ON DELETE CASCADE`, backfilled for every
existing row and populated on every new insert from that point on |

This is a single, complete migration — not staged across multiple PRs.
An earlier version of this branch deferred `app_secret_id`'s nullability
and the insert-time population of `app_id` to a later PR, keeping this
PR's diff limited to `coderd/database`. [Automated
review](https://github.com/coder/coder/pull/27712#discussion_r3686851911)
correctly flagged that as unsafe: the migration would backfill existing
rows once, but nothing would populate `app_id` for rows written
afterward, so the moment this PR merged, new tokens would start
accumulating a permanently `NULL` app_id — and if a release happened to
be cut before the follow-up PR landed, that gap could ship to customers
and would need a second, later backfill to close. Doing the full
migration now avoids that: `app_id` is correct from the first row
written, and the promised `NOT NULL` constraint requires no data repair
because it's already enforced.

Closing that gap requires a few mechanical, non-branching touches
outside `coderd/database`:
- `revoke.go`'s two ownership checks now compare `dbToken.AppID`
directly instead of looking up the app through `app_secret_id` — a
genuine simplification (and slightly less code), not a temporary shim.
- `tokens.go`'s two `InsertOAuth2ProviderAppToken` call sites supply the
new `app_id` column and wrap `app_secret_id` as a `NullUUID`.
- `oauth2_test.go`'s one direct-insert test fixture does the same.

None of these introduce client-type branching or new capability — every
client today is still confidential-only, still always presents a secret,
and behavior is unchanged. The full repo builds, vets, and all existing
tests pass unmodified in behavior.

## Coming next

- **PR2 (handler layer)**: `codersdk`'s `DetermineClientType()` reading
the requested `token_endpoint_auth_method`; `registration.go` skipping
secret generation for public clients (and wrapping the app+secret insert
in a single transaction, fixing a pre-existing
orphan-row/visibility-race gap); `tokens.go` making the secret check
conditional so PKCE alone authenticates a public client; `metadata.go`
advertising `"none"` in discovery. No further migration is needed — the
schema this PR ships is already final.
- **PR3 (API/e2e layer)**: integration tests through the real HTTP API
(`coderd/oauth2_test.go`), the MCP OAuth2 e2e flow
(`coderd/mcp/mcp_e2e_test.go`), and the manual test script
(`scripts/oauth2/test-mcp-oauth2.sh`).

Depends on: #27195 (original combined PR, being superseded by this
stack)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 10:41:06 -07:00
Bobby Ho fbac602456 feat!: add admin-controlled dynamic client registration toggle (#27316)
`POST /oauth2/register` (RFC 7591 Dynamic Client Registration) has
exactly one gate today: `ExperimentOAuth2`, a static, process-lifetime
flag that wraps the entire `/oauth2/*` route tree as an all-or-nothing
switch. That flag is scheduled for removal at GA, which would leave DCR
with zero admin control at all once it is gone.

Add a persistent, DCR-specific `oauth2_dcr_enabled` deployment setting,
independent of the experiment system, so admin control over DCR survives
GA. `POST /oauth2/register` checks the flag and rejects new
registrations with an RFC 7591-shaped `403` when disabled; discovery
metadata (`GET /.well-known/oauth-authorization-server`) conditionally
omits `registration_endpoint`. A new audited `GET`/`PUT
/api/v2/oauth2-provider/settings` endpoint lets an owner toggle it live,
no restart required. The setting defaults to disabled, matching the
canonical design proposal; disabling only stops new self-registrations,
clients that already registered continue to authorize and exchange
tokens normally.

Address issue described in
[ENG-3056](https://linear.app/codercom/issue/ENG-3056/oauth2-dcr-admin-configurable-enabledisable).

## Where this sits in the request path

```mermaid
sequenceDiagram
    autonumber
    participant A as Admin
    participant S as coderd
    participant DB as site_configs<br/>(oauth2_dcr_enabled)
    participant C as OAuth2/MCP Client

    Note over A,S: Admin toggles DCR (new)
    A->>S: PUT /api/v2/oauth2-provider/settings<br/>{dynamic_client_registration_enabled: false}
    S->>S: authorizeContext(ActionUpdate, ResourceDeploymentConfig)
    S->>DB: UPSERT oauth2_dcr_enabled = false
    S-->>A: 200 OK (audited)

    Note over C,S: Client discovery + registration afterward
    C->>S: GET /.well-known/oauth-authorization-server
    S->>DB: GetOAuth2DCREnabled (system ctx, every request, no cache)
    DB-->>S: false
    S-->>C: 200 metadata, registration_endpoint omitted

    C->>S: POST /oauth2/register
    S->>DB: GetOAuth2DCREnabled (system ctx, every request, no cache)
    DB-->>S: false
    S-->>C: 403 invalid_request,<br/>"Dynamic client registration is disabled"

    Note over C,S: A client that registered before the change is unaffected
    C->>S: GET /oauth2/authorize?client_id=...
    Note over S: no DCR-enabled check on this path
    S-->>C: 200 (proceeds normally)

    C->>S: PUT/DELETE /oauth2/clients/{client_id} (RFC 7592 self-management)
    Note over S: no DCR-enabled check on this path either
    S-->>C: 200 (proceeds normally)
```

## Files changed: manual vs. generated

Reviewers should focus on the **manual** files. The **generated** ones
are `make gen` output that follows mechanically from the manual changes
and don't need direct review.

<details>
<summary><b>Manual files (26)</b> — click to expand, grouped the same
way as "Suggested review order" below</summary>

**1. Database**

| File | What changed |
|---|---|
| `coderd/database/queries/siteconfig.sql` | New
`GetOAuth2DCREnabled`/`UpsertOAuth2DCREnabled` query pair on the
existing generic `site_configs` table. No schema change. |
| `coderd/database/dbauthz/dbauthz.go` | RBAC check
(`rbac.ResourceDeploymentConfig`) on the two new query methods; extends
the `subjectSystemOAuth2` system-actor role with read-only
`ResourceDeploymentConfig` access, needed so the public
discovery/registration endpoints can read the flag via
`dbauthz.AsSystemOAuth2`. |
| `coderd/database/dbauthz/dbauthz_test.go` | RBAC assertion coverage
for `GetOAuth2DCREnabled`/`UpsertOAuth2DCREnabled` in the
method-coverage test suite. |

**2. Request gating (the actual feature)**

| File | What changed |
|---|---|
| `coderd/oauth2provider/registration.go` | The actual gate:
`CreateDynamicClientRegistration` reads the flag first and returns an
RFC 7591-shaped `403` when disabled (defaults disabled if never
configured). |
| `coderd/oauth2provider/registration_test.go` | New unit test,
`TestCreateDynamicClientRegistration_DCREnabled`: calls the handler
directly (no HTTP server), covering enabled / explicitly disabled /
never-configured. |
| `coderd/oauth2provider/metadata.go` | `GetAuthorizationServerMetadata`
conditionally omits `registration_endpoint` from discovery metadata when
DCR is disabled. |
| `coderd/oauth2provider/metadata_test.go` | New unit test,
`TestGetAuthorizationServerMetadata_DCREnabled`: same three states, for
the discovery handler. |

**3. Admin settings endpoint**

| File | What changed |
|---|---|
| `codersdk/oauth2.go` | New `OAuth2ProviderSettings` SDK type plus
`Client.OAuth2ProviderSettings`/`PutOAuth2ProviderSettings` methods. |
| `coderd/oauth2.go` | New
`oauth2ProviderSettings`/`putOAuth2ProviderSettings` admin handlers
(audited via `audit.InitRequest`); updates the
`GetAuthorizationServerMetadata` call site to pass `api.Database`. |
| `coderd/coderd.go` | Registers `GET`/`PUT
/api/v2/oauth2-provider/settings`. |
| `coderd/oauth2_provider_settings_test.go` | New test file: admin
`GET`/`PUT` round-trip, default-disabled-before-any-`PUT`, and `403` for
a non-owner on both `GET` and `PUT`. |

**4. Audit wiring**

| File | What changed |
|---|---|
| `coderd/database/types.go` | New `database.OAuth2ProviderSettings`
audit-only struct (mirrors `NotificationsSettings`). |
| `coderd/audit/diff.go` | Adds the new struct to the `Auditable` type
union. |
| `coderd/audit/request.go` | Adds the new struct to all four dispatch
switches (`ResourceTarget`, `ResourceID`, `ResourceType`,
`ResourceRequiresOrgID`). |
| `codersdk/audit.go` | New API-facing
`ResourceTypeOAuth2ProviderSettings` constant and its `FriendlyString`
case. |
| `enterprise/audit/table.go` | Field-level audit action map
(`ActionTrack`/`ActionIgnore`) for the new struct. |
|
`coderd/database/migrations/000546_audit_oauth2_provider_settings.up.sql`
| Adds `oauth2_provider_settings` to the `resource_type` Postgres enum,
required for the audit wiring above (`resource_type` is a real enum, not
a Go-only value). |
|
`coderd/database/migrations/000546_audit_oauth2_provider_settings.down.sql`
| No-op (`ALTER TYPE ... ADD VALUE` can't be reverted). |

**5. Test-suite ripple from the disabled-by-default flip**

| File | What changed |
|---|---|
| `coderd/oauth2provider/oauth2providertest/helpers.go` | New shared
test helper, `EnableDCR`, since DCR now defaults to disabled and many
pre-existing tests need it turned on to register a client. |
| `coderd/oauth2_test.go` | Adds
`TestOAuth2DynamicClientRegistrationDisabled` (registers a client,
disables DCR, verifies new registration is rejected while the existing
client's self-management, authorize, and token exchange all keep
working); calls `EnableDCR` in every pre-existing test that registers a
client. |
| `coderd/oauth2_error_compliance_test.go` | Calls `EnableDCR` in every
test that registers a client, so RFC-error-format assertions aren't
masked by the new disabled-by-default gate. |
| `coderd/oauth2_metadata_validation_test.go` | Same: `EnableDCR` added
to every registration-dependent test. |
| `coderd/oauth2_security_test.go` | Same. |
| `coderd/oauth2provider/validation_test.go` | Same (near-duplicate of
`oauth2_metadata_validation_test.go` in a different package). |
| `coderd/oauth2provider/provider_test.go` | Same. |
| `coderd/mcp/mcp_e2e_test.go` | Same, for the MCP end-to-end
dynamic-registration flow test. |

</details>

<details>
<summary><b>Generated files (12)</b> — from <code>make gen</code>, no
need to review directly</summary>

`coderd/apidoc/docs.go`, `coderd/apidoc/swagger.json`,
`coderd/database/dbmetrics/querymetrics.go`,
`coderd/database/dbmock/dbmock.go`, `coderd/database/dump.sql`,
`coderd/database/models.go`, `coderd/database/querier.go`,
`coderd/database/queries.sql.go`, `docs/admin/security/audit-logs.md`,
`docs/reference/api/enterprise.md`, `docs/reference/api/schemas.md`,
`site/src/api/typesGenerated.ts`.

</details>

## Suggested review order

### 1. Database

Establishes the persisted setting and its RBAC rule; everything else
builds on `GetOAuth2DCREnabled`/`UpsertOAuth2DCREnabled`.

1. `coderd/database/queries/siteconfig.sql` — the two new queries. Same
boolean-encoding pattern as the existing
`oauth2_github_default_eligible` key right above them in the same file.
2. `coderd/database/dbauthz/dbauthz.go` — the RBAC wrapper for those two
queries, plus the `subjectSystemOAuth2` role extension (search this file
for `ResourceDeploymentConfig`, it appears in both spots).
3. `coderd/database/dbauthz/dbauthz_test.go` — asserts the RBAC checks
from (2) actually fire.

### 2. Request gating (the actual feature)

Where `POST /oauth2/register` and discovery metadata change behavior.

1. `coderd/oauth2provider/registration.go` — the primary gate. Read this
first; it's the feature.
2. `coderd/oauth2provider/registration_test.go` — its new unit test,
exercising the gate's three states directly against the handler.
3. `coderd/oauth2provider/metadata.go` — the same gating pattern applied
to the discovery `GET` endpoint.
4. `coderd/oauth2provider/metadata_test.go` — its new unit test.

### 3. Admin settings endpoint

How an owner flips the setting live.

1. `codersdk/oauth2.go` — the `OAuth2ProviderSettings` SDK type and
`Client` methods first; this is the public contract everything below
implements against.
2. `coderd/oauth2.go` — the `GET`/`PUT` handlers themselves.
3. `coderd/coderd.go` — route registration, to see where those handlers
get wired in.
4. `coderd/oauth2_provider_settings_test.go` — round-trip and permission
tests.

### 4. Audit wiring

Plumbing required so step 3's `PUT` is auditable; mechanical except for
(3).

1. `coderd/database/types.go` — the audit-only struct; everything else
in this layer exists to plumb it through.
2. `coderd/audit/diff.go` — adds it to the `Auditable` type union (the
compiler enforces this one).
3. `coderd/audit/request.go` — the four dispatch switches; the one part
of this layer worth reading closely.
4. `codersdk/audit.go` — the API-facing resource type constant.
5. `enterprise/audit/table.go` — the field-action map.
6.
`coderd/database/migrations/000546_audit_oauth2_provider_settings.{up,down}.sql`
— read last; a consequence of needing a new `resource_type` enum value
for (1)-(5), not a design decision of its own.

### 5. Test-suite ripple from the disabled-by-default flip

1. `coderd/oauth2provider/oauth2providertest/helpers.go` — the new
`EnableDCR` helper. Read first to understand the fix pattern before
seeing it applied repeatedly.
2. `coderd/oauth2_test.go` — next, since it also contains the new
`TestOAuth2DynamicClientRegistrationDisabled`, not just `EnableDCR` call
sites.
3. The rest, in any order, they're mechanical repeats of the same
one-line addition: `coderd/oauth2_error_compliance_test.go`,
`coderd/oauth2_metadata_validation_test.go`,
`coderd/oauth2_security_test.go`,
`coderd/oauth2provider/validation_test.go`,
`coderd/oauth2provider/provider_test.go`, `coderd/mcp/mcp_e2e_test.go`.

## Explicitly out of scope

Per the design proposal: rate limiting on `POST /oauth2/register`
(tracked separately), retroactively affecting already-registered clients
when DCR is disabled (this only gates new self-registration), and an
Initial Access Token requirement (a separate, follow-up ticket).
2026-07-28 16:59:33 -07:00
Zach 85984ff142 feat: add enable/disable support for user secrets (#27537)
Users can now disable a secret to stop it from being injected into
workspaces without deleting it, and re-enable it later. Disabled secrets
stay visible and editable everywhere they already appear.

An enabled secret must have at least one injection target; a secret with
no target can be stored only while disabled. Existing target-less secrets
are migrated to disabled to preserve current behavior.

Support spans the REST API, SDK, CLI, dashboard, and audit log.
2026-07-28 09:58:33 -06:00
Jake Howell bd5d640f1e fix(coderd/database/migrations): resolve duplicate 000554 migration collision (#27581)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

## Problem

`main` currently has **two migrations sharing version `000554`**:

- `000554_aibridge_token_usage_spend_export_index.{up,down}.sql`
- `000554_legacy_none_login_to_password.{up,down}.sql` (from #26851)

Both merged around the same time. #26851 was renumbered to `000554` when
`000553` was the latest, but `aibridge_token_usage_spend_export_index`
claimed `000554` and merged too, leaving a duplicate version number on
`main`. Duplicate migration versions break the migration sequence.

## Fix

Renumber the legacy none login migration to the next free slot,
`000555`, leaving the aibridge migration at `000554`:

- `000554_legacy_none_login_to_password.{up,down}.sql` ->
`000555_legacy_none_login_to_password.{up,down}.sql`
- `migrate_test.go`: `TestMigration000554...` ->
`TestMigration000555...`, `priorMigrationVersion` `553` -> `554`, and
the `os.ReadFile` filename.

The migration is data-only and unchanged; only its version number moves.
`TestMigration000555LegacyNoneLoginToPassword` passes locally.

The same collision exists on `release/2.36` via the backport (#27578),
which has been renumbered to `000555` to match.

Resolves [DEVEX-226] follow-up.

[DEVEX-226]: https://linear.app/issue/DEVEX-226
2026-07-28 11:35:36 +00:00
Jake HowellandSushant P 0e104f38e0 fix!: deprecate login_type=none, convert existing users to password login (#26851)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

Deprecates `login_type=none` (legacy passwordless machine users) in
favour of premium **service accounts**, and migrates existing accounts
off the deprecated path while preserving their identity. Resolves
[DEVEX-226].

## What this does

- **Creation is gated** — `POST /users` and `coder users create` reject
`login_type=none` (and the deprecated `--disable-login`) unless a
service account is requested.
- **Existing users are converted** — migration
`000554_legacy_none_login_to_password` rewrites legacy non-system,
non–service-account `login_type='none'` accounts to
`login_type='password'`. Email addresses are **preserved** and existing
API tokens remain valid. Admins can set a password if interactive login
is desired.

## Why convert to `password` and not `is_service_account`?

Migration `000433_add_is_service_account_to_users` adds two CHECK
constraints:

- `users_email_not_empty`: `(is_service_account = true) = (email = '')`
- `users_service_account_login_type`: `is_service_account = false OR
login_type = 'none'`

Turning a real, email-bearing `login_type=none` user into a service
account would require **blanking their email**. Converting to `password`
instead preserves the account and its email.

> ⚠️ **Breaking / one-way.** The `down` migration cannot restore which
users originally had `login_type='none'`.


Decision log

- **Goal:** move existing `login_type=none` users off the deprecated
path while preserving their identity/email.
- **Constraint discovered:** the `is_service_account` CHECK constraints
(migration `000433`) make a literal `none → service account` conversion
require blanking emails, so this PR converts to `password` instead to
keep emails intact.
- **Implementation:** creation-gating in `cli/usercreate.go` and
`coderd/users.go`, matching test updates, plus the
`000554_legacy_none_login_to_password.{up,down}.sql` migration.
- **CI fix:** the branch was behind `main` and its migration originally
numbered `000534`, which collided with main's
`000534_drop_chat_model_configs_provider`. Merged `main` and renumbered
to `000554` (next free after main's `000553`). `make gen` produces no
drift (the migration is data-only).



> The service-account conversion alternative (#27182, which blanked
emails) was closed in favour of this password-preserving approach.
>
> Docs follow-up: #27333.

[DEVEX-226]: https://linear.app/issue/DEVEX-226

---------

Co-authored-by: Sushant P <zenithwolf1000@users.noreply.github.com>
2026-07-28 21:05:50 +10:00
Michael Suchacz 997b5d0843 feat: add synthetic gateway keys (#27170)
> Mux is working on behalf of Mike.

## Summary

Add a per-user synthetic API key for chatd AI Gateway attribution. Chatd
resolves the key from the chat owner, extends it before expiry, and
discards the generated bearer token so the key is never a usable
credential.

There is no mapping table. The key is resolved from `api_keys` by a
deterministic token name (`chatd_<owner_id>_session_token`), mirroring
the provisionerd session token model, with three deltas that chatd
needs:

- **Login type guard**: token names are unvalidated user input, so a
user can create a bearer token with the colliding name. The lookup
excludes `login_type = 'token'` rows, so chatd never picks up (or
extends) a real user token. Synthetic keys are minted with the owner's
login type, which is never `token`.
- **In-place expiry extension instead of delete-and-reinsert**: chat
generations have no stop boundary, and an in-flight generation may have
already delegated the current key ID to aibridged. Extending
`expires_at` keeps the key ID stable forever.
- **Advisory-lock mint**: the unique index on token names is partial
(`WHERE login_type = 'token'`), so nothing DB-enforces uniqueness for
synthetic keys. A per-user advisory lock serializes concurrent mints.

Keys carry a minimal scope (`api_key:read`) as defense in depth; the
delegated gateway path never evaluates scopes and the secret is
discarded at mint.

Migration 000544 removes the foreign keys from the legacy message and
queue `api_key_id` columns while chatd continues stamping them for
rolling compatibility. Stale IDs are tolerated because routing uses
`chats.owner_id`. Individual key deletion, delete-all, and password
reset remove the key without changing chat history or queue versions,
and the next lookup remints it. Suspension does not delete the key;
delegated gateway authorization rejects inactive users at request time.

This is the first PR in a three-PR rollout and must be fully deployed
before #27171.

Refs
https://linear.app/codercom/issue/CODAGT-561/maintain-synthetic-api-key-per-user-per-chat
2026-07-18 20:45:13 +02:00
Cian Johnston f7481c5d08 feat: Add full text search over chat messages (#27126)
Closes CODAGT-721
Closes CODAGT-722
Closes CODAGT-723
Closes CODAGT-724
Closes CODAGT-725

This PR adds the database and API pieces necessary to support full-text
chat message search.

- Adds required chat schema for full-text search
- Adds dbpurge job to populate search_tsv in the background
- Adds `search` parameter to GetChats query
- Adds `search` filter to `searchquery.Chats`
- Wires chat search filter into chats API

> Implemented by Coder Agents, reviewed and tested by a human.
2026-07-16 15:21:57 +01:00
Danielle Maywood d66e4d794f feat: add configurable reasoning effort to Coder agents (#26974) 2026-07-09 23:35:12 +01:00
Danny KoppingandClaude Opus 4.8 85f56e4944 fix: recreate ai_provider_type instead of ADD VALUE (#25895)
Coder runs all migrations in a single transaction (`pgTxnDriver`).
Postgres forbids using an enum value added by `ALTER TYPE ... ADD VALUE`
within the same transaction that added it. Migration `000499` widened
`ai_provider_type` with `ADD VALUE`, and `000504` casts existing
`chat_providers` rows to that enum in the same transaction. On
deployments with a legacy provider using one of the new values (for
example `openai-compat`), the batch failed with `unsafe use of new
value` and the server could not start.

Recreate the type (create a new enum, alter the column, drop and rename)
instead of using `ADD VALUE`, matching the existing precedent in
`000144_user_status_dormant`. A freshly created enum's values are usable
immediately in the same transaction, so the cast in `000504` succeeds.
The resulting schema is identical, so `make gen` produces no `dump.sql`
diff and databases that already applied these migrations see no drift.

Added a regression test that seeds an `openai-compat` provider and
applies `000499` through `000504` in a single transaction, reproducing
the production path. The per-step `Stepper` used by the other migration
tests commits each migration separately and cannot surface this class of
bug.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Danny Kopping <danny@coder.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:30:45 +00:00
Michael Suchacz 40878eeba4 feat: add AI provider schema expansion (#25412) 2026-05-22 02:16:01 +02:00
Garrett Delfosse 78d4cf9e47 fix: soft-delete stale workspace agents on new build (#25207) 2026-05-18 08:33:29 -04:00
Cian Johnston b5a625549e feat: migrate agents-access to org-scoped system role for proper chat RBAC (#24438)
The agents-access role previously granted chat permissions at user
scope, but chats are org-scoped objects. Rego skips user-level perms
when org_owner is set, making the grants invisible. Handler-level
band-aids used synthetic non-org-scoped objects as a workaround.

  - Migrates agents-access from users.rbac_roles (site-level) to
    organization_members.roles (org-scoped) via DB migration
  - Redefines agents-access as a predefined org-scoped builtin role
    alongside organization-admin, organization-auditor, etc., with
    Member permissions granting chat create/read/update
  - Excludes ResourceChat from OrgMemberPermissions so org membership
    alone no longer grants chat access
  - Fixes handler Authorize checks to use org-scoped objects with
semantically correct actions (ActionUpdate for message/tool operations)
  - Grants org admins the ability to assign agents-access

Closes #24250
Fixes CODAGT-174

Note: this does not update the "Usage" endpoints. Tracked by CODAGT-161.
> 🤖
2026-04-23 17:59:42 +01:00
Cian Johnston 3ce82bb885 feat: add chat-access site-wide role to gate chat creation (#23724)
- Add `chat-access` built-in role granting chat CRUD at User scope
- Exclude `ResourceChat` from member, org member, and org service
account `allPermsExcept` calls
- Allow system, owner, and user-admin to assign the new role
- Migration auto-assigns role to users who have ever created a chat
- Update RBAC test matrix: `memberMe` denied, `chatAccessUser` allowed

**Breaking change**: Members without `chat-access` lose chat creation
ability. Migration covers existing chat creators. Members who have never
created a chat do not get this role automatically applied.

> 🤖 This PR was created by a Coder Agent and reviewed by me.
2026-03-31 10:07:21 +01:00
Mathias Fredriksson ff156772f2 fix(coderd/database): move context creation to first use in migration tests (#23032)
The timeout was started before the unbounded Stepper loop, so
under CI load the deadline could expire before reaching the
operations that actually use it.

Also bumps TestMigration000387 from WaitLong to WaitSuperLong.

Fixes coder/internal#1398
2026-03-13 14:03:40 +02:00
Danielle Maywood 92a6d6c2c0 chore: remove unnecessary loop variable captures (#22180)
Since Go 1.22, the loop variable capture issue is resolved. Variables
declared by for loops are now per-iteration rather than per-loop, making
the 'v := v' pattern unnecessary.
2026-02-19 09:02:19 +00:00
Mathias Fredriksson 79728c30fa chore(coderd/database/migrations): migrate tasks to new data model (#20434)
Updates coder/internal#976
Closes coder/internal#1078
2025-10-23 19:29:23 +03:00
Dean Sheather 39bf3ba628 chore: replace GetManagedAgentCount query with aggregate table (#19636)
- Removes GetManagedAgentCount query
- Adds new table `usage_events_daily` which stores aggregated usage
events by the type and UTC day
- Adds trigger to update the values in this table when a new row is
inserted into `usage_events`
- Adds a migration that adds `usage_events_daily` rows for existing data
in `usage_events`
- Adds tests for the trigger
- Adds tests for the backfill query in the migration

Since the `usage_events` table is unreleased currently, this migration
will do nothing on real deployments and will only affect preview
deployments such as dogfood.

Closes https://github.com/coder/internal/issues/943
2025-08-30 03:39:37 +10:00
ケイラ fae30a00fd chore: remove unnecessary redeclarations in for loops (#18440) 2025-06-20 13:16:55 -06:00
Edward AngertandEdwardAngert f1cca03ed3 docs: reorganize the About section (#18236)
As part of an information architecture overhaul, this PR reorganizes the
About section and adds a Support section (but not content to it yet)

[preview](https://coder.com/docs/@docs-ia-about/about)

this PR is intentionally limited in scope so that we can ship meaningful
changes faster and followup PRs should include:

- [ ] edit + overhaul the About page
- [ ] decide on the `start` directory
- [ ] ~screenshots page updates~ (this should happen July or later)

redirects PR: https://github.com/coder/coder.com/pull/944

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-06-12 13:56:45 -04:00
Jon AyersandClaude 17ddee05e5 chore: update golang to 1.24.1 (#17035)
- 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>
2025-03-26 01:56:39 -05:00
Eng Zer Jun 04c33968cf refactor: replace golang.org/x/exp/slices with slices (#16772)
The experimental functions in `golang.org/x/exp/slices` are now
available in the standard library since Go 1.21.

Reference: https://go.dev/doc/go1.21#slices

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2025-03-04 00:46:49 +11:00
Yevhenii Shcherbina 98dfc70f31 fix(coderd/database): remove linux build tags from db package (#16633)
Remove linux build tags from database package to make sure we can run
tests on Mac OS.
2025-02-25 11:39:37 -05:00
Mathias Fredriksson c069563af1 test: fix use of t.Logf where t.Log would suffice (#16328) 2025-01-29 14:35:04 +00:00
Cian Johnston 7b88776403 chore(testutil): add testutil.GoleakOptions (#16070)
- Adds `testutil.GoleakOptions` and consolidates existing options to
this location
- Pre-emptively adds required ignore for this Dependabot PR to pass CI
https://github.com/coder/coder/pull/16066
2025-01-08 15:38:37 +00:00
Hugo Dutka 1bfa7d42e8 chore: add postgres template caching for tests (#15336)
This PR is the first in a series aimed at closing
[#15109](https://github.com/coder/coder/issues/15109).

### Changes

- **Template Database Creation:**  
`dbtestutil.Open` now has the ability to create a template database if
none is provided via `DB_FROM`. The template database’s name is derived
from a hash of the migration files, ensuring that it can be reused
across tests and is automatically updated whenever migrations change.

- **Optimized Database Handling:**  
Previously, `dbtestutil.Open` would spin up a new container for each
test when `DB_FROM` was unset. Now, it first checks for an active
PostgreSQL instance on `localhost:5432`. If none is found, it creates a
single container that remains available for subsequent tests,
eliminating repeated container startups.

These changes address the long individual test times (10+ seconds)
reported by some users, likely due to the time Docker took to start and
complete migrations.
2024-11-04 17:23:31 +01:00
Marcin Tojek 6de59371ea feat: notifications: report failed workspace builds (#14571) 2024-09-18 09:11:44 +02:00
Marcin Tojek b8b80fe6d2 feat: store coder_workspace_tags in the database (#13294) 2024-05-20 13:30:19 +00:00
Cian Johnston 5454f4997b chore(ci): clean up databases after test finishes in CI (#12702) 2024-03-21 14:53:16 +00:00
Kyle Carberry 8abca9bea7 chore: rename git_auth to external_auth in our schema (#9935)
* chore: rename `git_auth` to `external_auth` in our schema

We're changing Git auth to be external auth. It will support
any OAuth2 or OIDC provider.

To split up the larger change I want to contribute the schema
changes first, and I'll add the feature itself in another PR.

* Fix names

* Fix outdated view

* Rename some additional places

* Fix sort order

* Fix template versions auth route

* Fix types

* Fix dbauthz
2023-09-29 19:13:20 +00:00
Cian JohnstonandKyle Carberry 7918e65510 feat(coderd): add dbcrypt package (#9522)
- Adds package enterprise/dbcrypt to implement database encryption/decryption
- Adds table dbcrypt_keys and associated queries
- Adds columns oauth_access_token_key_id and oauth_refresh_token_key_id
  to tables git_auth_links and user_links

Co-authored-by: Kyle Carberry <kyle@coder.com>
2023-09-06 12:06:26 +01:00
Kyle Carberry 22e781eced chore: add /v2 to import module path (#9072)
* chore: add /v2 to import module path

go mod requires semantic versioning with versions greater than 1.x

This was a mechanical update by running:
```
go install github.com/marwan-at-work/mod/cmd/mod@latest
mod upgrade
```

Migrate generated files to import /v2

* Fix gen
2023-08-18 18:55:43 +00:00
Colin Adler 9a0ba1bdc3 fix(coderd): remove CREATE INDEX CONCURRENTLY from migrations (#8353) 2023-07-06 16:44:29 -05:00
Ammar Bandukwala f6db95e71c test(coderd/database/migrations): increase fixture test timeout 2023-06-07 23:17:29 +00:00
Kyle Carberry 70d2203b9e chore: reduce the log output of skipped tests (#7520)
With the introduction of the workspace proxy tests there was a lot
of output if a test was eventually skipped.
2023-05-14 19:37:00 -05:00
Ammar Bandukwala 2bd6d2908e feat: convert entire CLI to clibase (#6491)
I'm sorry.
2023-03-23 17:42:20 -05:00
Marcin Tojek 3b7b96ac28 feat: Expose managed variables via API (#6134)
* WIP

* hcl

* useManagedVariables

* fix

* Fix

* Fix

* fix

* go:build

* Fix

* fix: bool flag

* Insert template variables

* API

* fix

* Expose via API

* More wiring

* CLI for testing purposes

* WIP

* Delete FIXME

* planVars

* WIP

* WIP

* UserVariableValues

* no dry run

* Dry run

* Done FIXME

* Fix

* Fix: CLI

* Fix: migration

* API tests

* Test info

* Tests

* More tests

* fix: lint

* Fix: authz

* Address PR comments

* Fix

* fix

* fix
2023-02-15 18:24:15 +01:00
Mathias Fredriksson b46d0d693f fix: Extend migration fixture test with down and fix 000045 (#6130) 2023-02-09 16:59:54 +02:00
Marcin Tojek 6ebadabe4e feat: Add basic support for rich parameters to coderd and provisionerd (#5710) 2023-01-17 11:22:11 +01:00
Mathias Fredriksson e906d0dc54 feat: Add database fixtures for testing migrations (#4858) 2022-11-08 19:59:44 +02:00
Dean Sheather 29d804e692 feat: add API key scopes and application_connect scope (#4067) 2022-09-19 17:39:02 +00:00