## What & why
Admin/setup docs lead with `coder server --flag` examples, but most
operators configure Coder through `CODER_*` environment variables
(system service, container, or Helm chart). There is no single page
mapping a setting to its env var, CLI flag, YAML key, and default, so
searching the docs for an env var name such as `CODER_PG_CONNECTION_URL`
returns nothing.
This adds a generated configuration reference and begins shifting admin
docs to lead with the environment-variable form.
## Changes
- **Generated configuration reference**
(`docs/admin/setup/configuration-reference.md`): a searchable,
per-setting list of every visible deployment option. Each option is a
heading (grouped and nested by serpent group) followed by its
description and the environment variable, CLI flag, YAML key, and
default that apply to it. Generated from `codersdk.DeploymentValues` so
it stays in sync.
- **Generator + `make gen` wiring** (`scripts/configdocgen/`): new
binary plus a Makefile target and `GEN_FILES` entry, mirroring the
existing `clidocgen` / `auditdocgen` pattern. Output is host-independent
(same env normalization as `clidocgen`).
- **Demo conversion** (`docs/admin/users/github-auth.md`): inverted to
lead with the `/etc/coder.d/coder.env` env-var form; the CLI-flag form
becomes a closing note that links to the reference. H2 slugs preserved.
- **Style guide** (`.claude/docs/DOCS_STYLE_GUIDE.md`): documents the
env-var-first convention for admin/setup docs.
- **Navigation**: manifest entry under Administration → Setup, plus a
TIP callout on the setup index.
## Risk
Docs + gen pipeline only; no runtime change. The page is regenerated by
`make gen`; the `gen` and `check-docs` CI checks pass.
## Follow-up
Several other admin pages still lead with flag walls. Recommend sweeping
them incrementally in separate PRs rather than expanding scope here.
<details>
<summary>Implementation notes (provenance, conflict resolution,
verification)</summary>
- Continues prior work by @aslilac and @bpmct from the
`kayla/docs-env-vars-first` branch. Both original commits are
cherry-picked here with authorship preserved.
- Rebased onto current `main`. Resolved two `Makefile` conflicts where
`main` had since added the `feature-stages.md` gen target at the same
locations; kept both targets (union) in `GEN_FILES`, `gen/mark-fresh`,
and the recipe block.
- The original branch's checked-in page predated recent
`codersdk.DeploymentValues` changes, so it was **regenerated** against
current `main` (adds `CODER_SCIM_USE_LEGACY`, the `Networking / Cluster`
section with `CODER_CLUSTER_HOST`, `CODER_BOUNDARY_LOG_RETENTION`, and
the AI Gateway description rename). The `gen` CI check enforces this
stays current.
- Fixed flag-link anchors for short-form flags (`--config`,
`--log-filter`): the generator derives the anchor from `FlagShorthand`
to match `clidocgen`'s heading (e.g. `#-l---log-filter`).
- `linkspector` ignores the AWS Bedrock base URL that appears as an
illustrative `<region>` placeholder in an option description, consistent
with the existing `openai.com` ignore patterns.
</details>
<details>
<summary>Configuration reference layout (2026-07-08 update)</summary>
Reworked the reference from a wide table into a nested, per-setting list
so it fits without horizontal scrolling and stops repeating the group
name in every heading:
- **List, not table.** Each option renders as a heading, its
description, and a bullet list of only the configuration methods that
apply to it (non-applicable methods are omitted instead of shown as
`-`).
- **Nested sections.** Sections nest by the serpent group hierarchy, so
`Email / Email Authentication` becomes `Email` (h2) with an `Email
authentication` (h3) subsection instead of a redundant flat title.
- **Shorter, sentence-case headings.** The redundant group prefix is
stripped from each option name and the remainder is lowercased to
sentence case, preserving acronyms and mixed-case tokens (`URL`, `TLS`,
`OAuth2`, `GitHub`) plus a small proper-noun allowlist (`Coder`,
`Terraform`, `Honeycomb`, `Anthropic`, `Bedrock`, ...). Example: `AI
Gateway Send Actor Headers` becomes `Send actor headers`.
- **Deprecated options** sort to the end of each section and lead with
an emphasized **Deprecated** marker. Headings stay clean (no
`(deprecated)` suffix) so their anchors remain stable.
- **Section intros** render from a group's `Description` when the source
defines one (e.g. DERP); no hand-maintained prose or links are
introduced.
All transformations run in pure Go at `make gen` time (no AI at
generation time). Generation is idempotent, and `markdownlint` and
`golangci-lint` both pass.
</details>
---
🤖 Opened by Coder Agents on behalf of @nickvigilante. Continues work by
@aslilac and @bpmct.
---------
Co-authored-by: Kayla (via Coder Agents) <kayla@coder.com>
Co-authored-by: Coder Agents <noreply@coder.com>
Co-authored-by: Ben Potter <me@bpmct.net>
## Problem
On a fresh deployment with no custom GitHub OAuth app, Coder falls back
to the default Coder-managed GitHub app. That app can only see
organization memberships in organizations where it has been installed.
If `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` is set but the app isn't installed
in the allowed organizations, the membership list comes back empty and
every login, including the first admin login, is rejected with a bare
"You aren't a member of the authorized Github organizations!" with no
hint about the actual cause. This leaves fresh deployments in an
apparently broken state.
## Fix
* Append a remediation hint to the login rejection when the default
provider is configured, pointing at the [app installation
page](<https://github.com/apps/coder/installations/select_target>) and
at configuring a custom GitHub OAuth app.
* Log a startup warning when the default provider is combined with
`CODER_OAUTH2_GITHUB_ALLOWED_ORGS`, listing the allowed orgs and the
install URL.
* Document the installation requirement next to the
`CODER_OAUTH2_GITHUB_ALLOWED_ORGS` step in the GitHub auth docs.
Access-control behavior is unchanged; the org check still rejects logins
as before, it just explains why and how to fix it.
## Testing
* New `TestUserOAuth2Github/NotInAllowedOrganizationDefaultProvider`
asserts the hint appears when `DefaultProviderConfigured` is set; the
existing `NotInAllowedOrganization` subtest asserts it does not leak
into the custom-app path.
Fixescoder/coder#17752
Normalizes non-standard code-fence language tags across `docs/**` so a
strict highlighter (Shiki, used by Fumadocs) won't fail the build on an
unrecognized language, and unifies redundant synonym tags onto one
canonical form per language. The current renderer (Speed-Highlight)
detects the language from the code content, not the fence label, so this
drift wasn't visible until now.
## Changes
- `hcl` -> `tf` (199 fences, including indented ones nested in
numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two
distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**`
is actually Terraform resource/data/provider syntax, so the more
specific `terraform` grammar is correct for all of them. `tf` is Shiki's
own alias for that grammar, and it's also what GitHub's own markdown
renderer resolves to the same HCL/Terraform highlighting.
- `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered
PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a
registered file extension (`.ps` isn't), so `ps1` renders identically to
`powershell` there today while bare `ps` would silently lose
highlighting.
- `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files)
- `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text
fallback either way, just shorter.
- `Dockerfile` -> `dockerfile` (lowercase)
- `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all
three to a single shell grammar; this was already the style guide's
stated preference, just not enforced across the existing corpus until
now.
- `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki
and GitHub.
- `jsonc` -> `json` (1 fence). The block has no comments or trailing
commas, so it doesn't need the comments-capable grammar.
- `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`).
Verified the actual content tokenizes identically under both grammars,
and a sibling block in the same file already needs `tsx` for real JSX,
so unifying to one tag is safe for this file. Documented a caveat: `tsx`
mis-tokenizes the legacy angle-bracket type-assertion syntax
(`<Type>value`), which is invalid in real `.tsx` files anyway, so use
`value as Type` instead.
- `yml` -> `yaml` (1 fence)
- Updated `docs/.style/style-guide/formatting.md` to document all
canonical tags
`promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki
doesn't bundle a grammar for either, so they need a custom grammar
registration when the site adopts Shiki, rather than degrading to `txt`.
Tracked as follow-up work under DOCS-118 and
[DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting)
(promql).
Does not touch `offlinedocs/`.
Linear:
[DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs)
<details>
<summary>How the fence tags were verified</summary>
Each tag was tested against a real `shiki@latest` highlighter instance
(`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's
`@wooorm/starry-night` grammar sources (the renderer that actually
displays these `.md` files today, in repo browsing and PR diffs), since
that's what determines whether brevity is safe before Shiki adoption:
```text
FAIL env -- Language `env` is not included in this bundle.
FAIL Dockerfile -- Language `Dockerfile` is not included in this bundle.
FAIL promql -- Language `promql` is not included in this bundle.
FAIL caddyfile -- Language `caddyfile` is not included in this bundle.
FAIL pwsh -- Language `pwsh` is not included in this bundle.
FAIL output -- Language `output` is not included in this bundle.
```
`hcl` doesn't error in Shiki, since it's a real grammar, but that's
exactly the trap: it was silently rendering every fence with the generic
HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged
fence in `docs/**` was manually checked against `origin/main` and is
genuinely Terraform content.
For `ts`/`tsx`, tokenizing the actual doc content confirmed identical
output under both grammars; a synthetic test with the legacy
angle-bracket cast syntax confirmed `tsx` degrades on that specific
construct, which the style guide now calls out.
The first normalization pass only matched fence tags at column 0
(`^```tag$`), missing tags indented inside numbered/bulleted lists. A
follow-up pass caught the remaining occurrences at any indentation
level.
</details>
---
*This PR description and the underlying changes were prepared with Coder
Agents assistance.*
## Issue
Closes#16824
Document that the default GitHub authentication app provided by Coder
requires device flow, and that this behavior cannot be overridden.
## Changes Made
Claude updated the GitHub authentication documentation to:
1. Add a prominent warning in the Default Configuration section
explaining that the default GitHub app requires device flow and ignores
the `CODER_OAUTH2_GITHUB_DEVICE_FLOW` setting
2. Clarify the Device Flow section to indicate that:
- Device flow is always enabled for the default GitHub app
- Device flow is optional for custom GitHub OAuth apps
- The `CODER_OAUTH2_GITHUB_DEVICE_FLOW` setting is ignored when using
the default app
[preview](https://coder.com/docs/@16824-github-device-flow/admin/users/github-auth)
<sub>🤖 Generated with [Claude Code](https://claude.ai/code)</sub>
---------
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: M Atif Ali <atif@coder.com>