GitOps is a pattern that has gained a fair share of popularity in recent times as it emphasizes declaratively expressing infrastructure and application configuration within Git repositories. When using Kubernetes, the concepts that GitOps employs aligns well as each of the resources (Deployments, Services, ConfigMaps) that comprise not only an application, but the platform itself can be stored in Git. While the management of these resources can be handled manually, a number of tools have emerged to not only aid in the GitOps space, but specifically with the integration with Kubernetes. 

ArgoCD is one such tool that emphasizes Continuous Delivery (CD) practices to repeatedly deliver changes to Kubernetes environments.

Note: ArgoCD has recently joined forces with Flux, a Cloud Native Computing Foundation (CNCF) sandbox project, to create gitops-engine as the solution that will combine the benefits of each standalone project.

ArgoCD accomplishes CD methodologies by using Git repositories as a source of truth for Kubernetes manifests that can be specified in a number of ways including plan yaml files, kustomize applications, as well as Helm Charts, and applies them to targeted clusters. When working with multiple teams and, in particular, enterprise organizations, it is imperative that each individual using the tool is authorized to do so in line with the principle of least privilege. ArgoCD features a fully functional Role Based Access Control (RBAC) system that can be used to implement this requirement. While ArgoCD itself does not include a user management system outside of a default admin user that has unrestricted access, it provides the ability to integrate with an external user management system through Single Sign On (SSO) capabilities. Open ID Connect (OIDC) is the authorization framework utilized by ArgoCD with two (2) supported approaches available:

  • Existing OIDC provider - An authorization provider that natively supports the OIDC
  • Bundled Dex Server - If an authorization provider does not support OIDC, a bundled OIDC and SSO with pluggable connectors to interact with external user management system

When using OpenShift as the Kubernetes distribution, one of the features that the platform natively supports the integration with an array of identity providers. In many cases, OpenShift leverages enterprise identity providers such as Active Directory/LDAP, GitHub or GitLab (including others) to provide access to users and define groups. Included with the deployment of ArgoCD is a Dex, a bundled OpenID Connect (OIDC) and OAuth Server with support for pluggable connectors to connect to user management systems. While Dex could be configured to integrate with these backend systems (such as LDAP) directly, it would add yet another integration point that would need to be managed and potentially cause additional burden. Instead, Dex can be configured to make use of OpenShift’s authentication capabilities. 

This approach aligns well as it reduces the number of integration points that need to be managed by centralizing how users are authenticated, reducing the burden on OpenShift cluster administrators, along with providing a streamlined and consistent experience for end users. This article will describe how to integrate with OpenShift authentication and how to implement granular role based access control in ArgoCD. 

Deploying ArgoCD on OpenShift

While the initial deployment of ArgoCD is outside the scope of this article, the ArgoCD website includes a Getting Started Guide which outlines the steps necessary along with manifests that can be used to deploy ArgoCD. Ensure that you not only have an OpenShift environment available, but are also a user with the admin role within a single namespace.

Note: The minimal level of permissions required to implement this integration is the admin role on a namespace in order to create and configure an OpenShift service account.

Once ArgoCD is deployed, the next step is to validate that you can reach the user interface. The manifests that were applied as described in the Getting Started Guide assume a deployment to a standard Kubernetes environment. OpenShift includes an ingress out-of-the-box solution using Routes to integrate with services running within the platform by external consumers. Create a route that enables access to ArgoCD using the OpenShift Command Line Interface. 

Note: The minimal level of permissions required to implement this integration is the admin role on a namespace in order to create and configure an OpenShift service account.

Once ArgoCD is deployed, the next step is to validate that you can reach the user interface. The manifests that were applied as described in the Getting Started Guide assume a deployment to a standard Kubernetes environment. OpenShift includes an ingress out-of-the-box solution using Routes to integrate with services running within the platform by external consumers. Create a route that enables access to ArgoCD using the OpenShift Command Line Interface. 

oc create route passthrough argocd --service=argocd-server --port=https --insecure-policy=Redirect

Confirm the web console is accessible by navigating to the location provided by executing the following command:

echo https://$(oc get routes argocd -o=jsonpath='{ .spec.host }')

