Skip to content

feat: add forceLegacyConfig flag for alphaConfig compatibility#385

Merged
tuunit merged 6 commits intooauth2-proxy:mainfrom
pierluigilenoci:fix/alphaconfig-unified-improvements
Mar 26, 2026
Merged

feat: add forceLegacyConfig flag for alphaConfig compatibility#385
tuunit merged 6 commits intooauth2-proxy:mainfrom
pierluigilenoci:fix/alphaconfig-unified-improvements

Conversation

@pierluigilenoci
Copy link
Copy Markdown
Member

@pierluigilenoci pierluigilenoci commented Jan 6, 2026

Summary

This PR fixes critical bugs in alphaConfig integration and introduces the forceLegacyConfig flag to provide backward compatibility for users with custom configuration files.

Problem Statement

Issue #226: alphaConfig fails with "invalid keys: upstreams"

When alphaConfig.enabled = true, oauth2-proxy loads BOTH configuration files:

  • The legacy config file (oauth2_proxy.cfg) via --config flag
  • The alpha config file (oauth2_proxy.yml) via --alpha-config flag

However, alphaConfig removed support for the upstreams option. If the legacy config contains upstreams, oauth2-proxy fails with:

failed to load core options: failed to load config: error unmarshalling config: '' has invalid keys: upstreams

Critical Bug: Missing email_domains validation

When alphaConfig.enabled=true with default values, the deployment was not mounting the ConfigMap or adding the --config flag, causing oauth2-proxy to fail with:

missing setting for email validation

Issue #302: Difficulty using external secrets with alphaConfig

Users wanting to load secrets from external sources (e.g., Azure Key Vault CSI Driver) lacked clear documentation on how to inject secrets via environment variables.

Issue #311: Missing alphaConfig documentation

Users needed examples showing how to configure upstreamConfig in alphaConfig mode, particularly for multi-upstream scenarios with path-based routing.

Solution

1. Fixed Critical Bug: Always mount ConfigMap

Fixed deployment template to ALWAYS mount the ConfigMap and add --config flag, regardless of alphaConfig settings. This ensures email_domains is always provided to oauth2-proxy.

2. Fixed alphaConfig Incompatibility

Changed the auto-generated legacy config logic:

  • When alphaConfig DISABLED → Full legacy config with email_domains + upstreams
  • When alphaConfig ENABLED → Minimal legacy config with email_domains ONLY (no upstreams)

This is because when alphaConfig is enabled, oauth2-proxy loads BOTH config files, and the legacy config CANNOT contain options removed by alphaConfig.

3. Introduced forceLegacyConfig Flag

Added config.forceLegacyConfig (default: true) to control whether custom configFile should be used when alphaConfig is enabled:

  • forceLegacyConfig = true (default): Use custom configFile as-is (backward compatible)
  • forceLegacyConfig = false: Ignore custom configFile and auto-generate minimal config

IMPORTANT: This flag ONLY affects custom configFile behavior. It does NOT control whether upstreams are included in auto-generated configs.

4. Structured Configuration

Changed from hardcoded config.configFile to structured fields:

  • config.emailDomains: Email domains allowed to authenticate (default: [ "*" ])
  • config.upstreams: Legacy upstream configuration (default: [ "file:///dev/null" ])
  • config.configFile: Custom config template (empty by default)

5. Configuration Generation Logic

The configmap.yaml template implements this logic:

alphaConfig forceLegacyConfig configFile Generated Config
disabled any empty email_domains + upstreams
disabled any custom Uses custom configFile as-is
enabled any empty email_domains ONLY (no upstreams)
enabled true custom Uses custom configFile as-is
enabled false custom email_domains ONLY (ignores custom)

Key Points:

  • When alphaConfig is enabled, auto-generated config NEVER includes upstreams (regardless of forceLegacyConfig)
  • forceLegacyConfig only controls whether to use or ignore custom configFile when alphaConfig is enabled
  • ConfigMap is ALWAYS mounted and --config flag is ALWAYS added

6. Fixed ConfigMap YAML rendering

Fixed aggressive Go template trim markers ({{- ... -}}) in configmap.yaml that collapsed data: and oauth2_proxy.cfg: onto a single line, producing invalid YAML. This caused the config file to be mounted as a directory instead of a file, resulting in CrashLoopBackOff:

failed to load legacy options: failed to load config: unable to load config file: read /etc/oauth2_proxy/oauth2_proxy.cfg: is a directory

7. Fixed checksum/config for rollout detection

