Skip to content

Commit

Permalink
Add Identity Provider CA to kubeconfig
Browse files Browse the repository at this point in the history
This change enables usage of self signed cert for the IdP by providing
a config `idpCAPath` in the config map.

Signed-off-by: Vijay Katam <vkatam@vmware.com>

Closes: vmware-archive#148
  • Loading branch information
vijaykatam committed Feb 11, 2020
1 parent d6a1fe1 commit 5eede51
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 28 deletions.
71 changes: 44 additions & 27 deletions cmd/gangway/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,18 @@ const (

// userInfo stores information about an authenticated user
type userInfo struct {
ClusterName string
Username string
KubeCfgUser string
IDToken string
RefreshToken string
ClientID string
ClientSecret string
IssuerURL string
APIServerURL string
ClusterCA string
HTTPPath string
ClusterName string
Username string
KubeCfgUser string
IDToken string
RefreshToken string
ClientID string
ClientSecret string
IssuerURL string
APIServerURL string
ClusterCA string
IdentityProviderCA string
HTTPPath string
}

// homeInfo is used to store dynamic properties on
Expand Down Expand Up @@ -122,11 +123,12 @@ func generateKubeConfig(cfg *userInfo) clientcmdapi.Config {
AuthProvider: &clientcmdapi.AuthProviderConfig{
Name: "oidc",
Config: map[string]string{
"client-id": cfg.ClientID,
"client-secret": cfg.ClientSecret,
"id-token": cfg.IDToken,
"idp-issuer-url": cfg.IssuerURL,
"refresh-token": cfg.RefreshToken,
"client-id": cfg.ClientID,
"client-secret": cfg.ClientSecret,
"id-token": cfg.IDToken,
"idp-issuer-url": cfg.IssuerURL,
"refresh-token": cfg.RefreshToken,
"idp-certificate-authority-data": cfg.IdentityProviderCA,
},
},
},
Expand Down Expand Up @@ -300,6 +302,20 @@ func generateInfo(w http.ResponseWriter, r *http.Request) *userInfo {
log.Warningf("Could not read CA file: %s", err)
}

identityProviderCA := ""
if cfg.IdentityProviderCAPath != "" {
caFile, err := os.Open(cfg.IdentityProviderCAPath)
if err != nil {
log.Errorf("Failed to open CA file. %s", err.Error())
}
defer caFile.Close()
idpCA, err := ioutil.ReadAll(caFile)
if err != nil {
log.Errorf("Could not read CA file: %s", err.Error())
}
identityProviderCA = base64.StdEncoding.EncodeToString(idpCA)
}

// load the session cookies
sessionIDToken, err := gangwayUserSession.Session.Get(r, "gangway_id_token")
if err != nil {
Expand Down Expand Up @@ -362,17 +378,18 @@ func generateInfo(w http.ResponseWriter, r *http.Request) *userInfo {
}

info := &userInfo{
ClusterName: cfg.ClusterName,
Username: username,
KubeCfgUser: kubeCfgUser,
IDToken: idToken,
RefreshToken: refreshToken,
ClientID: cfg.ClientID,
ClientSecret: cfg.ClientSecret,
IssuerURL: issuerURL,
APIServerURL: cfg.APIServerURL,
ClusterCA: string(caBytes),
HTTPPath: cfg.HTTPPath,
ClusterName: cfg.ClusterName,
Username: username,
KubeCfgUser: kubeCfgUser,
IDToken: idToken,
RefreshToken: refreshToken,
ClientID: cfg.ClientID,
ClientSecret: cfg.ClientSecret,
IssuerURL: issuerURL,
APIServerURL: cfg.APIServerURL,
ClusterCA: string(caBytes),
HTTPPath: cfg.HTTPPath,
IdentityProviderCA: identityProviderCA,
}
return info
}
1 change: 1 addition & 0 deletions cmd/gangway/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ func TestKubeconfigHandler(t *testing.T) {
"id-token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHYW5nd2F5VGVzdCIsImlhdCI6MTU0MDA0NjM0NywiZXhwIjoxODg3MjAxNTQ3LCJhdWQiOiJnYW5nd2F5LmhlcHRpby5jb20iLCJzdWIiOiJnYW5nd2F5QGhlcHRpby5jb20iLCJHaXZlbk5hbWUiOiJHYW5nIiwiU3VybmFtZSI6IldheSIsIkVtYWlsIjoiZ2FuZ3dheUBoZXB0aW8uY29tIiwiR3JvdXBzIjoiZGV2LGFkbWluIn0.zNG4Dnxr76J0p4phfsAUYWunioct0krkMiunMynlQsU",
"refresh-token": "bar",
"idp-issuer-url": "GangwayTest",
"idp-certificate-authority-data": "",
},
},
}
Expand Down
4 changes: 4 additions & 0 deletions docs/yaml/02-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,7 @@ data:
# The path to find custom HTML templates
# Env var: GANGWAY_CUSTOM_HTTP_TEMPLATES_DIR
#customHTMLTemplatesDir: /custom-templates
# The path to find the CA bundle for the IdP, optional. Used to configure kubectl.
# Env var: GANGWAY_IDP_CA_PATH
# idpCAPath: "/cacerts/idpca.cert"
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Config struct {
APIServerURL string `yaml:"apiServerURL" envconfig:"apiserver_url"`
ClusterCAPath string `yaml:"clusterCAPath" envconfig:"cluster_ca_path"`
TrustedCAPath string `yaml:"trustedCAPath" envconfig:"trusted_ca_path"`
IdentityProviderCAPath string `yaml:"idpCAPath" envconfig:"idp_ca_path"`
HTTPPath string `yaml:"httpPath" envconfig:"http_path"`

SessionSecurityKey string `yaml:"sessionSecurityKey" envconfig:"SESSION_SECURITY_KEY"`
Expand Down
4 changes: 4 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func TestEnvionmentOverrides(t *testing.T) {
os.Setenv("GANGWAY_TOKEN_URL", "https://foo.bar/token")
os.Setenv("GANGWAY_AUDIENCE", "foo")
os.Setenv("GANGWAY_SCOPES", "groups,sub")
os.Setenv("GANGWAY_IDP_CA_PATH", "/cacerts/idp-ca.cert")
cfg, err := NewConfig("")
if err != nil {
t.Errorf("Failed to test config overrides with error: %s", err)
Expand All @@ -54,6 +55,9 @@ func TestEnvionmentOverrides(t *testing.T) {
if cfg.Scopes[0] != "groups" || cfg.Scopes[1] != "sub" {
t.Errorf("Failed to set scopes via environment variable. Expected %s but got %s", "[groups, sub]", cfg.Scopes)
}
if cfg.IdentityProviderCAPath != "/cacerts/idp-ca.cert" {
t.Errorf("Failed to set idp ca via environment variable. Expected \"/cacerts/idp-ca.cert\" but got %s", cfg.IdentityProviderCAPath)
}
}

func TestGetRootPathPrefix(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion templates/commandline.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ kubectl config set-credentials {{ .KubeCfgUser }} \
--auth-provider-arg='client-id={{ .ClientID }}' \
--auth-provider-arg='client-secret={{ .ClientSecret }}' \
--auth-provider-arg='refresh-token={{ .RefreshToken }}' \
--auth-provider-arg='id-token={{ .IDToken }}'
--auth-provider-arg='id-token={{ .IDToken }}' \
--auth-provider-arg='idp-certificate-authority-data={{ .IdentityProviderCA }}' \
kubectl config set-context {{ .ClusterName }} --cluster={{ .ClusterName }} --user={{ .KubeCfgUser }}
kubectl config use-context {{ .ClusterName }}
rm ca-{{ .ClusterName }}.pem
Expand Down

0 comments on commit 5eede51

Please sign in to comment.