feat: Expose the OIDC JWKS tunables through the operator - #6690
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #6690 +/- ##
=======================================
Coverage 46.80% 46.81%
=======================================
Files 415 415
Lines 50395 50396 +1
Branches 7214 7214
=======================================
+ Hits 23587 23591 +4
+ Misses 25155 25154 -1
+ Partials 1653 1651 -2
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
franciscojavierarceo
left a comment
There was a problem hiding this comment.
The new JWKS fields are added only to the v1 API and generated v1 artifacts, while v1alpha1 remains a served API version in the CRD. A client submitting the still-served v1alpha1 form cannot express these settings and the fields will be unavailable/pruned during conversion. We should either add the fields and generated schema/deepcopy for v1alpha1 as well, or explicitly document and enforce that these new OIDC settings are unsupported through the served deprecated version.
|
@franciscojavierarceo The mechanism you describe is real and I confirmed it against the generated CRD: v1 exposes 8 fields under The part worth flagging is that this isn't specific to the JWKS settings. v1alpha1 has never carried The warning I added covers the whole Advanced OIDC options section rather than the two new fields, and says plainly that applying that example as v1alpha1 leaves OIDC configured by Secret alone with nothing in the output to say so. On enforcement: the v1alpha1 schema already enforces it, since the fields can't be expressed there at all, so I didn't add a validation path. Happy to backport the full OIDC field set to v1alpha1 if you'd rather close the gap properly, though that feels like its own PR against a deprecated version. |
|
@franciscojavierarceo @ntkathole Green and ready for another look, and it needs a @ntkathole this is the operator follow-up you asked about on #6683. |
|
@ntkathole @franciscojavierarceo It's failing repo-wide. The run on the unrelated The cause looks like a constraint that the pinned requirements have drifted past. Only PRs carrying |
|
@franciscojavierarceo @ntkathole The one red check is |
Follow-up to feast-dev#6683, requested in its review. Add jwksCacheLifespanSeconds and jwksRequestTimeoutSeconds to OidcAuthz as CR fields rather than OIDC Secret keys: these are non-secret operational knobs, so they belong with verifySSL and caCertConfigMap rather than in the Secret bag that carries IdP-coupled credentials. Both are optional pointers with a Minimum=1 constraint mirroring the SDK's validation, and are omitted from the generated feature_store.yaml when unset so the SDK defaults apply rather than the operator asserting its own. Regenerates deepcopy, CRD bases, dist/install.yaml, and the API reference. Documents that the cache lifespan is not purely a performance setting: it also bounds how long a key the provider revoked keeps validating tokens. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com>
Code review findings on the JWKS tunables change. The OLM bundle CRD was not regenerated, so it lacked both new fields while config/crd/bases and dist/install.yaml carried them. Every other OidcAuthz field is present in all three copies, and no PR workflow runs make bundle, so CI would not have caught it: an OLM install would have pruned the settings silently rather than failing. Regenerated with make bundle; operator-sdk bundle validate passes. Assert the client repo config omits both keys. OidcClientAuthConfig inherits the same strict validation, so mirroring the forwarding into the client path would break every client pod, and nothing tested it. Also restore the neighbouring blocks' length assertion so a leaked parameter fails. Add CRD validation tests for the Minimum=1 constraints the docs promise. Docs: caCertConfigMap was documented as a bare string but the CRD requires an object with a name key, so the whole snippet failed to apply, including the lines added here. Name the required Feast version instead of implying any newer image works. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com>
The CRD serves v1alpha1 alongside v1 with no conversion webhook, so a resource submitted as v1alpha1 is validated against the v1alpha1 schema and any field outside it is pruned without error. Under v1alpha1, authz.oidc accepts only secretRef, so every other option is silently dropped. This predates the JWKS settings: v1alpha1 has never carried issuerUrl, secretKeyName, tokenEnvVar, verifySSL or caCertConfigMap either, all of which landed v1-only in 7c04026. Documenting the whole section rather than the two new fields keeps the guidance consistent with that. The v1alpha1 schema already enforces this - the fields cannot be expressed there - so no validation change is needed, only the missing warning. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com>
262f1ad to
b2609bb
Compare
) * feat: Expose the OIDC JWKS tunables through the operator Follow-up to feast-dev#6683, requested in its review. Add jwksCacheLifespanSeconds and jwksRequestTimeoutSeconds to OidcAuthz as CR fields rather than OIDC Secret keys: these are non-secret operational knobs, so they belong with verifySSL and caCertConfigMap rather than in the Secret bag that carries IdP-coupled credentials. Both are optional pointers with a Minimum=1 constraint mirroring the SDK's validation, and are omitted from the generated feature_store.yaml when unset so the SDK defaults apply rather than the operator asserting its own. Regenerates deepcopy, CRD bases, dist/install.yaml, and the API reference. Documents that the cache lifespan is not purely a performance setting: it also bounds how long a key the provider revoked keeps validating tokens. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> * fix: Regenerate the OLM bundle and close review gaps Code review findings on the JWKS tunables change. The OLM bundle CRD was not regenerated, so it lacked both new fields while config/crd/bases and dist/install.yaml carried them. Every other OidcAuthz field is present in all three copies, and no PR workflow runs make bundle, so CI would not have caught it: an OLM install would have pruned the settings silently rather than failing. Regenerated with make bundle; operator-sdk bundle validate passes. Assert the client repo config omits both keys. OidcClientAuthConfig inherits the same strict validation, so mirroring the forwarding into the client path would break every client pod, and nothing tested it. Also restore the neighbouring blocks' length assertion so a leaked parameter fails. Add CRD validation tests for the Minimum=1 constraints the docs promise. Docs: caCertConfigMap was documented as a bare string but the CRD requires an object with a name key, so the whole snippet failed to apply, including the lines added here. Name the required Feast version instead of implying any newer image works. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> * docs: State that the OIDC authz options require apiVersion v1 The CRD serves v1alpha1 alongside v1 with no conversion webhook, so a resource submitted as v1alpha1 is validated against the v1alpha1 schema and any field outside it is pruned without error. Under v1alpha1, authz.oidc accepts only secretRef, so every other option is silently dropped. This predates the JWKS settings: v1alpha1 has never carried issuerUrl, secretKeyName, tokenEnvVar, verifySSL or caCertConfigMap either, all of which landed v1-only in 7c04026. Documenting the whole section rather than the two new fields keeps the guidance consistent with that. The v1alpha1 schema already enforces this - the fields cannot be expressed there - so no validation change is needed, only the missing warning. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> --------- Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com>
# [0.66.0](v0.65.0...v0.66.0) (2026-08-21) ### Bug Fixes * Add connection pre-warming for DynamoDB async client ([89240fa](89240fa)), closes [#6060](#6060) * Add remote registry client extra ([#6697](#6697)) ([b8dfcb0](b8dfcb0)) * Address review feedback on FIPS cipher suite configuration ([4a35fba](4a35fba)) * Allow remote-registry first apply for new projects ([39d408d](39d408d)) * Avoid importing feast.feature_store at mcp_server import time ([ddb2e9a](ddb2e9a)) * Bump pymssql to >=2.3.6 for macOS arm64 wheel support ([181eb35](181eb35)), closes [#5636](#5636) [#5193](#5193) [#5636](#5636) * Call ApplySavedDataset RPC instead of ApplyFeatureService in RemoteRegistry.apply_saved_dataset() ([934d341](934d341)) * Catch missing dbt parser dependency in dbt CLI commands ([#6534](#6534)) ([3c2ae3c](3c2ae3c)) * Default authentication to kubernetes auth ([6a4690a](6a4690a)) * Defer feature-freshness thread to post-fork to avoid Gunicorn deadlock ([#6648](#6648)) ([104ad10](104ad10)), closes [#6647](#6647) * Do not pass undeclared feature view columns to ODFV UDFs ([#6527](#6527)) ([75b9463](75b9463)) * downgrade mcp pin to 1.29.0 and fix CI lockfiles and unit tests ([98e5bca](98e5bca)), closes [#6706](#6706) * Feast apply silently ignoring ttl updates to None or timedelta(0) ([#6709](#6709)) ([97b0f25](97b0f25)), closes [#6703](#6703) * Fix mypy TorchTensor type alias error ([#6712](#6712)) ([34de6fa](34de6fa)), closes [#5563](#5563) * Fixed data source creation form gaps ([5d0f7d6](5d0f7d6)) * Handle parameterized and complex Trino types in type map ([326554d](326554d)) * Isolate default user permissions ([e37adbf](e37adbf)) * Isolate projection join key maps ([d1c709d](d1c709d)) * Map Postgres real to FLOAT instead of DOUBLE ([62db435](62db435)) * Merge shared ODFV source projections in feature resolution ([d269946](d269946)), closes [#6621](#6621) * More exhaustive athena types ([a9aaefc](a9aaefc)) * Normalize SQL registry read_path to the psycopg3 driver like path ([#6644](#6644)) ([996c6ea](996c6ea)), closes [#6643](#6643) * **operator:** add spec.services.onlineStore.disabled to opt out of the online store ([d81d4e3](d81d4e3)), closes [#6586](#6586) * Preinstall DuckDB delta extension for tests ([fd4d49d](fd4d49d)), closes [#6743](#6743) * Preserve event-time ordering within Redis online_write_batch ([40fb788](40fb788)), closes [#5163](#5163) * Prevent mutation of cached feature resolution results ([ea17419](ea17419)) * Remote feastRef FeatureStore fails first apply for a new feastProject ([9affee5](9affee5)) * Remove inert subjectaccessreviews and reorganize RBAC rules ([f771ea4](f771ea4)) * Report single-feature-view spark_application materialization success ([a9219d9](a9219d9)), closes [#6673](#6673) * Reset the global security manager after the permissions fixture ([7667215](7667215)) * Resolve kserve with pip --dry-run instead of installing it ([01da132](01da132)), closes [#6732](#6732) * Resolve write_to_offline_store feature view with a single registry lookup ([a42dc85](a42dc85)), closes [#4235](#4235) * Return False from __eq__ on cross-type comparison ([#6637](#6637)) ([0f149a9](0f149a9)), closes [#6636](#6636) * Reuse IdP-issued client tokens until near expiry ([602d752](602d752)) * Reuse the OIDC JWKS client across requests ([#6683](#6683)) ([a1e6fc2](a1e6fc2)) * Separate CronJob and feature-server ServiceAccounts ([398f643](398f643)) * Serialize UnixTimestamp proto values as raw int64 in remote online store transport ([1e7134f](1e7134f)) * Set FIPS cipher suites before pyarrow.flight import to prevent crash on IBM Power ([979b82a](979b82a)) * Support Entra ID (Azure AD) token claims in OIDC auth ([#6631](#6631)) ([f843c63](f843c63)) * UDF/ODFV source rehydrate (+ Postgres / online cache) ([#6655](#6655)) ([5fd7af7](5fd7af7)) * Updated projects-list.json in order to display newly added projects ([#6657](#6657)) ([3a6a103](3a6a103)) * Use correct image name in multi-arch imagetools push step ([faf85e0](faf85e0)) * Use join keys instead of entity names in ODFV materialization ([#6645](#6645)) ([abffebc](abffebc)), closes [#5965](#5965) * use matching proto class per feature view list in SqliteOnlineStore.plan() ([adb8c1c](adb8c1c)), closes [#6658](#6658) * Widen Athena integer type mapping for unsigned ints ([3425783](3425783)) ### Features * Add ConnectionRef to DataSource for pluggable external credential resolution ([28bde01](28bde01)) * Add Feature Service Create in UI ([0399380](0399380)) * Add hybrid to ValidOfflineStoreDBStorePersistenceTypes for HybridOfflineStore support ([#6707](#6707)) ([310ab51](310ab51)), closes [#6701](#6701) * Add MLflow integration support to Feast operator ([#6611](#6611)) ([52999f1](52999f1)) * Add opt-in filter_by_created_timestamp cutoff to get_historical_features ([#6617](#6617)) ([79b33ce](79b33ce)), closes [#6615](#6615) * Add optional OIDC token audience and issuer verification ([#6670](#6670)) ([ef307c6](ef307c6)) * Add packaged feature repository support to Feast Operator ([8112b1e](8112b1e)), closes [#6598](#6598) * add plan() support to DynamoDBOnlineStore ([51ce982](51ce982)), closes [#6658](#6658) [#6659](#6659) * Added optional namespace/colleciton to datasets ([165fcf2](165fcf2)) * Added SQL registry schema_mode and registry create command ([#6704](#6704)) ([037c4cd](037c4cd)) * Allow users to have protected project on shared registry ([f9923bc](f9923bc)) * Apply Intermediate TLS defaults on API fallback and handle transient errors ([#6587](#6587)) ([43ae993](43ae993)) * **cli:** Updated feast init demo by adding rag template ([#5946](#5946)) ([c8628eb](c8628eb)), closes [#5264](#5264) * Expose the OIDC JWKS tunables through the operator ([#6690](#6690)) ([fef4e78](fef4e78)), closes [#6683](#6683) * Making feast vector store with open ai search api compatible ([#6121](#6121)) ([54da19a](54da19a)) * Multi-arch publish for feast operator image ([b221036](b221036)) * OpenLineage lineage enhancements - full object coverage, richer UI, and API-level sync ([#6719](#6719)) ([120a868](120a868)) * **operator:** Add spec.services.initImage for init container image override ([#6598](#6598)) ([ca355cb](ca355cb)) * Pass optional OIDC audience and issuer through the operator ([#6677](#6677)) ([a13ed7b](a13ed7b)), closes [#6670](#6670) * **server:** Remote Materialization ([#6649](#6649)) ([b7ae488](b7ae488)), closes [#4526](#4526) * Support Lineage configs via operator ([bf1e54a](bf1e54a)) * Updated datasets UI to support grouping ([7ae64ec](7ae64ec))
) * feat: Expose the OIDC JWKS tunables through the operator Follow-up to feast-dev#6683, requested in its review. Add jwksCacheLifespanSeconds and jwksRequestTimeoutSeconds to OidcAuthz as CR fields rather than OIDC Secret keys: these are non-secret operational knobs, so they belong with verifySSL and caCertConfigMap rather than in the Secret bag that carries IdP-coupled credentials. Both are optional pointers with a Minimum=1 constraint mirroring the SDK's validation, and are omitted from the generated feature_store.yaml when unset so the SDK defaults apply rather than the operator asserting its own. Regenerates deepcopy, CRD bases, dist/install.yaml, and the API reference. Documents that the cache lifespan is not purely a performance setting: it also bounds how long a key the provider revoked keeps validating tokens. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> * fix: Regenerate the OLM bundle and close review gaps Code review findings on the JWKS tunables change. The OLM bundle CRD was not regenerated, so it lacked both new fields while config/crd/bases and dist/install.yaml carried them. Every other OidcAuthz field is present in all three copies, and no PR workflow runs make bundle, so CI would not have caught it: an OLM install would have pruned the settings silently rather than failing. Regenerated with make bundle; operator-sdk bundle validate passes. Assert the client repo config omits both keys. OidcClientAuthConfig inherits the same strict validation, so mirroring the forwarding into the client path would break every client pod, and nothing tested it. Also restore the neighbouring blocks' length assertion so a leaked parameter fails. Add CRD validation tests for the Minimum=1 constraints the docs promise. Docs: caCertConfigMap was documented as a bare string but the CRD requires an object with a name key, so the whole snippet failed to apply, including the lines added here. Name the required Feast version instead of implying any newer image works. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> * docs: State that the OIDC authz options require apiVersion v1 The CRD serves v1alpha1 alongside v1 with no conversion webhook, so a resource submitted as v1alpha1 is validated against the v1alpha1 schema and any field outside it is pruned without error. Under v1alpha1, authz.oidc accepts only secretRef, so every other option is silently dropped. This predates the JWKS settings: v1alpha1 has never carried issuerUrl, secretKeyName, tokenEnvVar, verifySSL or caCertConfigMap either, all of which landed v1-only in 7c04026. Documenting the whole section rather than the two new fields keeps the guidance consistent with that. The v1alpha1 schema already enforces this - the fields cannot be expressed there - so no validation change is needed, only the missing warning. Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com> --------- Signed-off-by: Larry Singleton <166439969+larrysingleton007@users.noreply.github.com>
What this PR does / why we need it
Follow-up to #6683, which you asked for in that review. #6683 added
jwks_cache_lifespan_secondsandjwks_request_timeout_secondstoOidcAuthConfig; this exposes them through the operator so they are reachable from a FeatureStore CR.They are added as CR fields on
OidcAuthzrather than OIDC Secret keys, because they are non-secret operational knobs and belong withverifySSLandcaCertConfigMaprather than in the Secret that carries IdP credentials. Wiring follows the existingVerifySSLpattern.Both are optional pointers with a
Minimum=1constraint mirroring the SDK's validation, and both are omitted from the generatedfeature_store.yamlwhen unset so the SDK's own defaults apply rather than the operator asserting a competing set.Worth flagging for review:
jwksCacheLifespanSecondsis not purely a performance setting. It also bounds how long a key the provider has revoked continues to validate tokens, so the docs describe that tradeoff rather than presenting it as a throughput dial.Regenerated artifacts: deepcopy, CRD bases,
dist/install.yaml, the API reference, and the OLM bundle. The bundle is a separatemake bundlestep thatmake manifestsdoes not cover and no PR workflow runs, so it is easy to miss; without it an OLM install silently prunes the new fields rather than failing.Testing: unit coverage asserts the keys are absent when unset and forwarded with correct values when set, plus that the client config omits them (it inherits the same strict validation). CRD validation tests cover the
Minimum=1constraints.go build ./...,gofmt, and all four operator test packages pass.One docs fix included: the
caCertConfigMapexample in the same block was written as a bare string, but the CRD requires an object with anamekey, so that snippet failed to apply as written.Which issue(s) this PR fixes
Fixes #6686