Summary
Server (auth_providers/command_config.go) has no client-timeout field, so every GetServerConfig() implementation silently drops CommandAuthConfig.HttpClientTimeout. Any downstream consumer that authenticates once and then rebuilds a client from the returned *Server (the documented handoff pattern used by keyfactor-go-client v3 NewKeyfactorClient and keyfactor-go-client-sdk NewAPIClient) loses the configured timeout and falls back to DefaultClientTimeout (60s) unless the KEYFACTOR_CLIENT_TIMEOUT env var happens to be set.
Impact
Callers that configure a longer timeout via WithClientTimeout() still get 60s transport timeouts (TLSHandshakeTimeout, ResponseHeaderTimeout, IdleConnTimeout, ExpectContinueTimeout are all derived from HttpClientTimeout in BuildTransport() / SetClient()).
Real-world failure: terraform-provider-keyfactor v2.9.1 exposes request_timeout and applies it with WithClientTimeout(), but the value never survives the GetServerConfig() → NewKeyfactorClient(serverConfig) round-trip. Long-running PFX enrollments (slow CA) then fail at ~60s with:
Post "https://<command-host>/KeyfactorAPI/Enrollment/PFX": net/http: timeout awaiting response headers
even though the user set request_timeout = 300. (ResponseHeaderTimeout fires at the 60s default.)
Repro
cfg := &auth_providers.CommandConfigOauth{}
cfg.CommandAuthConfig.
WithCommandHostName("command.example.com").
WithClientTimeout(300)
_ = cfg.Authenticate()
server := cfg.GetServerConfig()
// server has no timeout field — 300 is gone.
// Downstream (go-client / SDK) rebuilds:
rebuilt := auth_providers.CommandAuthConfig{CommandHostName: server.Host /* ... */}
_ = rebuilt.Authenticate() // HttpClientTimeout==0 → falls back to 60s default
Proposed fix
- Add
ClientTimeout int (json/yaml client_timeout) to Server.
- Populate it from
HttpClientTimeout in all GetServerConfig() implementations (core, basic, oauth, kerberos).
- Honor
Server.ClientTimeout in config-loading paths so round-trips are lossless.
Downstream: keyfactor-go-client v3 and keyfactor-go-client-sdk should copy cfg.ClientTimeout into CommandAuthConfig.HttpClientTimeout when rebuilding from a *Server.
Workaround
Set the KEYFACTOR_CLIENT_TIMEOUT environment variable (seconds) in the process environment — the rebuilt config still reads it when the struct value is zero.
Summary
Server(auth_providers/command_config.go) has no client-timeout field, so everyGetServerConfig()implementation silently dropsCommandAuthConfig.HttpClientTimeout. Any downstream consumer that authenticates once and then rebuilds a client from the returned*Server(the documented handoff pattern used by keyfactor-go-client v3NewKeyfactorClientand keyfactor-go-client-sdkNewAPIClient) loses the configured timeout and falls back toDefaultClientTimeout(60s) unless theKEYFACTOR_CLIENT_TIMEOUTenv var happens to be set.Impact
Callers that configure a longer timeout via
WithClientTimeout()still get 60s transport timeouts (TLSHandshakeTimeout,ResponseHeaderTimeout,IdleConnTimeout,ExpectContinueTimeoutare all derived fromHttpClientTimeoutinBuildTransport()/SetClient()).Real-world failure: terraform-provider-keyfactor v2.9.1 exposes
request_timeoutand applies it withWithClientTimeout(), but the value never survives theGetServerConfig()→NewKeyfactorClient(serverConfig)round-trip. Long-running PFX enrollments (slow CA) then fail at ~60s with:even though the user set
request_timeout = 300. (ResponseHeaderTimeoutfires at the 60s default.)Repro
Proposed fix
ClientTimeout int(json/yamlclient_timeout) toServer.HttpClientTimeoutin allGetServerConfig()implementations (core, basic, oauth, kerberos).Server.ClientTimeoutin config-loading paths so round-trips are lossless.Downstream: keyfactor-go-client v3 and keyfactor-go-client-sdk should copy
cfg.ClientTimeoutintoCommandAuthConfig.HttpClientTimeoutwhen rebuilding from a*Server.Workaround
Set the
KEYFACTOR_CLIENT_TIMEOUTenvironment variable (seconds) in the process environment — the rebuilt config still reads it when the struct value is zero.