fix(lint): G117 annotate intentional secret-pattern fields in DTOs and config structs
- commit
- b5f59d8484bbc49772f90b011b0a6673082a1fd3
- author
- bnema · · 2026-02-25 02:06 UTC
- parent
- 18a731f
- signature
- unsigned
7 files · +15 -12
M internal/adapters/in/cli/remote/auth.go +1 -1
| @@ -45,7 +45,7 @@ func (c *Client) Authenticate(ctx context.Context, username, password string) (* | |||
| 45 | 45 | req.Header.Set("Content-Type", "application/json") | |
| 46 | 46 | req.Header.Set("Accept", "application/json") | |
| 47 | 47 | ||
| 48 | - | resp, err := c.httpClient.Do(req) | |
| 48 | + | resp, err := c.httpClient.Do(req) //nolint:gosec // G704: CLI outbound request to user-configured remote endpoint, not server-side SSRF | |
| 49 | 49 | if err != nil { | |
| 50 | 50 | return nil, fmt.Errorf("failed to connect: %w", err) | |
| 51 | 51 | } | |
| @@ -45,7 +45,7 @@ func (c *Client) Authenticate(ctx context.Context, username, password string) (* | |||||
| 45 | req.Header.Set("Content-Type", "application/json") | 45 | req.Header.Set("Content-Type", "application/json") | ||
| 46 | req.Header.Set("Accept", "application/json") | 46 | req.Header.Set("Accept", "application/json") | ||
| 47 | 47 | ||||
| 48 | - | resp, err := c.httpClient.Do(req) | 48 | + | resp, err := c.httpClient.Do(req) //nolint:gosec // G704: CLI outbound request to user-configured remote endpoint, not server-side SSRF |
| 49 | if err != nil { | 49 | if err != nil { | ||
| 50 | return nil, fmt.Errorf("failed to connect: %w", err) | 50 | return nil, fmt.Errorf("failed to connect: %w", err) | ||
| 51 | } | 51 | } | ||
M internal/adapters/in/cli/remote/client.go +1 -1
| @@ -150,7 +150,7 @@ func (c *Client) request(ctx context.Context, method, path string, body any) (*h | |||
| 150 | 150 | req.Header.Set("Authorization", "Bearer "+c.token) | |
| 151 | 151 | } | |
| 152 | 152 | ||
| 153 | - | resp, err := c.httpClient.Do(req) | |
| 153 | + | resp, err := c.httpClient.Do(req) //nolint:gosec // G704: CLI outbound request to user-configured remote, not server-side SSRF | |
| 154 | 154 | if err != nil { | |
| 155 | 155 | return nil, err | |
| 156 | 156 | } | |
| @@ -150,7 +150,7 @@ func (c *Client) request(ctx context.Context, method, path string, body any) (*h | |||||
| 150 | req.Header.Set("Authorization", "Bearer "+c.token) | 150 | req.Header.Set("Authorization", "Bearer "+c.token) | ||
| 151 | } | 151 | } | ||
| 152 | 152 | ||||
| 153 | - | resp, err := c.httpClient.Do(req) | 153 | + | resp, err := c.httpClient.Do(req) //nolint:gosec // G704: CLI outbound request to user-configured remote, not server-side SSRF |
| 154 | if err != nil { | 154 | if err != nil { | ||
| 155 | return nil, err | 155 | return nil, err | ||
| 156 | } | 156 | } | ||
M internal/adapters/in/http/auth/handler.go +2 -2
| @@ -20,7 +20,7 @@ import ( | |||
| 20 | 20 | // InternalAuth holds credentials for internal loopback registry access. | |
| 21 | 21 | type InternalAuth struct { | |
| 22 | 22 | Username string | |
| 23 | - | Password string | |
| 23 | + | Password string //nolint:gosec // auth handler internal credential struct for loopback registry access | |
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | 26 | // Handler handles authentication requests at /auth/*. | |
| @@ -42,7 +42,7 @@ func NewHandler(authSvc in.AuthService, internalAuth InternalAuth, log zerowrap. | |||
| 42 | 42 | // PasswordRequest represents the request body for POST /auth/password. | |
| 43 | 43 | type PasswordRequest struct { | |
| 44 | 44 | Username string `json:"username"` | |
| 45 | - | Password string `json:"password"` | |
| 45 | + | Password string `json:"password"` //nolint:gosec // auth handler request DTO: password field is intentional for the auth endpoint | |
| 46 | 46 | } | |
| 47 | 47 | ||
| 48 | 48 | // PasswordResponse represents the response from POST /auth/password. | |
| @@ -20,7 +20,7 @@ import ( | |||||
| 20 | // InternalAuth holds credentials for internal loopback registry access. | 20 | // InternalAuth holds credentials for internal loopback registry access. | ||
| 21 | type InternalAuth struct { | 21 | type InternalAuth struct { | ||
| 22 | Username string | 22 | Username string | ||
| 23 | - | Password string | 23 | + | Password string //nolint:gosec // auth handler internal credential struct for loopback registry access |
| 24 | } | 24 | } | ||
| 25 | 25 | ||||
| 26 | // Handler handles authentication requests at /auth/*. | 26 | // Handler handles authentication requests at /auth/*. | ||
| @@ -42,7 +42,7 @@ func NewHandler(authSvc in.AuthService, internalAuth InternalAuth, log zerowrap. | |||||
| 42 | // PasswordRequest represents the request body for POST /auth/password. | 42 | // PasswordRequest represents the request body for POST /auth/password. | ||
| 43 | type PasswordRequest struct { | 43 | type PasswordRequest struct { | ||
| 44 | Username string `json:"username"` | 44 | Username string `json:"username"` | ||
| 45 | - | Password string `json:"password"` | 45 | + | Password string `json:"password"` //nolint:gosec // auth handler request DTO: password field is intentional for the auth endpoint |
| 46 | } | 46 | } | ||
| 47 | 47 | ||||
| 48 | // PasswordResponse represents the response from POST /auth/password. | 48 | // PasswordResponse represents the response from POST /auth/password. | ||
M internal/adapters/in/http/middleware/auth.go +1 -1
| @@ -48,7 +48,7 @@ func redactUsername(username string) string { | |||
| 48 | 48 | // These are generated per Gordon instance and are never exposed in config. | |
| 49 | 49 | type InternalRegistryAuth struct { | |
| 50 | 50 | Username string | |
| 51 | - | Password string | |
| 51 | + | Password string //nolint:gosec // auth middleware credential struct for loopback-only registry access | |
| 52 | 52 | } | |
| 53 | 53 | ||
| 54 | 54 | // RegistryAuthV2 middleware provides enhanced Docker Registry authentication | |
| @@ -48,7 +48,7 @@ func redactUsername(username string) string { | |||||
| 48 | // These are generated per Gordon instance and are never exposed in config. | 48 | // These are generated per Gordon instance and are never exposed in config. | ||
| 49 | type InternalRegistryAuth struct { | 49 | type InternalRegistryAuth struct { | ||
| 50 | Username string | 50 | Username string | ||
| 51 | - | Password string | 51 | + | Password string //nolint:gosec // auth middleware credential struct for loopback-only registry access |
| 52 | } | 52 | } | ||
| 53 | 53 | ||||
| 54 | // RegistryAuthV2 middleware provides enhanced Docker Registry authentication | 54 | // RegistryAuthV2 middleware provides enhanced Docker Registry authentication | ||
M internal/adapters/out/telemetry/provider.go +1 -1
| @@ -23,7 +23,7 @@ import ( | |||
| 23 | 23 | type Config struct { | |
| 24 | 24 | Enabled bool `mapstructure:"enabled"` | |
| 25 | 25 | Endpoint string `mapstructure:"endpoint"` // OTLP HTTP endpoint, e.g. "http://localhost:4318" | |
| 26 | - | AuthToken string `mapstructure:"auth_token"` // Basic auth token (base64 encoded user:pass) | |
| 26 | + | AuthToken string `mapstructure:"auth_token"` //nolint:gosec // telemetry provider API token field, required by external OTLP API schema | |
| 27 | 27 | Traces bool `mapstructure:"traces"` // Enable trace export | |
| 28 | 28 | Metrics bool `mapstructure:"metrics"` // Enable metric export | |
| 29 | 29 | Logs bool `mapstructure:"logs"` // Bridge zerowrap logs to OTLP | |
| @@ -23,7 +23,7 @@ import ( | |||||
| 23 | type Config struct { | 23 | type Config struct { | ||
| 24 | Enabled bool `mapstructure:"enabled"` | 24 | Enabled bool `mapstructure:"enabled"` | ||
| 25 | Endpoint string `mapstructure:"endpoint"` // OTLP HTTP endpoint, e.g. "http://localhost:4318" | 25 | Endpoint string `mapstructure:"endpoint"` // OTLP HTTP endpoint, e.g. "http://localhost:4318" | ||
| 26 | - | AuthToken string `mapstructure:"auth_token"` // Basic auth token (base64 encoded user:pass) | 26 | + | AuthToken string `mapstructure:"auth_token"` //nolint:gosec // telemetry provider API token field, required by external OTLP API schema |
| 27 | Traces bool `mapstructure:"traces"` // Enable trace export | 27 | Traces bool `mapstructure:"traces"` // Enable trace export | ||
| 28 | Metrics bool `mapstructure:"metrics"` // Enable metric export | 28 | Metrics bool `mapstructure:"metrics"` // Enable metric export | ||
| 29 | Logs bool `mapstructure:"logs"` // Bridge zerowrap logs to OTLP | 29 | Logs bool `mapstructure:"logs"` // Bridge zerowrap logs to OTLP | ||
M internal/adapters/out/tokenstore/unsafe.go +1 -1
| @@ -61,7 +61,7 @@ func NewUnsafeStore(dataDir string, log zerowrap.Logger) (*UnsafeStore, error) { | |||
| 61 | 61 | ||
| 62 | 62 | // unsafeTokenData holds both JWT and metadata in a single file. | |
| 63 | 63 | type unsafeTokenData struct { | |
| 64 | - | JWT string `json:"jwt"` | |
| 64 | + | JWT string `json:"jwt"` //nolint:gosec // token store persistence format: jwt field name is intentional | |
| 65 | 65 | Metadata tokenMetadata `json:"metadata"` | |
| 66 | 66 | } | |
| 67 | 67 | ||
| @@ -61,7 +61,7 @@ func NewUnsafeStore(dataDir string, log zerowrap.Logger) (*UnsafeStore, error) { | |||||
| 61 | 61 | ||||
| 62 | // unsafeTokenData holds both JWT and metadata in a single file. | 62 | // unsafeTokenData holds both JWT and metadata in a single file. | ||
| 63 | type unsafeTokenData struct { | 63 | type unsafeTokenData struct { | ||
| 64 | - | JWT string `json:"jwt"` | 64 | + | JWT string `json:"jwt"` //nolint:gosec // token store persistence format: jwt field name is intentional |
| 65 | Metadata tokenMetadata `json:"metadata"` | 65 | Metadata tokenMetadata `json:"metadata"` | ||
| 66 | } | 66 | } | ||
| 67 | 67 | ||||
M internal/app/run.go +8 -5
| @@ -126,7 +126,7 @@ type Config struct { | |||
| 126 | 126 | Type string `mapstructure:"type"` // "password" or "token" | |
| 127 | 127 | SecretsBackend string `mapstructure:"secrets_backend"` // "pass", "sops", or "unsafe" | |
| 128 | 128 | Username string `mapstructure:"username"` | |
| 129 | - | Password string `mapstructure:"password"` // deprecated: use password_hash | |
| 129 | + | Password string `mapstructure:"password"` //nolint:gosec // config struct field mapped from TOML config file (deprecated, use password_hash) | |
| 130 | 130 | PasswordHash string `mapstructure:"password_hash"` // path in secrets backend | |
| 131 | 131 | TokenSecret string `mapstructure:"token_secret"` // path in secrets backend | |
| 132 | 132 | TokenExpiry string `mapstructure:"token_expiry"` // e.g., "720h", "30d" | |
| @@ -747,7 +747,7 @@ func randomTokenHex(size int) (string, error) { | |||
| 747 | 747 | // InternalCredentials holds the internal registry credentials for CLI access. | |
| 748 | 748 | type InternalCredentials struct { | |
| 749 | 749 | Username string `json:"username"` | |
| 750 | - | Password string `json:"password"` | |
| 750 | + | Password string `json:"password"` //nolint:gosec // internal credential wire format: json key is intentional for CLI interop | |
| 751 | 751 | } | |
| 752 | 752 | ||
| 753 | 753 | // getSecureRuntimeDir returns a secure directory for runtime files. | |
| @@ -755,9 +755,12 @@ type InternalCredentials struct { | |||
| 755 | 755 | func getSecureRuntimeDir() (string, error) { | |
| 756 | 756 | // Try XDG_RUNTIME_DIR first (typically /run/user/<uid> on Linux) | |
| 757 | 757 | if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" { | |
| 758 | - | gordonDir := filepath.Join(runtimeDir, "gordon") | |
| 759 | - | if err := os.MkdirAll(gordonDir, 0700); err == nil { | |
| 760 | - | return gordonDir, nil | |
| 758 | + | runtimeDir = filepath.Clean(runtimeDir) | |
| 759 | + | if filepath.IsAbs(runtimeDir) { | |
| 760 | + | gordonDir := filepath.Join(runtimeDir, "gordon") | |
| 761 | + | if err := os.MkdirAll(gordonDir, 0700); err == nil { //nolint:gosec // G703: path cleaned and verified absolute before use | |
| 762 | + | return gordonDir, nil | |
| 763 | + | } | |
| 761 | 764 | } | |
| 762 | 765 | } | |
| 763 | 766 | ||
| @@ -126,7 +126,7 @@ type Config struct { | |||||
| 126 | Type string `mapstructure:"type"` // "password" or "token" | 126 | Type string `mapstructure:"type"` // "password" or "token" | ||
| 127 | SecretsBackend string `mapstructure:"secrets_backend"` // "pass", "sops", or "unsafe" | 127 | SecretsBackend string `mapstructure:"secrets_backend"` // "pass", "sops", or "unsafe" | ||
| 128 | Username string `mapstructure:"username"` | 128 | Username string `mapstructure:"username"` | ||
| 129 | - | Password string `mapstructure:"password"` // deprecated: use password_hash | 129 | + | Password string `mapstructure:"password"` //nolint:gosec // config struct field mapped from TOML config file (deprecated, use password_hash) |
| 130 | PasswordHash string `mapstructure:"password_hash"` // path in secrets backend | 130 | PasswordHash string `mapstructure:"password_hash"` // path in secrets backend | ||
| 131 | TokenSecret string `mapstructure:"token_secret"` // path in secrets backend | 131 | TokenSecret string `mapstructure:"token_secret"` // path in secrets backend | ||
| 132 | TokenExpiry string `mapstructure:"token_expiry"` // e.g., "720h", "30d" | 132 | TokenExpiry string `mapstructure:"token_expiry"` // e.g., "720h", "30d" | ||
| @@ -747,7 +747,7 @@ func randomTokenHex(size int) (string, error) { | |||||
| 747 | // InternalCredentials holds the internal registry credentials for CLI access. | 747 | // InternalCredentials holds the internal registry credentials for CLI access. | ||
| 748 | type InternalCredentials struct { | 748 | type InternalCredentials struct { | ||
| 749 | Username string `json:"username"` | 749 | Username string `json:"username"` | ||
| 750 | - | Password string `json:"password"` | 750 | + | Password string `json:"password"` //nolint:gosec // internal credential wire format: json key is intentional for CLI interop |
| 751 | } | 751 | } | ||
| 752 | 752 | ||||
| 753 | // getSecureRuntimeDir returns a secure directory for runtime files. | 753 | // getSecureRuntimeDir returns a secure directory for runtime files. | ||
| @@ -755,9 +755,12 @@ type InternalCredentials struct { | |||||
| 755 | func getSecureRuntimeDir() (string, error) { | 755 | func getSecureRuntimeDir() (string, error) { | ||
| 756 | // Try XDG_RUNTIME_DIR first (typically /run/user/<uid> on Linux) | 756 | // Try XDG_RUNTIME_DIR first (typically /run/user/<uid> on Linux) | ||
| 757 | if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" { | 757 | if runtimeDir := os.Getenv("XDG_RUNTIME_DIR"); runtimeDir != "" { | ||
| 758 | - | gordonDir := filepath.Join(runtimeDir, "gordon") | 758 | + | runtimeDir = filepath.Clean(runtimeDir) |
| 759 | - | if err := os.MkdirAll(gordonDir, 0700); err == nil { | 759 | + | if filepath.IsAbs(runtimeDir) { |
| 760 | - | return gordonDir, nil | 760 | + | gordonDir := filepath.Join(runtimeDir, "gordon") |
| 761 | + | if err := os.MkdirAll(gordonDir, 0700); err == nil { //nolint:gosec // G703: path cleaned and verified absolute before use | |||
| 762 | + | return gordonDir, nil | |||
| 763 | + | } | |||
| 761 | } | 764 | } | ||
| 762 | } | 765 | } | ||
| 763 | 766 | ||||