Skip to content

dex, oauth2-proxy: refuse to render placeholder credentials - #3569

Open
danish9039 wants to merge 2 commits into
kubeflow:masterfrom
danish9039:gsoc/fail-on-placeholder-secrets
Open

dex, oauth2-proxy: refuse to render placeholder credentials#3569
danish9039 wants to merge 2 commits into
kubeflow:masterfrom
danish9039:gsoc/fail-on-placeholder-secrets

Conversation

@danish9039

Copy link
Copy Markdown
Member

Pull Request Template for Kubeflow Manifests

✏️ Summary of Changes

Both charts ship REPLACE_ME credential defaults, and nothing stopped an
installation from using them.

helm install dex ./common/dex/helm --namespace auth
helm install oauth2-proxy ./common/oauth2-proxy/helm --namespace oauth2-proxy

Today both succeed, and produce:

dex-oidc-client.OIDC_CLIENT_SECRET  = REPLACE_ME_OIDC_CLIENT_SECRET
dex-passwords.DEX_USER_PASSWORD     = REPLACE_ME_STATIC_PASSWORD_HASH
oauth2-proxy.client-secret          = REPLACE_ME_CLIENT_SECRET
oauth2-proxy.cookie-secret          = REPLACE_ME_COOKIE_SECRET

The cookie secret signs oauth2-proxy session cookies. A value anyone can read out
of this repository means anyone can forge a session.

The charts now fail before rendering while a placeholder is in place.

Two related checks

staticPassword.hash must look like bcrypt. Dex compares the submitted
password against this hash; any other value matches nothing, so the account
silently cannot log in. The chart checks the $2a$ / $2b$ / $2y$ prefix.

credentials.cookieSecret must decode to 16, 24 or 32 bytes. oauth2-proxy
uses it as an AES key. Any other length is accepted by Kubernetes and then
crash-loops the workload, which is a much worse place to find out.

Every message names the value and how to generate a correct one, for example:

credentials.cookieSecret must be 16, 24 or 32 bytes, raw or base64 encoded;
got 8 raw bytes decoding to 6. Generate one with
openssl rand -base64 32 | tr -- '+/' '-_'

Test change

tests/test_dex_helm_rollout_checksums.py rendered with the placeholder defaults
and, in one case, with staticPassword.hash=changed-password-hash, a value no
password could ever match. It now supplies real-shaped credentials. The guard
found this, which is the point of it.

📦 Dependencies

None. Applies to two merged charts and is independent of every open pull request.

#3568 also touches common/dex/helm; the two do not overlap in any file except
the chart README, and whichever merges second may need a trivial rebase.

🐛 Related Issues

Found while reviewing the Dex configuration surface for #3568.

Validation

helm template dex ./common/dex/helm -n auth                      # fails, as intended
helm template oauth2-proxy ./common/oauth2-proxy/helm -n oauth2-proxy   # fails
./tests/helm_kustomize_compare_all.sh          # every component still passes
python3 tests/test_dex_helm_rollout_checksums.py
helm lint common/dex/helm --namespace auth
helm lint common/oauth2-proxy/helm --namespace oauth2-proxy
black --check tests/ && git diff --check

The Kustomize comparison is unaffected: the CI values files supply real
credentials, so every scenario renders exactly as before.

✅ Contributor Checklist

  • I have tested these changes with kustomize. See Installation Prerequisites.
  • All commits are signed-off to satisfy the DCO check.
  • I have considered adding my company to the adopters page to support Kubeflow and help the community, since I expect help from the community for my issue (see 1. and 2.).

You can join the CNCF Slack and access our meetings at the Kubeflow Community website. Our channel on the CNCF Slack is here #kubeflow-community-distribution.

@google-oss-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign kimwnasptd for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@danish9039

Copy link
Copy Markdown
Member Author

/retest

@google-oss-prow google-oss-prow Bot added size/L and removed size/M labels Aug 2, 2026
@danish9039

Copy link
Copy Markdown
Member Author

/retest

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds Helm rendering guards against placeholder or malformed credentials for Dex and OAuth2 Proxy.

Changes:

  • Validates OIDC, bcrypt, and cookie secrets.
  • Documents credential requirements.
  • Adds automated coverage and valid test fixtures.

Reviewed changes

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

Show a summary per file
File Description
common/dex/helm/templates/validate-credentials.yaml Validates Dex credentials.
common/dex/helm/README.md Documents Dex requirements.
common/oauth2-proxy/helm/templates/validate-credentials.yaml Validates OAuth2 Proxy credentials.
common/oauth2-proxy/helm/README.md Documents cookie-secret requirements.
tests/test_helm_credential_guards.py Tests credential guards.
tests/test_dex_helm_rollout_checksums.py Supplies valid credential fixtures.
.github/workflows/helm-kustomize-comparison.yml Runs the new tests.

Comment thread .github/workflows/helm-kustomize-comparison.yml Outdated
Comment thread tests/dex_helm_rollout_checksums_test.py Outdated
Comment thread common/dex/helm/templates/validate-credentials.yaml Outdated
Signed-off-by: danish9039 <danishsiddiqui040@gmail.com>
@danish9039
danish9039 force-pushed the gsoc/fail-on-placeholder-secrets branch from e265180 to 459d736 Compare August 31, 2026 17:41
@danish9039

Copy link
Copy Markdown
Member Author

/retest

Copilot review follow-up: the placeholder-hash check fired even with
config.enablePasswordDB=false, where the hash is unused, blocking the
external-connector configuration. Also names the shared workflow step for
both components and gives the credential fixtures explicit names.

Signed-off-by: danish9039 <danishsiddiqui040@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Several core guard branches and the padded-secret path remain untested.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

tests/helm_credential_guards_test.py:69

  • This default render exits at the client-secret guard, leaving the cookie-placeholder guard untested. Render again with a valid client secret and assert the cookie-specific failure so the second guard cannot regress unnoticed.
    def test_oauth2_proxy_defaults_are_rejected(self):
        result = self.render_oauth2_proxy()

        self.assertNotEqual(result.returncode, 0)
        self.assertIn(
  • Files reviewed: 7/7 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +59 to +63
def test_dex_defaults_are_rejected(self):
result = self.render_dex()

self.assertNotEqual(result.returncode, 0)
self.assertIn("oidcClient.secret is still the placeholder", result.stderr)
("123456789012345678901234", "raw 24"),
("12345678901234567890123456789012", "raw 32"),
("AAECAwQFBgcICQoLDA0ODw", "unpadded URL-safe, decodes to 16"),
("Zm9vYmFyZm9vYmFyZm9vYmFyZm9vYmFy", "padded, decodes to 24"),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants