Skip to content

Commit 3ae859a

Browse files
committed
fix: Make Renewal Token Expiry Feature Configurable
Signed-off-by: akhil nittala <nakhil@redhat.com>
1 parent c9e571d commit 3ae859a

9 files changed

Lines changed: 120 additions & 3 deletions

File tree

api/v1beta1/argocd_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,11 @@ func (a *ArgoCDNetworkPolicySpec) IsEnabled() bool {
924924
// +k8s:openapi-gen=true
925925
// +kubebuilder:validation:XValidation:rule="!(has(self.sso) && has(self.oidcConfig))",message="spec.sso and spec.oidcConfig cannot both be set"
926926
type ArgoCDSpec struct {
927+
// EnableDexTokenExpiry enables the short-lived Dex token renewal feature.
928+
// When true, the operator uses TokenRequest API for time-limited tokens.
929+
// When false (default), the operator uses the legacy non-expiring token approach.
930+
// +kubebuilder:validation:Optional
931+
EnableDexTokenExpiry *bool `json:"enableDexTokenExpiry,omitempty"`
927932

928933
// ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed.
929934
ApplicationSet *ArgoCDApplicationSet `json:"applicationSet,omitempty"`

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/argocd-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ metadata:
257257
capabilities: Deep Insights
258258
categories: Integration & Delivery
259259
certified: "false"
260-
createdAt: "2026-07-07T12:03:30Z"
260+
createdAt: "2026-07-09T06:07:34Z"
261261
description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
262262
operators.operatorframework.io/builder: operator-sdk-v1.35.0
263263
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4

bundle/manifests/argoproj.io_argocds.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17804,6 +17804,12 @@ spec:
1780417804
disableAdmin:
1780517805
description: DisableAdmin will disable the admin user.
1780617806
type: boolean
17807+
enableDexTokenExpiry:
17808+
description: |-
17809+
EnableDexTokenExpiry enables the short-lived Dex token renewal feature.
17810+
When true, the operator uses TokenRequest API for time-limited tokens.
17811+
When false (default), the operator uses the legacy non-expiring token approach.
17812+
type: boolean
1780717813
extraConfig:
1780817814
additionalProperties:
1780917815
type: string

config/crd/bases/argoproj.io_argocds.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17793,6 +17793,12 @@ spec:
1779317793
disableAdmin:
1779417794
description: DisableAdmin will disable the admin user.
1779517795
type: boolean
17796+
enableDexTokenExpiry:
17797+
description: |-
17798+
EnableDexTokenExpiry enables the short-lived Dex token renewal feature.
17799+
When true, the operator uses TokenRequest API for time-limited tokens.
17800+
When false (default), the operator uses the legacy non-expiring token approach.
17801+
type: boolean
1779617802
extraConfig:
1779717803
additionalProperties:
1779817804
type: string

controllers/argocd/argocd_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ func (r *ReconcileArgoCD) internalReconcile(ctx context.Context, request ctrl.Re
376376

377377
// If Dex is in use, requeue before the token reaches its renewal threshold so
378378
// the operator proactively renews it without waiting for an external event.
379-
if UseDex(argocd) {
379+
if UseDex(argocd) && isDexTokenExpiryFeatureEnabled(argocd) {
380380
if v, ok := r.dexTokenRequeueAfter.Load(argocd.Namespace); ok {
381381
if d, ok := v.(time.Duration); ok {
382382
return reconcile.Result{RequeueAfter: d}, argocd, argoCDStatus, nil

controllers/argocd/dex.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,27 @@ func needsDexTokenRenewal(secret *corev1.Secret) bool {
7676
return time.Until(expiry) < dexServerTokenRenewalThreshold()
7777
}
7878

79+
// isDexTokenExpiryFeatureEnabled returns true if Dex token renewal expiry is enabled.
80+
// Users can set enableDexTokenExpiry: false (default) in the ArgoCD CR to use the legacy non-expiring token approach.
81+
func isDexTokenExpiryFeatureEnabled(cr *argoproj.ArgoCD) bool {
82+
if cr.Spec.EnableDexTokenExpiry == nil {
83+
return false // Enabled by default (old behavior with non-expiring tokens)
84+
}
85+
return *cr.Spec.EnableDexTokenExpiry
86+
}
87+
7988
// getDexOAuthClientSecret returns a time-limited Dex OAuth client token via the TokenRequest API.
89+
// If token renewal is disabled via the feature flag, it falls back to the legacy approach.
8090
func (r *ReconcileArgoCD) getDexOAuthClientSecret(cr *argoproj.ArgoCD) (*string, error) {
91+
// Check if token expiry feature is enabled, by default it is false, so we use the non-expiry legacy approach
92+
if !isDexTokenExpiryFeatureEnabled(cr) {
93+
// Use legacy approach (non-expiring tokens)
94+
log.Info("Dex token renewal feature is disabled, using legacy non-expiring token approach")
95+
return r.getDexOAuthClientSecretLegacy(cr)
96+
}
97+
98+
// Use new TokenRequest API approach (PR #2163)
99+
log.Info("Dex token renewal feature is enabled, using TokenRequest API for short-lived tokens")
81100
sa := newServiceAccountWithName(common.ArgoCDDefaultDexServiceAccountName, cr)
82101
if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil {
83102
return nil, err
@@ -159,6 +178,76 @@ func (r *ReconcileArgoCD) getDexOAuthClientSecret(cr *argoproj.ArgoCD) (*string,
159178
return &token, nil
160179
}
161180

181+
// getDexOAuthClientSecretLegacy returns the legacy non-expiring Dex OAuth client secret.
182+
// This is the original implementation before PR #2163.
183+
// It uses persistent service account token secrets without automatic renewal.
184+
func (r *ReconcileArgoCD) getDexOAuthClientSecretLegacy(cr *argoproj.ArgoCD) (*string, error) {
185+
sa := newServiceAccountWithName(common.ArgoCDDefaultDexServiceAccountName, cr)
186+
if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil {
187+
return nil, err
188+
}
189+
190+
// Find the token secret
191+
var tokenSecret *corev1.ObjectReference
192+
for _, saSecret := range sa.Secrets {
193+
if strings.Contains(saSecret.Name, "token") {
194+
tokenSecret = &saSecret
195+
break
196+
}
197+
}
198+
199+
if tokenSecret == nil {
200+
// This change of creating secret for dex service account is due to
201+
// the change in Kubernetes v1.24 that reduces secret-based service account tokens.
202+
// From k8s v1.24 onwards, no default secret for service account is created.
203+
// However, for dex to work we need to provide the token of the secret used
204+
// by the dex service account as an OAuth token. This change helps achieve that.
205+
secret := &corev1.Secret{
206+
ObjectMeta: metav1.ObjectMeta{
207+
GenerateName: "argocd-dex-server-token-",
208+
Namespace: cr.Namespace,
209+
Annotations: map[string]string{
210+
corev1.ServiceAccountNameKey: sa.Name,
211+
},
212+
},
213+
Type: corev1.SecretTypeServiceAccountToken,
214+
}
215+
argoutil.AddTrackedByOperatorLabel(&secret.ObjectMeta)
216+
argoutil.LogResourceCreation(log, secret)
217+
218+
err := r.Create(context.TODO(), secret)
219+
if err != nil {
220+
return nil, errors.New("unable to locate and create ServiceAccount token for OAuth client secret")
221+
}
222+
223+
err = controllerutil.SetControllerReference(cr, secret, r.Scheme)
224+
if err != nil {
225+
return nil, err
226+
}
227+
228+
tokenSecret = &corev1.ObjectReference{
229+
Name: secret.Name,
230+
Namespace: cr.Namespace,
231+
}
232+
sa.Secrets = append(sa.Secrets, *tokenSecret)
233+
234+
argoutil.LogResourceUpdate(log, sa, "adding ServiceAccount token for OAuth client secret")
235+
err = r.Update(context.TODO(), sa)
236+
if err != nil {
237+
return nil, errors.New("failed to add ServiceAccount token for OAuth client secret")
238+
}
239+
}
240+
241+
// Fetch the secret to obtain the token
242+
secret := argoutil.NewSecretWithName(cr, tokenSecret.Name)
243+
if err := argoutil.FetchObject(r.Client, cr.Namespace, secret.Name, secret); err != nil {
244+
return nil, err
245+
}
246+
247+
token := string(secret.Data["token"])
248+
return &token, nil
249+
}
250+
162251
// reconcileDexLegacySATokenSecrets deletes non-expiring kubernetes.io/service-account-token
163252
// Secrets for the Dex SA and removes their stale references from the SA.
164253
func (r *ReconcileArgoCD) reconcileDexLegacySATokenSecrets(cr *argoproj.ArgoCD) error {

deploy/olm-catalog/argocd-operator/0.19.0/argocd-operator.v0.19.0.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ metadata:
257257
capabilities: Deep Insights
258258
categories: Integration & Delivery
259259
certified: "false"
260-
createdAt: "2026-07-07T12:03:30Z"
260+
createdAt: "2026-07-09T06:07:34Z"
261261
description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
262262
operators.operatorframework.io/builder: operator-sdk-v1.35.0
263263
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4

deploy/olm-catalog/argocd-operator/0.19.0/argoproj.io_argocds.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17804,6 +17804,12 @@ spec:
1780417804
disableAdmin:
1780517805
description: DisableAdmin will disable the admin user.
1780617806
type: boolean
17807+
enableDexTokenExpiry:
17808+
description: |-
17809+
EnableDexTokenExpiry enables the short-lived Dex token renewal feature.
17810+
When true, the operator uses TokenRequest API for time-limited tokens.
17811+
When false (default), the operator uses the legacy non-expiring token approach.
17812+
type: boolean
1780717813
extraConfig:
1780817814
additionalProperties:
1780917815
type: string

0 commit comments

Comments
 (0)