Now that access to the console has been verified, let’s describe the architecture of ArgoCD as it pertains to user management. The primary component of the ArgoCD solution is the ArgoCD server (argocd-server). It exposes an API server that can be used by the ArgoCD command line tool (CLI) as well as the web server for which we verified previously. The native OIDC integration from ArgoCD to a supported authentication backend is included within this API server layer. When leveraging an alternate authentication backend that does not natively support OIDC, a standalone instance of the Dex is deployed. It is the logic within Dex which governs the integration with OpenShift. The ability to leverage OpenShift within Dex was a recently added connector and, as a result, the version of Dex that is utilized during the default ArgoCD deployment does not yet contain the needed connector. 

Execute the following command to replace the image that is being used by Dex with the image that includes the OpenShift connector:

oc patch deployment argocd-dex-server  -p '{"spec": {"template": 
{"spec": {"containers": [{"name": "dex","image": "quay.io/redhat-cop/dex:v2.22.0-openshift"

"}]}}}}'

Confirm the updated Dex pod is running by executing the following command:

oc get pods -l=app.kubernetes.io/name=argocd-dex-server

Integrating ArgoCD with OpenShift Authentication

With the Dex container using the proper image, the next step is to enable the integration of ArgoCD and OpenShift authentication. OpenShift contains an integrated OAuth server for users to authenticate against the API. External applications (in this case Dex) can be given access to obtain information on behalf of a user from the OAuth server by registering a new OAuth client. OpenShift provides two mechanisms for registering an OAuth client:
Using a Service Account as a constrained form of OAuth Client
 

The recommended approach, in this circumstance, is to leverage a Service Account as an OAuth Client rather than create an additional OAuth Client with the OAuth server. The primary reasoning behind this decision is that registering an additional OAuth Client with the OAuth server requires elevated access to OpenShift whereas using a service account as an OAuth client only required privileges that are already available within a namespace. However, one must note that while a Service Account can be used to represent an OAuth client for the integration with ArgoCD, there are many situations for which it cannot. One of the primary drawbacks is that only a subset of OAuth scopes supported within OpenShift can be requested by these types of clients as well as role based access can only be granted within the same namespace as the Service Account. 

Only a few steps need to be completed prior to leveraging a Service Account as an OAuth client. First, a Service Account must be identified for this integration. The deployment of ArgoCD created a service account called argocd-dex-server that is used to run the Dex container. This is an ideal Service Account to use for this purpose. 

Next, as with any type of integration with an OAuth server, the application authenticates using a Client ID and Client Secret. The client ID in this case is the full name of the service account in the format system:serviceaccount:<namespace>:<service_account_name>. So in this situation, if ArgoCD was deployed in a namespace called argocd, the Client ID would be system:serviceaccount:argocd:argocd-dex-server. 

The Client Secret is any one of the OpenShift OAuth API tokens that are automatically configured upon Service Account creation. This token can be obtained by executing the following command:

oc serviceaccounts get-token argocd-dex-server

The final step is to configure the Redirect URI that represents the location within ArgoCD that users should redirected to after successfully authenticating as part of the OAuth flow, within an annotation on the Service Account. This annotation makes use of the format serviceaccounts.openshift.io/oauth-redirecturi.<name> annotation. So, in this case, the annotation can be specified as serviceaccounts.openshift.io/oauth-redirecturi.argocd. The value of this annotation that represents the Redirect URI takes the following form (using the hostname for ArgoCD retrieved previously):

https://<argocd_host>/api/dex/callback

Patch the Service Account to add the Redirect URI annotation by replacing the content currently held by <argocd_redirect_uri> by executing the following command:

oc patch serviceaccount argocd-dex-server --type='json' -p='[{"op": "add", "path": "/metadata/annotations/serviceaccounts.openshift.io~1oauth-redirecturi.argocd", "value":"&lt;argocd_redirect_uri&gt;"}]'

Confirm the annotation was applied to the Service Account appropriately by executing the following command:

oc patch serviceaccount argocd-dex-server --type='json' -p='[{"op": "add", "path": "/metadata/annotations/serviceaccounts.openshift.io~1oauth-redirecturi.argocd", "value":"<argocd_redirect_uri>"}]'

Now that ArgoCD has been granted access to obtain user information from OpenShift, the next step is to configure SSO within ArgoCD. As ArgoCD emphasizes the use of GitOps methodologies through declarative configuration, the majority of the configuration for ArgoCD itself is managed through a range of native Kubernetes resources stored in the cluster. Specifically, the argocd-cm ConfigMap contains the primary configuration for ArgoCD and within this resource is the location for which the integration with the Dex OIDC connector is defined (A full list of resources that aid in the configuration of ArgoCD along with the available options can be found here).

With an understanding of where the specific configuration to enable SSO integration with OpenShift can be managed, let’s investigate the key options exposed by the OpenShift Dex connector as illustrated in the table below: 


oc edit cm argocd-cmDefine the SSO configuration for OpenShift by editing the argocd-cm ConfigMap using the following command:

At initial deployment time, the content of the ConfigMap is empty and contains no data property. The resulting ConfigMap is the code complete configuration that will be ultimately applied:

data:
  url: https://<argocd_host>
 dex.config: |
   connectors:
     # OpenShift
     - type: openshift
       id: openshift
       name: OpenShift
       config:
         issuer: <openshift_api_server>
         clientID: <client_id>
         clientSecret: <client_secret>
         redirectURI: <redirect_uri>
         insecureCA: true

Now, let’s walk through each property in detail;

The first property that is required when enabling SSO is the URL for the ArgoCD server itself in the url property. Once again, make use of the hostname discovered previously.

Next, we will define the properties for the Dex connector. The id, type, and name properties are all required regardless of the type of connector being used. The id property refers to a unique value within the Dex server. The type property must be specified as openshift as it identifies the connector that should be used. The name property refers to the friendly name that will appear in the ArgoCD user interface to identify the connector.  

Now, let’s define the properties associated with the OpenShift connector. First, the issuer property is the location of the OpenShift API server. This value can be obtained by running the following command:

oc whoami --show-server

Next, as discovered previously, provide the values of the clientID and clientSecret from the constrained Service Account. 

The redirectURI property should match the value that was placed within the annotation in the Service Account.

Finally, depending on the Certificate Authority that issued the SSL certificate for the OpenShift API server, there may be a need to perform additional configuration so that the Dex server can communicate securely. This could be accomplished by specifying the rootCA property that references the location within the Dex container with the necessary certificates. However, to demonstrate the functionality of the ArgoCD and OpenShift integration, we will forgo this configuration and instead specify the insecureCA property to be true to bypass SSL verification.

Save the ConfigMap to apply the changes.

ArgoCD monitors the state of the ConfigMap and automatically reloads the Dex server so no further action is required prior to testing the integration. 

With the SSO configuration in place, navigate to the ArgoCD URL. You will be presented with a login page as well as a “Login via OpenShift” button. Select this button which will direct you to the OpenShift Login page. Complete the OpenShift login process as well as allowing ArgoCD to make use of your user information when prompted. Afterwards, you will be presented with the ArgoCD overview screen.

Congratulations! You have successfully integrated OpenShift authentication with ArgoCD!

Utilize OpenShift Groups to Restrict Access

By default, any valid OpenShift user who successfully authenticates is granted access to ArgoCD. In many cases, there will be a desire or requirement to limit access to certain subset of users to enhance the security of the solution. For demonstration purposes, we will create two groups within OpenShift and associate users into each group. Ensure that you have two user accounts defined within OpenShift to implement this solution. If you are making use of the kubeadmin account that is provided by default when installing OpenShift, enable the htpasswd identity provider within OpenShift as described in the OpenShift Documentation and create two users, john and bill. Feel free to associate a password of your choosing to each user (such as redhat1!). Afterward, verify both of these users can login to ArgoCD by logging out of any existing sessions and attempting to authenticate with the credentials for each user.  

With two users created, let’s create two groups within OpenShift called argocdusers and argocdadmins. If your OpenShift environment is already making use of groups, feel free to skip the group creation and association step and make use of these previously created assets. 

Otherwise, create the two groups using the following commands:

oc adm groups new argocdusers
oc adm groups new argocdadmins

With the groups created, lets configure the OpenShift connector to require users attempting to authenticate be a member of each group. The groups property allows you to specify a list of groups that have access.

Once again edit the ConfigMap using the following command:

oc edit cm argocd-cm

Add the groups property with the names of the two groups to which will result in the ConfigMap appearing similar to the following:

data:
  url: <argocd_url>
 dex.config: |
   connectors:
     # OpenShift
     - type: openshift
       id: openshift
       name: OpenShift
       config:
         issuer: <openshift_api_server>
         clientID: <client_id>
         clientSecret: <client_secret>
         redirectURI: <redirect_uri>
         insecureCA: true
         groups:
           - argocdusers
           - argocdadmins

Saving the changes will automatically update the configuration. Logout of ArgoCD if previously authenticated and attempt to login again as either john or bill. You should be presented with an error stating that user attempting to login is not part of the required groups. 

Let’s go ahead and fix this.

Add john to the argocdusers group and add bill to the argocdadmins group using the following commands:

oc adm groups add-users argocdusers john
oc adm groups add-users argocdadmins bill

Attempt to login to ArgoCD once again and this time, authorization should succeed now that the users are placed within groups that have been granted access.

Role Based Access Control

While ArgoCD does not have a native user management system, it does feature a robust role based access control system. By default, any authenticated user can browse around the web console, but does not have access to any resources. So, if an attempt is made from either John or Bill’s account to modify any resource will result in an access error (Feel free to try this out yourself). In order for elevated access to be granted, we will look to leverage the groups that a user is a member of and apply policies to perform functions within ArgoCD. For users in the argocdusers group, we will allow users  to make use of the readonly role that is available in ArgoCD as part of a typical deployment (The default set of policies are defined in the builtin-policy.csv file). However, for users in the argocdadmins group, we will want to grant ArgoCD admin privileges. So in our case, Bill will be able to modify all resources within ArgoCD, but John will not (but will be able to view all of the resources, a privilege he did not have previously). 

Role based access control in ArgoCD is defined within a ConfigMap called argocd-rbac-cm. Similar to the argocd-cm ConfigMap resource that we configured previously, no data is defined by default. Two primary components can be managed through this resource:

  1. Default access policy
  2. Policies and group associations in CSV format

As indicated previously, the default access policy that is applied to any authenticated user is read only. This access level can be changed by defining the policy.default property. The policy that is to be applied can either be one of the built in roles or a new role which could be defined within the policy.csv property. While we will not define a new set of policies, we will use the policy.csv property to define an association between the group defined in OpenShift and an ArgoCD role. An ArgoCD role can be associated to a group using the following format:

g, <group_name>, <role>

So, to associate the argocdusers group to the builtin readonly role and the argocdadmins group to the built in admin role, the following would be the resulting group policies:

g, argocdusers, role:readonly
g, argocdadmins, role:admin

Edit the argocd-rbac-cm ConfigMap:

<span>oc edit cm argocd-rbac-cm

Apply the policy to the policy.csv property as shown below:

data:
 policy.csv: |
   g, argocdusers, role:readonly
   g, argocdadmins, role:admin

With the policy applied, login as Bill who is a member of the argocdadmins group and perform a modification to confirm the policy has taken effect. To verify, let’s attempt to create a new ArgoCD Project, which is a logical grouping of applications and ideal for when ArgoCD is used by multiple teams. 

Login as Bill, select the gear icon from the left hand navigation bar, and then click on Projects. At the top of the page, select New Project and enter openshift as the Project Name. Click Create to not only create the project, but to confirm the elevated level of permissions is being applied.

Feel free to logout of Bill’s account and login as John to confirm that he is now able to view all resources within ArgoCD including the openshift project Bill’s user created previously completing all of the desired tasks for integrating ArgoCD with OpenShift authentication. 

While the steps illustrated previously mainly utilized the web interface, users making use of the SSO integration with OpenShift can continue to use the ArgoCD Command Line Interface. When invoking the argocd login subcommand, omit the usage of the --username and --password flags and instead provide the --sso flag. Upon invocation, the default web browser will be launched to the OpenShift login page to complete the login process

As demonstrated in this article, the ability to leverage OpenShift’s authentication and group management capabilities not only provides new opportunities into the GitOps landscape using ArgoCD, but increases the likelihood of being adopted in enterprise environments as it leverages many of the previously agreed upon user management strategies that is part of any OpenShift deployment. 


About the author

Andrew Block is a Distinguished Architect at Red Hat, specializing in cloud technologies, enterprise integration and automation.

Read full bio