Validate keys in `glab config set` against the config schema
## Summary `glab config set <key> <value>` accepts any arbitrary key without validation. Unknown keys get written to the config file and `glab config get` reads them back, but nothing in the codebase consumes them. This creates a UX trap: users discover plausible-sounding keys (or invent them based on docs or intuition), set them, see the value round-trip via `get`, and reasonably assume they're being applied. ## Example Surfaced in [#8334](https://gitlab.com/gitlab-org/cli/-/work_items/8334), where a user set `oauth_scopes` (not a real config key) and concluded the CLI was ignoring it: ``` glab config set oauth_scopes "openid profile read_user read_api read_repository" --host <self-managed-host> glab config get oauth_scopes --host <self-managed-host> # => openid profile read_user read_api read_repository ``` The value silently sits in `~/.config/glab-cli/config.yml` and nothing reads it. ## Proposed work ### 1. Sweep [`internal/config/config.yaml.lock`](https://gitlab.com/gitlab-org/cli/-/blob/main/internal/config/config.yaml.lock) for missing keys The lock file is already the canonical schema (consumed by `gen.go` → `config_stub.go` to produce the default config tree), but it's currently incomplete. Keys read by the codebase but absent from the lock: - **User-settable** (should be added): `client_id`, `ca_cert`, `client_cert`, `client_key`, `skip_tls_verify`, `use_keyring`, `job_token`, `user`, `auto_download`, `branch_prefix` - **Internal state** (CLI-managed, decide whether to register with a marker or exclude from validation): `is_oauth2`, `oauth2_expiry_date`, `oauth2_refresh_token`, `refresh_token`, `last_update_check` Add the user-settable ones with appropriate scoping (global vs per-host) and inline doc comments. ### 2. Wire validation into [`internal/commands/config/set/config_set.go`](https://gitlab.com/gitlab-org/cli/-/blob/main/internal/commands/config/set/config_set.go) Load the lock-file key set at init, check `o.key` against it (including prefix-matched families like `duo_cli_*` and `orbit_local_*`), and either: - **Warn-but-allow** — additive, lowest risk, preserves existing configs with stray keys. - **Reject by default with a `--force` escape** — stronger signal, but breaks users who have stray keys today. Suggested starting point: warn-but-allow, reassess after some time in the field. ### 3. Document the convention Update [`internal/config/Readme.md`](https://gitlab.com/gitlab-org/cli/-/blob/main/internal/config/Readme.md) so future contributors know that adding a new config key requires updating the lock file. Consider a CI lint or test that diffs `cfg.Get(..., "<key>")` literals against the lock to catch drift. ## Out of scope - Whether `oauth_scopes` itself should become a real, honored config key (separate design conversation; see discussion in #8334). - Migrating users' existing configs to remove orphaned keys.
issue