<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luiz Cesar Cherri</title>
    <description>The latest articles on DEV Community by Luiz Cesar Cherri (@cesar_cherri).</description>
    <link>https://dev.to/cesar_cherri</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3270717%2Ff744b3e5-8c43-4853-8589-0ff7814ff02b.jpg</url>
      <title>DEV Community: Luiz Cesar Cherri</title>
      <link>https://dev.to/cesar_cherri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cesar_cherri"/>
    <language>en</language>
    <item>
      <title>Managing access credentials is challenging for security and DevOps teams. In this article, I share how to use Service Accounts and RHACM/OCM to automate centralized multicluster access.</title>
      <dc:creator>Luiz Cesar Cherri</dc:creator>
      <pubDate>Tue, 01 Jul 2025 10:50:38 +0000</pubDate>
      <link>https://dev.to/cesar_cherri/managing-access-credentials-is-challenging-for-security-and-devops-teams-in-this-article-i-share-2c0o</link>
      <guid>https://dev.to/cesar_cherri/managing-access-credentials-is-challenging-for-security-and-devops-teams-in-this-article-i-share-2c0o</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5" class="crayons-story__hidden-navigation-link"&gt;Managing Service Accounts in Multicluster Environments with RHACM&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/cesar_cherri" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3270717%2Ff744b3e5-8c43-4853-8589-0ff7814ff02b.jpg" alt="cesar_cherri profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/cesar_cherri" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Luiz Cesar Cherri
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Luiz Cesar Cherri
                
              
              &lt;div id="story-author-preview-content-2599913" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/cesar_cherri" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3270717%2Ff744b3e5-8c43-4853-8589-0ff7814ff02b.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Luiz Cesar Cherri&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 30 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5" id="article-link-2599913"&gt;
          Managing Service Accounts in Multicluster Environments with RHACM
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/security"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;security&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/openshift"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;openshift&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>devops</category>
      <category>security</category>
      <category>kubernetes</category>
      <category>openshift</category>
    </item>
    <item>
      <title>Managing Service Accounts in Multicluster Environments with RHACM</title>
      <dc:creator>Luiz Cesar Cherri</dc:creator>
      <pubDate>Mon, 30 Jun 2025 17:59:50 +0000</pubDate>
      <link>https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5</link>
      <guid>https://dev.to/cesar_cherri/managing-service-accounts-in-multicluster-environments-with-rhacm-1c5</guid>
      <description>&lt;p&gt;Service Accounts are fundamental Kubernetes resources used to enable programmatic access to the cluster, typically for automation, workloads, or system integrations. They provide access tokens that authenticate against the Kubernetes API, offering a simpler alternative to traditional X.509 certificate-based authentication or OAuth mechanisms, such as those commonly used in OpenShift clusters.&lt;/p&gt;

&lt;h1&gt;
  
  
  Service Account - A Brief History
&lt;/h1&gt;

&lt;p&gt;Since the early days of Kubernetes, administrators could create ServiceAccount tokens without an expiration date. While this approach was convenient, it introduced security risks - if a token was leaked, it could be used indefinitely until an administrator revoked it manually.&lt;/p&gt;

&lt;p&gt;To address this, Kubernetes and OpenShift deprecated long-lived tokens. From now on, ServiceAccount tokens are time-bound, meaning they have an expiration date and must be renewed periodically.&lt;/p&gt;

&lt;p&gt;This change was introduced starting with Kubernetes v1.24, when the automatic creation of long-lived legacy tokens was disabled by default. Instead, Kubernetes adopted the &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume" rel="noopener noreferrer"&gt;Bound ServiceAccount Token Volume&lt;/a&gt; feature, which issues short-lived, auto-rotating tokens tied to the pod lifecycle. This approach improves security but also introduces operational challenges, especially in scenarios where tokens are required outside the pod context - such as CI/CD pipelines, external automation, or multicluster management.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Managed ServiceAccount?
&lt;/h2&gt;

&lt;p&gt;Managing ServiceAccount tokens at scale — especially across multiple clusters — introduces operational challenges. Each interaction with a Kubernetes API requires a fresh, valid token. With tokens now being short-lived and requiring frequent rotation, DevOps teams need a reliable way to automate their issuance, renewal, and distribution.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://github.com/open-cluster-management-io/managed-serviceaccount" rel="noopener noreferrer"&gt;Managed ServiceAccount&lt;/a&gt; is a custom resource definition (CRD) introduced by &lt;a href="https://open-cluster-management.io/" rel="noopener noreferrer"&gt;Open Cluster Management&lt;/a&gt;. It lets you define a ServiceAccount that is automatically created on all eligible managed clusters, based on criteria defined by your DevOps team.&lt;/p&gt;

