Skip to content

Commit f656884

Browse files
feat(sso): allow custom ca configuration
1 parent a2924e6 commit f656884

File tree

7 files changed

+665
-4
lines changed

7 files changed

+665
-4
lines changed

config/sso.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ type SSOConfig struct {
3333
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
3434
// FilterGroupsRegex filters groups using regular expressions
3535
FilterGroupsRegex []string `json:"filterGroupsRegex,omitempty"`
36+
// custom PEM encoded CA certificate file contents
37+
RootCA string `json:"rootCA,omitempty"`
38+
// custom CA certificate file name
39+
RootCAFile string `json:"rootCAFile,omitempty"`
3640
}
3741

3842
func (c SSOConfig) GetSessionExpiry() time.Duration {

docs/argo-server-sso.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,50 @@ sso:
212212
- ".*argo-wf.*"
213213
- ".*argo-workflow.*"
214214
```
215+
216+
## Custom TLS Configuration
217+
218+
> v3.8 and after
219+
220+
You can configure custom TLS settings for OIDC provider connections. This is useful when your OIDC provider uses self-signed certificates or custom Certificate Authorities (CAs).
221+
222+
### Custom CA Certificate
223+
224+
You can specify a custom CA certificate in several ways:
225+
226+
**Default system CA path** - If you mount CA certificates to `/etc/ssl/certs`, they will be automatically picked up by the system without needing to configure `rootCA` or `rootCAFile`:
227+
228+
**Explicit configuration** - You can also explicitly specify custom CA certificates:
229+
230+
1. **Inline PEM content** - Provide the CA certificate content directly in the configuration:
231+
232+
```yaml
233+
sso:
234+
# Custom PEM encoded CA certificate file contents
235+
rootCA: |-
236+
-----BEGIN CERTIFICATE-----
237+
MIIDXTCCAkWgAwIBAgIJAKoK/heBjcOuMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
238+
...
239+
-----END CERTIFICATE-----
240+
```
241+
242+
2. **File path** - Reference a CA certificate file mounted in the container:
243+
244+
```yaml
245+
sso:
246+
# Custom CA certificate file name
247+
rootCAFile: /etc/ssl/certs/custom-ca.pem
248+
```
249+
250+
### Skip TLS Verification
251+
252+
For development or testing environments, you can disable TLS certificate verification:
253+
254+
```yaml
255+
sso:
256+
# Skip TLS certificate verification (not recommended for production)
257+
insecureSkipVerify: true
258+
```
259+
260+
!!! Warning
261+
Using `insecureSkipVerify: true` disables TLS certificate verification and should only be used in development environments. For production, always use proper CA certificates.

docs/workflow-controller-configmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ SSOConfig contains single sign-on configuration settings
298298
| `UserInfoPath` | `string` | UserInfoPath specifies the path to user info endpoint |
299299
| `InsecureSkipVerify` | `bool` | InsecureSkipVerify skips TLS certificate verification |
300300
| `FilterGroupsRegex` | `Array<string>` | FilterGroupsRegex filters groups using regular expressions |
301+
| `RootCA` | `string` | custom PEM encoded CA certificate file contents |
302+
| `RootCAFile` | `string` | custom CA certificate file name |
301303

302304
## RBACConfig
303305

docs/workflow-controller-configmap.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ data:
458458
enabled: false
459459
# Skip TLS verify, not recommended in production environments. Useful for testing purposes. >= v3.2.4
460460
insecureSkipVerify: false
461+
# Custom PEM encoded CA certificate file contents. >= v3.8
462+
# Note: If CA certificates are mounted to /etc/ssl/certs, this config is not needed.
463+
rootCA: ""
464+
# Custom CA certificate file name. >= v3.8
465+
# Note: If CA certificates are mounted to /etc/ssl/certs, this config is not needed.
466+
rootCAFile: ""
461467
462468
# workflowRestrictions restricts the Workflows that the controller will process.
463469
# Current options:

server/auth/sso/clients.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package sso
2+
3+
import (
4+
"crypto/tls"
5+
"crypto/x509"
6+
"fmt"
7+
"net/http"
8+
"os"
9+
)
10+
11+
type HTTPClientConfig struct {
12+
InsecureSkipVerify bool
13+
RootCA string
14+
RootCAFile string
15+
}
16+
17+
func (c HTTPClientConfig) String() string {
18+
rootCALen := len(c.RootCA)
19+
rootCAPreview := ""
20+
if rootCALen > 0 {
21+
if rootCALen > 50 {
22+
rootCAPreview = c.RootCA[:50] + "..."
23+
} else {
24+
rootCAPreview = c.RootCA
25+
}
26+
}
27+
28+
return fmt.Sprintf("HTTPClientConfig{InsecureSkipVerify: %t, RootCA: %q (%d bytes), RootCAFile: %q}",
29+
c.InsecureSkipVerify, rootCAPreview, rootCALen, c.RootCAFile)
30+
}
31+
32+
func createHTTPClient(config HTTPClientConfig) (*http.Client, error) {
33+
34+
// Start with a copy of the default client
35+
httpClient := *http.DefaultClient
36+
37+
// If no custom TLS configuration is needed, return the default client copy
38+
if !config.InsecureSkipVerify && config.RootCA == "" && config.RootCAFile == "" {
39+
return &httpClient, nil
40+
}
41+
42+
// Clone the default transport and cast to *http.Transport
43+
defaultTransport := http.DefaultTransport.(*http.Transport)
44+
transport := defaultTransport.Clone()
45+
46+
// Configure TLS settings
47+
tlsConfig := &tls.Config{
48+
InsecureSkipVerify: config.InsecureSkipVerify,
49+
}
50+
51+
// Set RootCAs if provided
52+
// Load root CA certificates from both string and file if defined
53+
if config.RootCA != "" || config.RootCAFile != "" {
54+
55+
rootCAs := x509.NewCertPool()
56+
57+
// Add certificates from PEM string if provided
58+
if config.RootCA != "" {
59+
if ok := rootCAs.AppendCertsFromPEM([]byte(config.RootCA)); !ok {
60+
return nil, fmt.Errorf("failed to append certificates from PEM string")
61+
}
62+
}
63+
64+
// Add certificates from file if provided
65+
if config.RootCAFile != "" {
66+
rootCAFile, err := os.ReadFile(config.RootCAFile)
67+
if err != nil {
68+
return nil, fmt.Errorf("failed to read CA certificate file: %w", err)
69+
}
70+
71+
if ok := rootCAs.AppendCertsFromPEM(rootCAFile); !ok {
72+
return nil, fmt.Errorf("failed to append CA certificate from file")
73+
}
74+
}
75+
76+
tlsConfig.RootCAs = rootCAs
77+
}
78+
79+
// Apply the custom TLS config to the cloned transport
80+
transport.TLSClientConfig = tlsConfig
81+
82+
// Use the modified transport in our client copy
83+
httpClient.Transport = transport
84+
85+
return &httpClient, nil
86+
}

0 commit comments

Comments
 (0)