Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9578ce9

Browse files
authored
OAuth now uses client TLS certs (if configured) (#5042)
* OAuth now uses client TLS certs (if configured) * Update docs * Cleaning * Fix lint errors and generate static files * Fix lint error and regenerate more static files * Suppress lint error
1 parent 49c7648 commit 9578ce9

File tree

9 files changed

+61
-10
lines changed

9 files changed

+61
-10
lines changed

cli/deployment/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,16 @@ func newConfig() *codersdk.DeploymentConfig {
282282
Flag: "tls-min-version",
283283
Default: "tls12",
284284
},
285+
ClientCertFile: &codersdk.DeploymentConfigField[string]{
286+
Name: "TLS Client Cert File",
287+
Usage: "Path to certificate for client TLS authentication. It requires a PEM-encoded file.",
288+
Flag: "tls-client-cert-file",
289+
},
290+
ClientKeyFile: &codersdk.DeploymentConfigField[string]{
291+
Name: "TLS Client Key File",
292+
Usage: "Path to key for client TLS authentication. It requires a PEM-encoded file.",
293+
Flag: "tls-client-key-file",
294+
},
285295
},
286296
Trace: &codersdk.TraceConfig{
287297
Enable: &codersdk.DeploymentConfigField[bool]{

cli/server.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,11 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
392392
return xerrors.Errorf("OIDC issuer URL must be set!")
393393
}
394394

395+
ctx, err := handleOauth2ClientCertificates(ctx, cfg)
396+
if err != nil {
397+
return xerrors.Errorf("configure oidc client certificates: %w", err)
398+
}
399+
395400
oidcProvider, err := oidc.NewProvider(ctx, cfg.OIDC.IssuerURL.Value)
396401
if err != nil {
397402
return xerrors.Errorf("configure oidc provider: %w", err)
@@ -1249,3 +1254,21 @@ func startBuiltinPostgres(ctx context.Context, cfg config.Root, logger slog.Logg
12491254
}
12501255
return connectionURL, ep.Stop, nil
12511256
}
1257+
1258+
func handleOauth2ClientCertificates(ctx context.Context, cfg *codersdk.DeploymentConfig) (context.Context, error) {
1259+
if cfg.TLS.ClientCertFile.Value != "" && cfg.TLS.ClientKeyFile.Value != "" {
1260+
certificates, err := loadCertificates([]string{cfg.TLS.ClientCertFile.Value}, []string{cfg.TLS.ClientKeyFile.Value})
1261+
if err != nil {
1262+
return nil, err
1263+
}
1264+
1265+
return context.WithValue(ctx, oauth2.HTTPClient, &http.Client{
1266+
Transport: &http.Transport{
1267+
TLSClientConfig: &tls.Config{ //nolint:gosec
1268+
Certificates: certificates,
1269+
},
1270+
},
1271+
}), nil
1272+
}
1273+
return ctx, nil
1274+
}

cli/testdata/coder_server_--help.golden

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ Flags:
177177
used for checking the authenticity of
178178
client
179179
Consumes $CODER_TLS_CLIENT_CA_FILE
180+
--tls-client-cert-file string Path to certificate for client TLS
181+
authentication. It requires a PEM-encoded
182+
file.
183+
Consumes $CODER_TLS_CLIENT_CERT_FILE
184+
--tls-client-key-file string Path to key for client TLS
185+
authentication. It requires a PEM-encoded
186+
file.
187+
Consumes $CODER_TLS_CLIENT_KEY_FILE
180188
--tls-enable Whether TLS will be enabled.
181189
Consumes $CODER_TLS_ENABLE
182190
--tls-key-file strings Paths to the private keys for each of the

codersdk/deploymentconfig.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ type TelemetryConfig struct {
101101
}
102102

103103
type TLSConfig struct {
104-
Enable *DeploymentConfigField[bool] `json:"enable" typescript:",notnull"`
105-
CertFiles *DeploymentConfigField[[]string] `json:"cert_file" typescript:",notnull"`
106-
ClientAuth *DeploymentConfigField[string] `json:"client_auth" typescript:",notnull"`
107-
ClientCAFile *DeploymentConfigField[string] `json:"client_ca_file" typescript:",notnull"`
108-
KeyFiles *DeploymentConfigField[[]string] `json:"key_file" typescript:",notnull"`
109-
MinVersion *DeploymentConfigField[string] `json:"min_version" typescript:",notnull"`
104+
Enable *DeploymentConfigField[bool] `json:"enable" typescript:",notnull"`
105+
CertFiles *DeploymentConfigField[[]string] `json:"cert_file" typescript:",notnull"`
106+
ClientAuth *DeploymentConfigField[string] `json:"client_auth" typescript:",notnull"`
107+
ClientCAFile *DeploymentConfigField[string] `json:"client_ca_file" typescript:",notnull"`
108+
KeyFiles *DeploymentConfigField[[]string] `json:"key_file" typescript:",notnull"`
109+
MinVersion *DeploymentConfigField[string] `json:"min_version" typescript:",notnull"`
110+
ClientCertFile *DeploymentConfigField[string] `json:"client_cert_file" typescript:",notnull"`
111+
ClientKeyFile *DeploymentConfigField[string] `json:"client_key_file" typescript:",notnull"`
110112
}
111113

112114
type TraceConfig struct {

docs/admin/auth.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ Once complete, run `sudo service coder restart` to reboot Coder.
7575

7676
> When a new user is created, the `preferred_username` claim becomes the username. If this claim is empty, the email address will be stripped of the domain, and become the username (e.g. `[email protected]` becomes `example`).
7777
78+
If your OpenID Connect provider requires client TLS certificates for authentication, you can configure them like so:
79+
```console
80+
CODER_TLS_CLIENT_CERT_FILE=/path/to/cert.pem
81+
CODER_TLS_CLIENT_KEY_FILE=/path/to/key.pem
82+
```
83+
7884
## SCIM (enterprise)
7985

8086
Coder supports user provisioning and deprovisioning via SCIM 2.0 with header

scripts/apitypings/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type TypescriptTypes struct {
6363
// String just combines all the codeblocks.
6464
func (t TypescriptTypes) String() string {
6565
var s strings.Builder
66-
_, _ = s.WriteString("// Code generated by 'make coder/scripts/apitypings/main.go'. DO NOT EDIT.\n\n")
66+
_, _ = s.WriteString("// Code generated by 'make site/src/api/typesGenerated.ts'. DO NOT EDIT.\n\n")
6767

6868
sortedTypes := make([]string, 0, len(t.Types))
6969
sortedEnums := make([]string, 0, len(t.Enums))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Code generated by 'make coder/scripts/apitypings/main.go'. DO NOT EDIT.
1+
// Code generated by 'make site/src/api/typesGenerated.ts'. DO NOT EDIT.
22

33
// From codersdk/enums.go
44
export type Enum = "bar" | "baz" | "foo" | "qux"

scripts/apitypings/testdata/generics/generics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Code generated by 'make coder/scripts/apitypings/main.go'. DO NOT EDIT.
1+
// Code generated by 'make site/src/api/typesGenerated.ts'. DO NOT EDIT.
22

33
// From codersdk/generics.go
44
export interface ComplexGeneric<C extends comparable, S extends Single, T extends Custom> {

site/src/api/typesGenerated.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Code generated by 'make coder/scripts/apitypings/main.go'. DO NOT EDIT.
1+
// Code generated by 'make site/src/api/typesGenerated.ts'. DO NOT EDIT.
22

33
// From codersdk/apikey.go
44
export interface APIKey {
@@ -598,6 +598,8 @@ export interface TLSConfig {
598598
readonly client_ca_file: DeploymentConfigField<string>
599599
readonly key_file: DeploymentConfigField<string[]>
600600
readonly min_version: DeploymentConfigField<string>
601+
readonly client_cert_file: DeploymentConfigField<string>
602+
readonly client_key_file: DeploymentConfigField<string>
601603
}
602604

603605
// From codersdk/deploymentconfig.go

0 commit comments

Comments
 (0)