&lt;p&gt;It ensures that the ServiceAccount is consistently created across clusters, and it automatically handles token issuance and rotation, making secure multicluster access much easier to manage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Managed ServiceAccounts focus on token lifecycle, but they do not manage RBAC permissions. Those remain the responsibility of cluster administrators, often addressed through GitOps practices or policies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Red Hat Advanced Cluster Management for Kubernetes (RHACM) is the downstream distribution of the upstream Open Cluster Management (OCM) project.&lt;/p&gt;

&lt;p&gt;Although this article uses Red Hat OpenShift and RHACM to demonstrate the examples, the features, APIs, and resource definitions are the same in both RHACM and OCM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Less Talk, More Action
&lt;/h2&gt;

&lt;p&gt;Once you have a functional RHACM or OCM environment — preferably composed of a &lt;strong&gt;Hub Cluster&lt;/strong&gt; and one or more &lt;strong&gt;Managed Clusters&lt;/strong&gt; — you can create a resource like the following on the Hub Cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;authentication.open-cluster-management.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ManagedServiceAccount&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;automation&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;cluster-name&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;validity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When a cluster is imported (i.e., becomes a Managed Cluster) into the Hub, the Hub creates a dedicated namespace for that cluster. This namespace is used to host configurations and resources managed by the Hub for that specific cluster.&lt;/p&gt;

&lt;p&gt;To create a ServiceAccount on a Managed Cluster, the resource definition must be placed within the corresponding namespace on the Hub. Therefore, make sure to replace &lt;code&gt;cluster-name&lt;/code&gt; with the name of your target Managed Cluster.&lt;/p&gt;

&lt;p&gt;The YAML above defines a ServiceAccount named &lt;code&gt;automation&lt;/code&gt; that will be created on the target Managed Cluster. The token associated with this ServiceAccount is configured to be &lt;strong&gt;automatically rotated every two hours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffz89yepsfwtyzrt6b53q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffz89yepsfwtyzrt6b53q.png" alt="Managed ServiceAccount Propagation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the diagram, this definition not only creates a ServiceAccount on the target clusters, but also creates a Secret in the cluster’s namespace on the Hub. This Secret contains the most up-to-date token for the corresponding ServiceAccount.&lt;/p&gt;

&lt;p&gt;In short, any tool or automation that needs access to the managed clusters can simply retrieve the token from the corresponding Secret in the Hub cluster.&lt;/p&gt;

&lt;p&gt;It’s important to note that the Hub maintains and automatically rotates this token according to the configuration defined in the ManagedServiceAccount resource. This ensures that the token is always valid and up to date, without requiring manual intervention.&lt;/p&gt;
&lt;h2&gt;
  
  
  What About ServiceAccount Permissions?
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, Managed ServiceAccounts handle the creation and automatic renewal of the ServiceAccount and its token. However, once the ServiceAccount is created on the managed cluster, &lt;strong&gt;it initially has no permissions&lt;/strong&gt; to perform any operations within that cluster.&lt;/p&gt;

&lt;p&gt;To grant the necessary permissions, you must configure a &lt;code&gt;RoleBinding&lt;/code&gt; or &lt;code&gt;ClusterRoleBinding&lt;/code&gt; on the managed cluster. This binding associates the ServiceAccount with the appropriate RBAC roles, ensuring that the tool or automation can operate as expected.&lt;/p&gt;

&lt;p&gt;The example below shows a &lt;code&gt;ClusterRoleBinding&lt;/code&gt; created for this purpose:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRoleBinding&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;automation&lt;/span&gt;
&lt;span class="na"&gt;roleRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;apiGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRole&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-admin&lt;/span&gt;
&lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;automation&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-cluster-management-agent-addon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Note: The ServiceAccount is always created in the &lt;code&gt;open-cluster-management-agent-addon&lt;/code&gt; namespace on the managed cluster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The example above grants the &lt;code&gt;automation&lt;/code&gt; ServiceAccount &lt;code&gt;cluster-admin&lt;/code&gt; privileges. If more restrictive permissions are needed, you can create a custom &lt;code&gt;Role&lt;/code&gt; or &lt;code&gt;ClusterRole&lt;/code&gt; to define exactly the level of access required.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scaling the Solution with Policies
&lt;/h2&gt;

