# dex-operator We want to develop a dex operator. There are a few dex operator implementations on the web already. But mostly, either they deploy dex, and no CR to config, or they require dex to be deployed already, via Helm chart, and then have CR to configure dex. # Usage You'll need operator-sdk. ``` git clone https://github.com/identitatem/dex-operator.git oc new-project dex-operator # this will deploy the operator as a bundle make sdk-run cd hack/gitops-community ./start.sh # add dex roles/bindings to the service account oc apply -f rbac-dex-operator-dexsso-community.yaml # edit the DexConfig to reference your domain, eventually this will be in the operator, then apply oc apply -f config/sample/dexconfig-community.yaml ``` # Cert Rotation Here, the cert expired after 1 hour. Fail to verify at that point. ```bash= 53 Fri Aug 13 04:36:43 UTC 2021 Thu Aug 12 23:36:43 CDT 2021 server.crt: OK client.crt: OK 54 Fri Aug 13 04:37:43 UTC 2021 Thu Aug 12 23:37:43 CDT 2021 server.crt: OK client.crt: OK 55 Fri Aug 13 04:38:43 UTC 2021 Thu Aug 12 23:38:43 CDT 2021 server.crt: OK client.crt: OK 56 Fri Aug 13 04:39:43 UTC 2021 Thu Aug 12 23:39:43 CDT 2021 server.crt: OK client.crt: OK 57 Fri Aug 13 04:40:43 UTC 2021 Thu Aug 12 23:40:43 CDT 2021 C = US, ST = , L = San Francisco, street = Golden Gate Bridge, postalCode = 94016, O = "Company, INC." error 10 at 1 depth lookup: certificate has expired C = US, O = "Hat, Inc.", CN = dex error 10 at 0 depth lookup: certificate has expired error server.crt: verification failed C = US, ST = , L = San Francisco, street = Golden Gate Bridge, postalCode = 94016, O = "Company, INC." error 10 at 1 depth lookup: certificate has expired C = US, O = "Hat, Inc.", CN = dex error 10 at 0 depth lookup: certificate has expired error client.crt: verification failed 58 Fri Aug 13 04:41:43 UTC 2021 Thu Aug 12 23:41:43 CDT 2021 C = US, ST = , L = San Francisco, street = Golden Gate Bridge, postalCode = 94016, O = "Company, INC." error 10 at 1 depth lookup: certificate has expired C = US, O = "Hat, Inc.", CN = dex error 10 at 0 depth lookup: certificate has expired error server.crt: verification failed C = US, ST = , L = San Francisco, street = Golden Gate Bridge, postalCode = 94016, O = "Company, INC." error 10 at 1 depth lookup: certificate has expired C = US, O = "Hat, Inc.", CN = dex error 10 at 0 depth lookup: certificate has expired error client.crt: verification failed 59 ``` # Secrets and Configmaps These are the required resources to start up the dex-operator and the dex server. | resource | type | description | |----------|------|-------------| | ${m.Name}-tls-secret | secret | tls cert/key generated for service, this will be mounted by dex web at /etc/dex/tls | | ${m.Name}-config | configmap | generated configmap, that is loaded into dex pod to provide the dex configuration and connector list | | dex.grpc.tls | secret | tls for grpc service in dex, keyed for `dex:5557`, loaded as a volume mount in dex pod | | github-client-community | secret | referenced by the connector, stored as secret, and mounted into dex server | - [ ] are connectors part of the gRPC api ? I know we can add staticClients, but what about connectors. --- ## Verified inside the container that Dex is serving the openid ```bash= /tmp $ wget -cS localhost:5556/api/dex/.well-known/openid-configuration -O - Connecting to localhost:5556 (127.0.0.1:5556) HTTP/1.1 200 OK Content-Length: 984 Content-Type: application/json Date: Tue, 27 Jul 2021 23:22:26 GMT Connection: close { "issuer": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex", "authorization_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/auth", "token_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/token", "jwks_uri": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/keys", "userinfo_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/userinfo", "response_types_supported": [ "code" ], "subject_types_supported": [ "public" ], "id_token_signing_alg_values_supported": [ "RS256" ], "scopes_supported": [ "openid", "email", "groups", "profile", "offline_access" ], "token_endpoint_auth_methods_supported": [ "client_secret_basic" ], "claims_supported": [ "aud", "email", "email_verified", "exp", "iat", "iss", "locale", "name", "sub" ] - 100% |******************************************************************************| 984 0:00:00 ETA ``` ## Verifed from outside as well ```bash= ✗ curl -k https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/.well-known/openid-configuration { "issuer": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex", "authorization_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/auth", "token_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/token", "jwks_uri": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/keys", "userinfo_endpoint": "https://dex-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex/userinfo", "response_types_supported": [ "code" ], "subject_types_supported": [ "public" ], "id_token_signing_alg_values_supported": [ "RS256" ], "scopes_supported": [ "openid", "email", "groups", "profile", "offline_access" ], "token_endpoint_auth_methods_supported": [ "client_secret_basic" ], "claims_supported": [ "aud", "email", "email_verified", "exp", "iat", "iss", "locale", "name", "sub" ] } ``` * When deploying the gitops dex pod, the openid is accessible from http. The service is NodePort, and the Route is `edge`. * For gitops dex, it doesn't matter what service type is, NodePort or ClusterIP, the route is able to reach. ---- ```bash= # Reset Environment make cleanup oc delete ns dex-operator oc new-project dex-operator # create tls, secret, dex configuration configmap cd hack/community ./start.sh # to deploy prebuilt bundle, against dell-r730-008 cluster export IMAGE_TAG_BASE=quay.io/cdoan/dex-operator make sdk-run sample ``` ---- ## Project Steps Project created using `operator-sdk` version `1.9.0` * skaffold a new operator sdk project ```bash= operator-sdk init --domain identitatem.io --repo github.com/cdoan1/dex-operator operator-sdk create api --version v1alpha1 --kind DexConfig --resource --controller ``` * added CR `DexConfig` to manage the lifecycle of dex pod/instance * updated the `reconsile` run loop to detect for `DexConfig` instance, and create the dex pod deployment * added rbac (via operator bundle for now, sa, clusterrole, clusterrolebinding) * applying the secret and config manually for now ## Progress ```bash= (base) ➜ dex-operator git:(master) ✗ stern -n dex-operator dex-server + dex-server-648f5c6d45-d95fl › dex dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="Starting configmap/secret informers" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="Configmap/secret informer synced" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="0xc000344b40 subscribed to settings updates" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config issuer: https://openshift-gitops-server-openshift-gitops.apps.dell-r730-008.demo.red-chesterfield.com/api/dex" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config storage: memory" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config static client: Argo CD" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config static client: Argo CD CLI" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config connector: openshift" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="config skipping approval screen" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="keys expired, rotating" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="keys rotated, next rotation: 2021-07-23 20:34:16.957655429 +0000 UTC" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="listening (http/telemetry) on 0.0.0.0:5558" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="listening (http) on 0.0.0.0:5556" dex-server-648f5c6d45-d95fl dex time="2021-07-23T14:34:16Z" level=info msg="listening (grpc) on 0.0.0.0:5557" ``` Running pods ```bash= NAME READY STATUS RESTARTS AGE a4aa8abe9497f328e7ed380e5c67d3eaeec922d3103a7b204c6e63ec65hr7n8 0/1 Completed 0 17m dex-operator-controller-manager-5557b68d44-gzqhw 2/2 Running 0 17m dex-server-648f5c6d45-d95fl 1/1 Running 0 15s quay-io-cdoan-dex-operator-bundle-v0-0-6 1/1 Running 0 17m ``` ### Quick Look You can deploy my bundle in your environment by running this command if you have operator-sdk installed, and you have access to an OLM capable kubernetes cluster: ```bash= operator-sdk run bundle quay.io/cdoan/dex-operator-bundle:v0.0.6 ``` ## References