<p>I have some average yaml file defining some average role resource, all yaml should reflect my resource's desired state.</p>
<p>To get new average role into cluster I usually run <code>kubectl apply -f my-new-role.yaml</code>
but now I see this (recommended!?) alternative <code>kubectl auth reconcile -f my-new-role.yaml</code></p>
<p>Ok, there may be RBAC relationships, ie Bindings, but shouldn't an <strong>apply</strong> do same thing?</p>
<p>Is there ever a case where one would update (cluster) roles but not want their related (cluster) bindings updated?</p>

<p>The <code>kubectl auth reconcile</code> command-line utility has been added in Kubernetes <code>v1.8</code>.<br />
Properly applying RBAC permissions is a complex task because you need to compute logical covers operations between rule sets.</p>
<p>As you can see in the <a href="https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.8.md#cli-changes" rel="noreferrer">CHANGELOG-1.8.md</a>:</p>
<blockquote>
<p>Added RBAC reconcile commands with kubectl auth reconcile -f FILE. When passed a file which contains RBAC roles, rolebindings, clusterroles, or clusterrolebindings, this command computes covers and adds the missing rules. The logic required to properly apply RBAC permissions is more complicated than a JSON merge because you have to compute logical covers operations between rule sets. This means that we cannot use kubectl apply to update RBAC roles without risking breaking old clients, such as controllers.</p>
</blockquote>
<p>The <code>kubectl auth reconcile</code> command will ignore any resources that are not <code>Role</code>, <code>RoleBinding</code>, <code>ClusterRole</code>, and <code>ClusterRoleBinding</code> objects, so you can safely run reconcile on the full set of manifests (see: <a href="https://github.com/argoproj/argo-cd/issues/523#issuecomment-417911606" rel="noreferrer">Use 'kubectl auth reconcile' before 'kubectl apply'</a>)</p>
<hr />
<p>I've created an example to demonstrate how useful the <code>kubectl auth reconcile</code> command is.</p>
<p>I have a simple <code>secret-reader</code> <code>RoleBinding</code> and I want to change a binding's <code>roleRef</code> (I want to change the <code>Role</code> that this binding refers to):<br />
<strong>NOTE:</strong> A binding to a different role is a fundamentally different binding (see: <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#clusterrolebinding-example" rel="noreferrer">A binding to a different role is a fundamentally different binding</a>).</p>
<pre><code># BEFORE
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secret-reader
subjects:
- kind: ServiceAccount
  name: service-account-1
  namespace: default
  
# AFTER
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secret-creator
subjects:
- kind: ServiceAccount
  name: service-account-1
  namespace: default
</code></pre>
<p>As we know, <code>roleRef</code> is immutable, so it is not possible to update this <code>secret-admin</code> <code>RoleBinding</code> using <code>kubectl apply</code>:</p>
<pre><code>$ kubectl apply -f secret-admin.yml
The RoleBinding &quot;secret-admin&quot; is invalid: roleRef: Invalid value: rbac.RoleRef{APIGroup:&quot;rbac.authorization.k8s.io&quot;, Kind:&quot;Role&quot;, Name:&quot;secret-creator&quot;}: cannot change roleRef
</code></pre>
<p>Instead, we can use <code>kubectl auth reconcile</code>. If a <code>RoleBinding</code> is updated to a new <code>roleRef</code>, the <code>kubectl auth reconcile</code> command handles a delete/recreate related objects for us.</p>
<pre><code>$ kubectl auth reconcile -f secret-admin.yml
rolebinding.rbac.authorization.k8s.io/secret-admin reconciled
        reconciliation required recreate
</code></pre>
<p>Additionally, you can use the <code>--remove-extra-permissions</code> and <code>--remove-extra-subjects</code> options.</p>
<p>Finally, we can check if everything has been successfully updated:</p>
<pre><code>$ kubectl describe rolebinding secret-admin
Name:         secret-admin
Labels:       &lt;none&gt;
Annotations:  &lt;none&gt;
Role:
  Kind:  Role
  Name:  secret-creator
Subjects:
  Kind            Name               Namespace
  ----            ----               ---------
  ServiceAccount  service-account-1  default
</code></pre>