&lt;p&gt;So far, we’ve described the basic configuration of Managed ServiceAccounts. However, we haven’t yet covered how to make this process &lt;strong&gt;scalable and repeatable&lt;/strong&gt; across multiple clusters.&lt;/p&gt;

&lt;p&gt;In other words, the key question is:&lt;br&gt;
&lt;strong&gt;“How can I automate this entire process so that whenever a new cluster is attached to the Hub, it immediately becomes accessible to my automation tools?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To achieve this, we can leverage the &lt;code&gt;Policy&lt;/code&gt; and &lt;code&gt;Placement&lt;/code&gt; resources provided by RHACM/OCM.&lt;/p&gt;

&lt;p&gt;These resources define &lt;strong&gt;“what”&lt;/strong&gt; should be applied (&lt;strong&gt;the desired configuration&lt;/strong&gt;) and &lt;strong&gt;“where”&lt;/strong&gt; it should be applied (&lt;strong&gt;the set of managed clusters selected by Placement criteria&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;The diagram below illustrates how this mechanism works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpedmws1r22oulmzb26e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpedmws1r22oulmzb26e.png" alt="RHACM Policy Propagation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This model allows you to automatically distribute or configure any resource — including Managed ServiceAccounts, RoleBindings, and others — based on the labels assigned to clusters. As soon as a managed cluster joins the Hub, the selected policies are applied automatically.&lt;/p&gt;

&lt;p&gt;You can learn more about Policies and Placements in the &lt;a href="https://docs.redhat.com/en/documentation/red_hat_advanced_cluster_management_for_kubernetes/2.13/html/governance/governance#governance" rel="noopener noreferrer"&gt;Red Hat Official Documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;To support the technical concepts covered in this article, I’ve created a Git repository with &lt;code&gt;Policy&lt;/code&gt; definitions that configure both the Managed ServiceAccount and the corresponding &lt;code&gt;ClusterRoleBindings&lt;/code&gt; across all clusters imported into a given Hub Cluster.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/lccherri" rel="noopener noreferrer"&gt;
        lccherri
      &lt;/a&gt; / &lt;a href="https://github.com/lccherri/rhacm-managed-serviceaccount" rel="noopener noreferrer"&gt;
        rhacm-managed-serviceaccount
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Managing Service Accounts with RHACM&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Managed Service Accounts in Red Hat Advanced Cluster Management (RHACM) allow you to securely distribute Service Accounts across managed clusters. The associated tokens are stored in dedicated secrets on the hub cluster, ensuring centralized and secure access.&lt;/p&gt;

&lt;p&gt;This setup enables automation workflows to retrieve Service Account tokens directly from the hub cluster, simplifying and securing access to managed clusters.&lt;/p&gt;

&lt;p&gt;This demonstration provides RHACM Policies that create all necessary resources to deliver this capability in a highly scalable environment.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Before you begin, ensure the following requirements are met:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;OpenShift Container Platform version 4.16 or later.&lt;/li&gt;
&lt;li&gt;Red Hat Advanced Cluster Management for Kubernetes (RHACM) version 2.13 or later.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installing RHACM&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;To install RHACM, execute the following command:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Run the ACM installation script&lt;/span&gt;
sh ./00-rhacm/acm-install.sh&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This script installs RHACM operator on your cluster.&lt;/p&gt;
&lt;p&gt;Access the OpenShift console and navigate to &lt;strong&gt;Installed Operators &amp;gt; Advanced Cluster Management&lt;/strong&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/lccherri/rhacm-managed-serviceaccount" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;With the approach implemented in this repository, &lt;strong&gt;whenever a new cluster is imported into the Hub, it immediately becomes accessible using a predefined ServiceAccount&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The example defines two Policies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/lccherri/rhacm-managed-serviceaccount/blob/main/00-rhacm/02-policies/configure-managedsa-automation.yaml" rel="noopener noreferrer"&gt;&lt;strong&gt;Managed ServiceAccount Policy&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates the Managed ServiceAccount resource in the Hub.&lt;/li&gt;
&lt;li&gt;This Policy targets every namespace that has the label &lt;code&gt;cluster.open-cluster-management.io/managedCluster&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/lccherri/rhacm-managed-serviceaccount/blob/main/00-rhacm/02-policies/configure-rolebinding-automation.yaml" rel="noopener noreferrer"&gt;&lt;strong&gt;ClusterRoleBinding Policy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Applies a &lt;code&gt;ClusterRoleBinding&lt;/code&gt; on the managed clusters.&lt;/li&gt;
&lt;li&gt;Grants the created ServiceAccount the necessary permissions to operate on those clusters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A Policy can also be used to define more restrictive &lt;code&gt;Roles&lt;/code&gt; or &lt;code&gt;ClusterRoles&lt;/code&gt;, depending on the level of access required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The Big Picture
&lt;/h1&gt;

&lt;p&gt;Now that you understand the concepts and how to implement them, let’s look at how this works in a &lt;strong&gt;real-world automation scenario&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The diagram below represents an &lt;strong&gt;Ansible automation workflow&lt;/strong&gt;, where the tokens required to authenticate against the managed clusters are requested from the Hub Cluster:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnv2uxpl65zny33n7r5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnv2uxpl65zny33n7r5h.png" alt="Sample Integration Process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The automation tool queries the Hub Cluster for one or more tokens&lt;/strong&gt; to authenticate with the target managed clusters.&lt;br&gt;
→ &lt;strong&gt;Tip:&lt;/strong&gt; You can create a dedicated ServiceAccount on the Hub Cluster with restricted permissions that allow it to query only the Secrets related to specific Managed ServiceAccounts.&lt;br&gt;
→ This approach helps enforce the principle of &lt;strong&gt;least privilege&lt;/strong&gt;, improving overall security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Hub Cluster API returns the required tokens&lt;/strong&gt;, extracted from the Secrets maintained by the Managed ServiceAccount controller.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The automation tool uses the retrieved tokens&lt;/strong&gt; to perform API calls directly against the Managed Clusters, executing its intended tasks (deployments, queries, validations, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Meanwhile, the Hub Cluster and Managed Clusters continuously ensure that all ServiceAccount tokens remain fresh and valid&lt;/strong&gt;, thanks to the automatic rotation and renewal mechanisms provided by Managed ServiceAccounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your use case requires short-lived tokens (less than two hours) or involves long-running automation workflows, it’s recommended that the automation tool retrieves a fresh token from the Hub before each interaction with the Managed Clusters.&lt;/p&gt;

&lt;p&gt;This helps prevent authentication failures caused by token expiration during long-running workflows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Managing ServiceAccounts at scale has always been a challenge in Kubernetes environments — even more so when operating across multiple clusters.&lt;/p&gt;

&lt;p&gt;The combination of Managed ServiceAccounts and Policies in RHACM/OCM provides a robust and secure framework to automate identity management for workloads and automation tools.&lt;/p&gt;

&lt;p&gt;This approach centralizes token management, ensures automatic rotation, and eliminates the need for manual credential handling on each cluster. As a result, it not only improves operational efficiency but also significantly enhances security posture.&lt;/p&gt;

&lt;p&gt;Whether you’re operating CI/CD pipelines, external automation tools like Ansible, or any system that needs API-level access to clusters, this model provides a scalable, repeatable, and secure way to do it.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/" rel="noopener noreferrer"&gt;Kubernetes - Managing Service Accounts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://open-cluster-management.io/docs/getting-started/integration/managed-serviceaccount/" rel="noopener noreferrer"&gt;Managed ServiceAccount&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>kubernetes</category>
      <category>openshift</category>
    </item>
    <item>
      <title>Highly Scalable Infrastructures with GitOps Pull Model</title>
      <dc:creator>Luiz Cesar Cherri</dc:creator>
      <pubDate>Wed, 18 Jun 2025 12:38:49 +0000</pubDate>
      <link>https://dev.to/cesar_cherri/highly-scalable-infrastructures-with-gitops-pull-model-74p</link>
      <guid>https://dev.to/cesar_cherri/highly-scalable-infrastructures-with-gitops-pull-model-74p</guid>
      <description>&lt;p&gt;In recent years, working as a consultant in the technology field, I’ve observed how companies have increasingly adopted multi-cluster strategies using Kubernetes and OpenShift. These strategies generally aim to distribute workloads across clusters for reasons such as team segmentation or to enhance system resilience and availability.&lt;/p&gt;

&lt;p&gt;To support this approach, delivery automation and pipeline standardization have become essential to ensure consistency, auditability, and scalability — while also providing operational control and efficiency.&lt;/p&gt;

&lt;p&gt;In this article, I show how Red Hat Advanced Cluster Management for Kubernetes (RHACM) enables a Hub-and-Spoke GitOps architecture integrated with Argo CD.&lt;/p&gt;

&lt;p&gt;The practical foundation for this article is the &lt;a href="https://github.com/lccherri/gitops-pull-model" rel="noopener noreferrer"&gt;GitOps Pull Model repository&lt;/a&gt;, which provides a simplified implementation of the proposed model.&lt;/p&gt;

&lt;h1&gt;
  
  
  But… What is GitOps?
&lt;/h1&gt;

&lt;p&gt;GitOps is a declarative approach to infrastructure and application management that relies on Git as the single source of truth and leverages continuous automation to apply changes. Instead of executing manual commands or scripts directly against clusters, the desired state of the environment is versioned in a Git repository, and automated tools, like Argo CD, are responsible for reconciling that state with the actual environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2t4cwf8if0okjjna1f2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2t4cwf8if0okjjna1f2.png" alt="Traditional GitOps Flow" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This strategy brings several key benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auditability and traceability:&lt;/strong&gt; Every change is recorded as a Git commit, enabling full visibility and review history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reproducibility and consistency:&lt;/strong&gt; Environments can be rebuilt from the repository, minimizing drift and human error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security and control:&lt;/strong&gt; By separating change approval (via Git) from change application (via automation), access to clusters can be tightly controlled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed and scalability:&lt;/strong&gt; Applications and configurations can be propagated efficiently and safely across multiple clusters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitOps extends familiar software development concepts — such as pull requests, CI/CD, and versioning — into the realm of infrastructure operations, unifying delivery processes with modern DevOps practices.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Hub-and-Spoke Architecture?
&lt;/h1&gt;

&lt;p&gt;In environments with only a few Kubernetes clusters, it’s common for each cluster to have its own Argo CD instance, directly managed by the development team or even a dedicated DevOps team. However, this approach becomes difficult to scale in dynamic environments where clusters are frequently provisioned and decommissioned.&lt;/p&gt;

&lt;p&gt;To address this challenge, the Hub-and-Spoke model offers a well-established architectural pattern in distributed systems, where a central component (the Hub) coordinates or manages multiple peripheral components (the Spokes). In Kubernetes or OpenShift environments, this pattern proves especially useful for centrally managing a large number of clusters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgzwngvbybgcjvdjsfb3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgzwngvbybgcjvdjsfb3.png" alt="The Hub-and-Spoke Architecture" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a GitOps and multi-cluster management context, the architecture can be described as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hub:&lt;/strong&gt; A central cluster, often running management tools like Red Hat Advanced Cluster Management (RHACM), responsible for registering, inspecting, and applying policies to the Spoke clusters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spokes:&lt;/strong&gt; Managed clusters that operate independently but are governed by configurations or policies originating from the Hub. Each Spoke typically runs its own GitOps agent (e.g., Argo CD) and pulls its desired state from a shared Git repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The RHACM GitOps - Pull Model
&lt;/h1&gt;

&lt;p&gt;Implementing a Hub-and-Spoke architecture can require significant effort from DevOps teams. To simplify this process, &lt;strong&gt;Red Hat Advanced Cluster Management (RHACM)&lt;/strong&gt; provides built-in mechanisms that streamline the deployment of this model.&lt;/p&gt;

&lt;p&gt;RHACM includes controllers that process Argo CD &lt;code&gt;ApplicationSets&lt;/code&gt; and distribute the resulting &lt;code&gt;Applications&lt;/code&gt; to managed clusters that match predefined &lt;code&gt;Placement&lt;/code&gt; criteria. Notably, the Hub cluster does not execute or reconcile these applications itself. Instead, it delegates this responsibility to the target managed clusters.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates how this delegation and synchronization flow works in practice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidfi37nloym4zlpcyz5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidfi37nloym4zlpcyz5t.png" alt="RHACM GitOps Pull Model" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the Argo CD &lt;code&gt;Applications&lt;/code&gt; are applied to the managed clusters, they begin reporting their status back to the Hub cluster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more details on this capability, refer to the official documentation:&lt;br&gt;
&lt;a href="https://docs.redhat.com/en/documentation/red_hat_advanced_cluster_management_for_kubernetes/2.13/html-single/gitops/index" rel="noopener noreferrer"&gt;Red Hat Advanced Cluster Management — GitOps Integration Guide&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Bridging Theory and Practice
&lt;/h1&gt;

&lt;p&gt;The &lt;a href="https://github.com/lccherri/gitops-pull-model" rel="noopener noreferrer"&gt;GitOps Pull Model repository&lt;/a&gt; presents a simplified implementation of the GitOps Hub-and-Spoke architecture, where each Spoke cluster operates independently and &lt;strong&gt;pulls from a shared Git repository&lt;/strong&gt;. Although intentionally minimalistic, the project effectively demonstrates the core principles of GitOps in multi-cluster environments — with a key role played by &lt;strong&gt;Red Hat Advanced Cluster Management (RHACM)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Role of RHACM
&lt;/h2&gt;

&lt;p&gt;RHACM acts as the control plane for the Hub cluster, automating and orchestrating the following tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated installation of the OpenShift GitOps Operator:&lt;/strong&gt; RHACM applies policies that ensure all clusters have the necessary operator installed, enabling the provisioning of Argo CD instances.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative Argo CD configuration on the Hub cluster:&lt;/strong&gt; A dedicated policy configures the Argo CD instance on the Hub, centralizing control and initial setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Provisioning Argo CD on managed clusters:&lt;/strong&gt; RHACM applies policies that deploy and configure Argo CD on each Spoke, so each cluster operates its own independent GitOps instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Selective artifact distribution via Placements:&lt;/strong&gt; Through the use of &lt;code&gt;Placements&lt;/code&gt;, RHACM informs its Argo CD instance which clusters must receive the configurations, based on labels assigned to the managed clusters. This allows centralized governance with flexible scope.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture balances centralized governance and visibility (via the Hub) with decentralized execution (via the Spokes), enhancing &lt;strong&gt;security, scalability, and standardization&lt;/strong&gt; across clusters.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefits of the Pull Model in Multi-Cluster Environments
&lt;/h1&gt;

&lt;p&gt;Adopting a GitOps approach based on the pull model, especially within a Hub-and-Spoke architecture, unlocks several strategic and operational advantages. This choice directly promotes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;&lt;br&gt;
Communication flows from the managed clusters to the Git repository, removing the need for direct Hub access and significantly reducing the attack surface of the overall system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operational Autonomy for Spokes&lt;/strong&gt;&lt;br&gt;
Each managed cluster runs its own Argo CD instance and applies its own manifests, enabling independent operation with local control and greater agility in managing workloads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Horizontal Scalability&lt;/strong&gt;&lt;br&gt;
Adding new clusters does not impact the Hub’s performance, as each Spoke synchronizes independently and asynchronously, allowing the architecture to scale linearly and efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Auditability and Traceability&lt;/strong&gt;&lt;br&gt;
With all configurations version-controlled in Git, changes can be tracked accurately, history is preserved, and rollbacks are safe and straightforward to execute.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless Integration with DevSecOps Practices&lt;/strong&gt;&lt;br&gt;
Centralizing the desired state in Git supports automated validations, pull request-based code reviews, and CI/CD pipelines that are decoupled from runtime environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Elimination of Single Points of Failure&lt;/strong&gt;&lt;br&gt;
Since each Spoke manages its own sync operations, a failure in the Hub does not affect the Spokes, which continue operating based on the last known Git state — improving overall system resilience.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The GitOps Pull Model, provided by RHACM, offers a powerful foundation for scalable, secure, and autonomous Kubernetes and OpenShift operations. By adopting this approach, organizations can reduce operational complexity and improve governance across distributed environments.&lt;/p&gt;

&lt;h1&gt;
  
  
  Credits and References
&lt;/h1&gt;

&lt;p&gt;This article was written to provide theoretical background for the GitOps Pull Model Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lccherri/gitops-pull-model" rel="noopener noreferrer"&gt;GitOps Pull Model Sample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;… which showcases a working example of a multi-cluster GitOps architecture using Red Hat Advanced Cluster Management (RHACM).&lt;/p&gt;

&lt;p&gt;Both the conceptual and practical aspects are based on the following reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.redhat.com/en/documentation/red_hat_advanced_cluster_management_for_kubernetes/2.13/html-single/gitops/index?source=post_page-----18945f558a9f---------------------------------------" rel="noopener noreferrer"&gt;Red Hat Advanced Cluster Management — GitOps Integration Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.redhat.com/en/blog/introducing-the-argo-cd-application-pull-controller-for-red-hat-advanced-cluster-management?source=post_page-----18945f558a9f---------------------------------------" rel="noopener noreferrer"&gt;Introducing the Argo CD Application Pull Controller for Red Hat Advanced Cluster Management&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>openshift</category>
      <category>gitops</category>
    </item>
  </channel>
</rss>
