Skip to content

feat: add azure oidc PKI auth instead of client secret #9054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update golden files
  • Loading branch information
Emyrk committed Aug 14, 2023
commit cb98e183e85bf54336a0c648f1aaf99641c3657e
10 changes: 10 additions & 0 deletions cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,19 @@ can safely ignore these settings.
--oidc-auth-url-params struct[map[string]string], $CODER_OIDC_AUTH_URL_PARAMS (default: {"access_type": "offline"})
OIDC auth URL parameters to pass to the upstream provider.

--oidc-client-cert-file string, $CODER_OIDC_CLIENT_CERT_FILE
Pem encoded certificate file to use for oauth2 PKI/JWT authorization.
The public certificate that accompanies oidc-client-key-file. A
standard x509 certificate is expected.

--oidc-client-id string, $CODER_OIDC_CLIENT_ID
Client ID to use for Login with OIDC.

--oidc-client-key-file string, $CODER_OIDC_CLIENT_KEY_FILE
Pem encoded RSA private key to use for oauth2 PKI/JWT authorization.
This can be used instead of oidc-client-secret if your IDP supports
it.

--oidc-client-secret string, $CODER_OIDC_CLIENT_SECRET
Client secret to use for Login with OIDC.

Expand Down
7 changes: 7 additions & 0 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions coderd/oauthpki/oidcpki.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package oauthpki
import (
"context"
"crypto/rsa"
"crypto/sha1"
"crypto/sha1" //#nosec // Not used for cryptography.
"crypto/x509"
"encoding/base64"
"encoding/json"
Expand Down Expand Up @@ -92,6 +92,8 @@ func NewOauth2PKIConfig(params ConfigParams) (*Config, error) {
}

block, _ := pem.Decode(params.PemEncodedCert)
// Used as an identifier, not an actual cryptographic hash.
//nolint:gosec
hashed := sha1.Sum(block.Bytes)

return &Config{
Expand Down Expand Up @@ -196,7 +198,13 @@ func (src *jwtTokenSource) Token() (*oauth2.Token, error) {
"refresh_token": {src.refreshToken},
}
// Using params based auth
resp, err := cli.PostForm(src.cfg.tokenURL, v)
req, err := http.NewRequest("POST", src.cfg.tokenURL, strings.NewReader(v.Encode()))
if err != nil {
return nil, xerrors.Errorf("oauth2: make token refresh request: %w", err)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req = req.WithContext(src.ctx)
resp, err := cli.Do(req)
if err != nil {
return nil, xerrors.Errorf("oauth2: cannot get token: %w", err)
}
Expand Down Expand Up @@ -235,7 +243,7 @@ func (src *jwtTokenSource) Token() (*oauth2.Token, error) {
}

if unmarshalError != nil {
return nil, fmt.Errorf("oauth2: cannot unmarshal token: %v", err)
return nil, fmt.Errorf("oauth2: cannot unmarshal token: %w", err)
}

newToken := &oauth2.Token{
Expand All @@ -256,7 +264,7 @@ func (src *jwtTokenSource) Token() (*oauth2.Token, error) {
// decode returned id token to get expiry
claimSet, err := jws.Decode(v)
if err != nil {
return nil, fmt.Errorf("oauth2: error decoding JWT token: %v", err)
return nil, fmt.Errorf("oauth2: error decoding JWT token: %w", err)
}
newToken.Expiry = time.Unix(claimSet.Exp, 0)
}
Expand Down
12 changes: 9 additions & 3 deletions coderd/oauthpki/okidcpki_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ B1B7CpkMU55hPP+7nsofCszNrMDXT8Z5w2a3zLKM
// It runs an oauth2.Exchange method and hijacks the request to only check the
// request side of the transaction.
func TestAzureADPKIOIDC(t *testing.T) {
t.Parallel()

oauthCfg := &oauth2.Config{
ClientID: "random-client-id",
Endpoint: oauth2.Endpoint{
Expand Down Expand Up @@ -128,6 +130,8 @@ func TestAzureADPKIOIDC(t *testing.T) {
// to prevent some regressions by running a full "e2e" oauth and asserting some
// of the request values.
func TestSavedAzureADPKIOIDC(t *testing.T) {
t.Parallel()

var (
stateString = "random-state"
oauth2Code = base64.StdEncoding.EncodeToString([]byte("random-code"))
Expand Down Expand Up @@ -237,15 +241,17 @@ func TestSavedAzureADPKIOIDC(t *testing.T) {
}

return nil, xerrors.Errorf("not implemented")
}},
},
},
}
fakeCtx = oidc.ClientContext(context.Background(), fakeClient)
var _ = fakeCtx
_ = fakeCtx

// This simulates a client logging into the browser. The 307 redirect will
// make sure this goes through the full flow.
_, err = fakeClient.Get(pki.AuthCodeURL("state", oauth2.AccessTypeOffline))
resp, err := fakeClient.Get(pki.AuthCodeURL("state", oauth2.AccessTypeOffline))
require.NoError(t, err)
_ = resp.Body.Close()

require.True(t, initialExchange, "initial token exchange complete")
require.True(t, tokenRefreshed, "token was refreshed")
Expand Down
2 changes: 2 additions & 0 deletions docs/api/general.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 30 additions & 22 deletions docs/api/schemas.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions docs/cli/server.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions enterprise/cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,19 @@ can safely ignore these settings.
--oidc-auth-url-params struct[map[string]string], $CODER_OIDC_AUTH_URL_PARAMS (default: {"access_type": "offline"})
OIDC auth URL parameters to pass to the upstream provider.

--oidc-client-cert-file string, $CODER_OIDC_CLIENT_CERT_FILE
Pem encoded certificate file to use for oauth2 PKI/JWT authorization.
The public certificate that accompanies oidc-client-key-file. A
standard x509 certificate is expected.

--oidc-client-id string, $CODER_OIDC_CLIENT_ID
Client ID to use for Login with OIDC.

--oidc-client-key-file string, $CODER_OIDC_CLIENT_KEY_FILE
Pem encoded RSA private key to use for oauth2 PKI/JWT authorization.
This can be used instead of oidc-client-secret if your IDP supports
it.

--oidc-client-secret string, $CODER_OIDC_CLIENT_SECRET
Client secret to use for Login with OIDC.

Expand Down