The checksum/config pod annotation was only computed when config.configFile was set. Changes to auto-generated config (via emailDomains, upstreams, alphaConfig.enabled, or forceLegacyConfig) would update the ConfigMap but NOT trigger a pod rollout, leaving pods with stale config. Now the checksum is computed from the full rendered configmap.yaml whenever existingConfig is not set.

8. Comprehensive Documentation

Added examples for:

  • alphaConfig upstreams: Multi-upstream configuration with path-based routing, rewriteTarget, injectResponseHeaders
  • External secrets: Using extraEnv to load secrets from Azure Key Vault CSI Driver
  • forceLegacyConfig usage: Clear instructions on when and how to use the flag

Migration Guide

For most users (NOT experiencing issue #226)

No action required. The chart now works correctly with alphaConfig enabled using default values.

For users experiencing "invalid keys: upstreams" error

If you're getting this error with alphaConfig enabled, you have two options:

Option A: Use alphaConfig upstreams (RECOMMENDED)

config:
  emailDomains: [ "*" ]
  # Remove upstreams from config - let chart auto-generate minimal legacy config

alphaConfig:
  enabled: true
  configData:
    upstreamConfig:
      upstreams:
        - id: backend
          path: /
          uri: http://backend:8080

Option B: Use custom configFile with forceLegacyConfig
If you have a custom config.configFile that includes upstreams:

config:
  forceLegacyConfig: false  # Ignore custom configFile
  emailDomains: [ "*" ]

alphaConfig:
  enabled: true
  configData:
    upstreamConfig:
      upstreams:
        - id: backend
          path: /
          uri: http://backend:8080

For users with custom configFile (backward compatibility)

If you have a custom config.configFile that does NOT contain removed alphaConfig options:

config:
  forceLegacyConfig: true  # Use custom configFile (default)
  configFile: |
    email_domains = [ "*" ]
    # Your other legacy config options

alphaConfig:
  enabled: true
  configData:
    upstreamConfig:
      upstreams:
        - id: backend
          path: /
          uri: http://backend:8080

Testing

Created comprehensive CI test suite covering all configuration scenarios:

All test cases pass successfully.

Breaking Changes

None. This is a non-breaking change.

  • ConfigMap is now always mounted (fixes bug, doesn't break existing deployments)
  • Default behavior with alphaConfig now works correctly
  • forceLegacyConfig defaults to true for backward compatibility with custom configFiles

Checklist

  • Chart version bumped to 10.2.0 (minor version for new feature)
  • Changelog updated in Chart.yaml
  • Comprehensive test suite created with 6 CI test scenarios
  • Documentation added with examples
  • DCO sign-off included in all commits
  • Zero breaking changes confirmed via testing

Related Issues

@pierluigilenoci pierluigilenoci force-pushed the fix/alphaconfig-unified-improvements branch 6 times, most recently from 2226bf0 to ed7aef1 Compare January 6, 2026 21:21
@pierluigilenoci pierluigilenoci changed the title feat: Add forceLegacyConfig flag for alphaConfig compatibility [WIP] feat: Add forceLegacyConfig flag for alphaConfig compatibility Jan 6, 2026
@pierluigilenoci pierluigilenoci force-pushed the fix/alphaconfig-unified-improvements branch from 1314875 to 9f00757 Compare January 7, 2026 09:10
@pierluigilenoci pierluigilenoci requested a review from tuunit January 7, 2026 09:14
@pierluigilenoci pierluigilenoci changed the title [WIP] feat: Add forceLegacyConfig flag for alphaConfig compatibility feat: Add forceLegacyConfig flag for alphaConfig compatibility Jan 7, 2026
@pierluigilenoci pierluigilenoci requested a review from tuunit January 7, 2026 10:34
@pierluigilenoci pierluigilenoci force-pushed the fix/alphaconfig-unified-improvements branch from 81e4ac9 to 2b757e4 Compare January 15, 2026 09:23
@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch 2 times, most recently from a7ae6d4 to 9468636 Compare January 16, 2026 08:00
@pierluigilenoci pierluigilenoci force-pushed the fix/alphaconfig-unified-improvements branch 2 times, most recently from e9822cd to 9683e02 Compare January 24, 2026 19:35
@pierluigilenoci
Copy link
Copy Markdown
Member Author

Hey @JoelSpeed @desaintmartin @jkroepke — just a gentle nudge on this one. @tuunit raised a question about whether this could be a breaking change, and I provided a detailed explanation back in January, but we haven't had a chance to reach consensus yet.

Would any of you have a moment to take a look and share your thoughts? I'd really appreciate a second pair of eyes on this. No rush at all — just want to make sure it doesn't fall through the cracks. Thanks!

@tuunit
Copy link
Copy Markdown
Member

tuunit commented Mar 20, 2026

@pierluigilenoci sorry I lost track of your PR always feel free to give me another nudge on Slack! I'll have another look at it tomorrow

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Helm chart’s config generation to support alphaConfig mode without conflicting legacy options, and introduces a config.forceLegacyConfig flag to control compatibility behavior when users provide a custom legacy config file.

Changes:

  • Always mount the legacy ConfigMap and always pass --config, ensuring legacy-required settings (like email_domains) are present even with alphaConfig enabled.
  • Restructure legacy config generation into structured values (config.emailDomains, config.upstreams) and conditional rendering logic in configmap.yaml to avoid upstreams when alphaConfig is enabled.
  • Add multiple ct install scenarios and update chart metadata/changelog entries.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
helm/oauth2-proxy/values.yaml Introduces structured config fields + forceLegacyConfig and adds documentation/examples.
helm/oauth2-proxy/templates/deployment.yaml Makes legacy --config argument and config mount unconditional.
helm/oauth2-proxy/templates/configmap.yaml Implements the legacy-config rendering matrix for alphaConfig / forceLegacyConfig / configFile.
helm/oauth2-proxy/ci/custom-configfile-values.yaml Adds ct install scenario for custom legacy config (alpha disabled).
helm/oauth2-proxy/ci/alphaconfig-legacy-true-values.yaml Adds ct scenario for alphaConfig with forceLegacyConfig=true.
helm/oauth2-proxy/ci/alphaconfig-legacy-false-values.yaml Adds ct scenario for alphaConfig with forceLegacyConfig=false.
helm/oauth2-proxy/ci/alphaconfig-custom-configfile-legacy-true-values.yaml Adds ct scenario for alphaConfig + custom legacy config honored.
helm/oauth2-proxy/ci/alphaconfig-custom-configfile-legacy-false-values.yaml Adds ct scenario for alphaConfig + custom legacy config ignored.
helm/oauth2-proxy/ci/existing-configmap-values.yaml Adds ct scenario for using an externally provided legacy ConfigMap.
helm/oauth2-proxy/Chart.yaml Bumps chart version and updates Artifact Hub changelog annotations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tuunit tuunit changed the title feat: Add forceLegacyConfig flag for alphaConfig compatibility feat: add forceLegacyConfig flag for alphaConfig compatibility Mar 21, 2026
@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch from 25b74b9 to d8075c2 Compare March 21, 2026 09:45
@tuunit tuunit requested a review from Copilot March 21, 2026 09:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pierluigilenoci pierluigilenoci force-pushed the fix/alphaconfig-unified-improvements branch from 87ae0cd to 21be40f Compare March 21, 2026 13:33
@pierluigilenoci
Copy link
Copy Markdown
Member Author

@tuunit in the meantime I've addressed all the Copilot review observations and squashed everything into a single commit. Looking forward to your improvements!

pierluigilenoci and others added 2 commits March 23, 2026 01:03
- Always mount ConfigMap and pass --config flag regardless of alphaConfig
- Auto-generate minimal legacy config (email_domains only) when alphaConfig enabled
- Add config.forceLegacyConfig flag to control custom configFile behavior
- Add structured config fields: emailDomains, upstreams
- Fix configmap.yaml YAML rendering (trim markers collapsing data:/key)
- Compute checksum/config from rendered configmap for proper rollout detection
- Add comprehensive CI test scenarios and documentation

Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch from 21be40f to aa1f3e0 Compare March 22, 2026 18:30
@tuunit
Copy link
Copy Markdown
Member

tuunit commented Mar 22, 2026

@pierluigilenoci

I made a couple larger and minor changes:

  • Refactored config logic into helpers (_helpers.tpl): Moved inline conditionals from configmap.yaml into reusable templates (legacy-config.mode, legacy-config.name, legacy-config.content) for better and more central maintainability

  • Fixed checksum behavior: Changed deployment annotation to hash actual rendered config content instead of the template file path (this should ensure that pods actually roll when values change, not just when templates change)

  • Renamed the CI coverage: 6 granular test cases covering all combinations of alphaConfig.enabled + forceLegacyConfig + existingConfig/configFile

  • Updated the alphaConfig migration guide and precedence rules in Readme and other places like the values yaml and helpers

@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch 3 times, most recently from e62b3f1 to b8bb546 Compare March 22, 2026 18:37
@tuunit tuunit requested a review from Copilot March 22, 2026 18:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch from b8bb546 to 2010371 Compare March 22, 2026 18:49
* Refactored config logic into helpers (_helpers.tpl): Moved inline conditionals from configmap.yaml into reusable templates (legacy-config.mode, legacy-config.name, legacy-config.content) for better and more central maintainability

* Fixed checksum behavior: Changed deployment annotation to hash actual rendered config content instead of the template file path (this should ensure that pods actually roll when values change, not just when templates change)

* Renamed the CI coverage: 6 granular test cases covering all combinations of alphaConfig.enabled + forceLegacyConfig + existingConfig/configFile

* Updated the alphaConfig migration guide and precedence rules in Readme and other places like the values yaml and helpers

Signed-off-by: Jan Larwig <jan@larwig.com>
@tuunit tuunit force-pushed the fix/alphaconfig-unified-improvements branch from 2010371 to de9be5f Compare March 22, 2026 18:50
@tuunit
Copy link
Copy Markdown
Member

tuunit commented Mar 22, 2026

@pierluigilenoci please have a look at more improvements. Hope it makes sense to you!

I'm not yet 100% happy with the Readme update. it sounds quite convoluted and i think users will be confused. i'll give it another shot to rephrase it differently tomorrow on my way to kubecon

Signed-off-by: Jan Larwig <jan@larwig.com>
@pierluigilenoci
Copy link
Copy Markdown
Member Author

pierluigilenoci commented Mar 23, 2026

Hey @tuunit, thanks for the refactoring — the _helpers.tpl approach is much cleaner. A couple of things I'd like to discuss:

1. config.configFile default change — potential breaking change?

The default for config.configFile changed from:

configFile: |-
    email_domains = [ "*" ]
    upstreams = [ "file:///dev/null" ]

to:

configFile: ""

While functionally equivalent for the chart's own rendering (the new structured fields emailDomains and upstreams produce the same output), this could be a breaking change for users who reference .Values.config.configFile in their own wrapper charts or custom templates — they would now get an empty string instead of the legacy config content.

Should we call this out explicitly in the migration guide / changelog?

2. Doubts about closing #302

I initially included Closes #302 in the PR description, but looking at it again I'm not sure we're actually resolving what that issue asks for.

Issue #302 raises two architectural concerns:

  1. The alpha secret is stored as base64 instead of plain YAML
  2. Secrets (clientId, clientSecret) should be mapped to environment variables by the chart itself, not embedded in the config file

What we provide here is a documentation workaround (showing users how to manually use extraEnv with secretKeyRef), but the chart still embeds secrets in the alpha config secret the same way as before.

I'm thinking we should either:

  • Change Closes #302 to Related to #302 (acknowledging it's a partial workaround, not a full fix)
  • Or plan a separate follow-up to actually implement env-var injection for alpha secrets in the chart

What do you think? I don't want to close #302 and have users re-open it because the core ask wasn't addressed.

(Also fixed the "inot" → "into" typo in the README directly.)

@pierluigilenoci
Copy link
Copy Markdown
Member Author

@tuunit this is my PR, is up to you for the final approval 😬

Copy link
Copy Markdown
Member

@tuunit tuunit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tuunit tuunit merged commit 727b5ec into oauth2-proxy:main Mar 26, 2026
2 checks passed
name: {{ template "oauth2-proxy.fullname" . }}-wait-for-redis
defaultMode: 0775
{{- end }}
{{- if or .Values.config.existingConfig .Values.config.configFile }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason to remove this line? This breaks my setup as I use oauth2-proxy with CSI SecretStore Driver and I am mounting the config file through the CSI SecretStore driver and not a configmap. In my Helm values I have

config:
	configfile: ""

Due to this config and the now removed logic it didn't used tomount the configmap.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @MattiasGees this is simple a use case we didn't consider during the refactoring.

I think the following fix should help resolve your problem:
#402

Please have a look at it :)

pierluigilenoci added a commit to pierluigilenoci/manifests that referenced this pull request Mar 29, 2026
When alphaConfig.enabled=false and forceLegacyConfig=false, the chart
now skips ConfigMap generation, volume mount, and --config flag entirely.
This restores support for users managing oauth2-proxy configuration via
external means (e.g., CSI SecretStore Driver) that was broken by oauth2-proxy#385.

Closes oauth2-proxy#385 (discussion_r3001082837)
pierluigilenoci added a commit to pierluigilenoci/manifests that referenced this pull request Mar 29, 2026
When alphaConfig.enabled=false and forceLegacyConfig=false, the chart
now skips ConfigMap generation, volume mount, and --config flag entirely.
This restores support for users managing oauth2-proxy configuration via
external means (e.g., CSI SecretStore Driver) that was broken by oauth2-proxy#385.

Closes oauth2-proxy#385 (discussion_r3001082837)

Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants