feat(api): support dynamic custom headers for authenticating proxies
What does this MR do and why?
Adds generic command-backed custom HTTP headers for GitLab instances protected by an authenticating proxy. This replaces the earlier Google IAP-specific implementation with configuration that can support IAP and other proxy providers.
Each entry under custom_headers accepts exactly one source:
valuefor a literal valuevalueFromEnvfor an environment variablevalueFromCommandfor the trimmed stdout of an executable
Command output is resolved once while initializing the client and cached once per configured header for the lifetime of the glab process, avoiding repeated token-generation commands on every request. Commands are limited to 30 seconds. Empty output, multiline output, NUL bytes, invalid command syntax, timeouts, and non-zero exits produce actionable errors.
The shared HTTP RoundTripper injects resolved headers for API calls, raw glab api requests, and OAuth refresh requests. Configured custom headers are authoritative, matching the prior go-gitlab request-option behavior. The transport clones requests before mutation and only injects headers for configured GitLab/API hosts so credentials cannot leak across redirects. With GLAB_DEBUG_HTTP, custom headers remain visible while known sensitive values are redacted.
Google IAP example
A Google IAP identity token can be supplied through either an environment variable or a command, as documented in the custom-header section of the README. For example, valueFromCommand can invoke gcloud auth print-identity-token with the configured service account and audience.
The earlier IAP-specific config keys, login flags, Go package, Google dependency, and glab iap configure-ssh command have been removed. SSH-over-IAP setup is outside the CLI implementation and can be covered by provider-specific documentation instead.
Verification
go test ./...go test -race -tags=integration ./internal/api -run ^$golangci-lint run --new-from-rev=origin/mainmake build- Live read-only API smoke tests against the IAP-protected
gitlab-prod.thearmory-gss.cloudinstance using bothvalueFromEnvandvalueFromCommand
The live tests used the existing armory profile and stored GitLab PAT; no credentials are embedded in this MR.