[ 
https://issues.apache.org/jira/browse/KNOX-3512?focusedWorklogId=1047418&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1047418
 ]

ASF GitHub Bot logged work on KNOX-3512:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 14/Oct/26 11:59
            Start Date: 14/Oct/26 11:59
    Worklog Time Spent: 10m 
      Work Description: smolnar82 merged PR #1451:
URL: https://github.com/apache/knox/pull/1451




Issue Time Tracking
-------------------

    Worklog Id:     (was: 1047418)
    Time Spent: 1h 20m  (was: 1h 10m)

> KnoxIDF: per-issuer CA bundle (jwksCa) for trusted OIDC issuer discovery and 
> JWKS fetches
> -----------------------------------------------------------------------------------------
>
>                 Key: KNOX-3512
>                 URL: https://issues.apache.org/jira/browse/KNOX-3512
>             Project: Apache Knox
>          Issue Type: Task
>          Components: JWT, Server
>    Affects Versions: 3.1.0
>            Reporter: Sandor Molnar
>            Assignee: Sandor Molnar
>            Priority: Major
>             Fix For: 3.1.0
>
>          Time Spent: 1h 20m
>  Remaining Estimate: 0h
>
> *Problem*
> Knox fetches each trusted OIDC issuer's discovery document and JWKS over 
> HTTPS using the global JVM/Knox truststore. Kubernetes apiservers acting as 
> issuers often use self-signed certificates, each with its own CA. Today the 
> only way to trust them is to import every CA into the global truststore at 
> startup. That has two costs:
>  - Every CA rotation needs a restart.
>  - Trust widens for all TLS clients in Knox (LDAP and the rest).
> TrustedOidcIssuer has no way to carry a CA.
> *Proposal*
> Add an optional {{jwksCa}} field to trusted OIDC issuer registrations. It 
> takes one of two forms:
>  - Inline PEM: one or more {{---{-}{{-}}BEGIN CERTIFICATE{{-}}{-}---}} blocks.
>  - Kubernetes Secret reference: {{{}secret:[<namespace>/]<name>#<key>{}}}. 
> Namespace defaults to "knox", the other 2 parts are required. Knox reads it 
> through the in-cluster Kubernetes API.
> +Behaviour:+
>  - When {{jwksCa}} is set, that issuer's discovery and JWKS TLS connections 
> trust only the given bundle, and hostname verification stays on. The global 
> truststore is never changed, so other TLS clients in Knox do not trust the 
> issuer CA.
>  - When {{jwksCa}} is not set, nothing changes.
>  - {{jwksCa}} is only accepted together with {{{}dynamicJwks: true{}}}.
>  - If {{jwksCa}} is configured but cannot be loaded (Secret or key missing, 
> unparsable PEM), verification fails closed and does not fall back to the 
> global truststore.
>  - CA changes take effect without a restart:
>  -- Inline: re-registering the issuer replaces its trust material straight 
> away.
>  -- Secret reference: Knox reads the Secret lazily, with no background 
> refresh. It reads it:
>  --- on the first discovery or JWKS fetch for the issuer.
>  --- on access, when the cached CA is older than 
> {{gateway.trusted.oidc.issuer.ca.secret.max.age.secs}} (default 
> {{{}1800{}}}). This picks up CAs removed from the bundle.
>  --- after a fetch fails with a TLS trust error (handshake or certificate 
> validation). Knox re-reads the Secret and retries once, at most once every 
> 30s per issuer. Timeouts and non-200 responses don't trigger a re-read.
>  --- on {{{}POST /trusted-oidc-issuers/refresh-jwks{}}}, which drops the 
> cached CA so the next fetch reads it again.
>  -- If the Secret can't be read the first time, verification fails closed. If 
> a max-age re-read fails, Knox keeps the last working CA and logs the failure.
>  - Rotating the issuer's signing key still needs no config change. When a 
> token's kid is not in the cached JWKS, the JWKS is fetched again.
> *Changes*
>  - {{{}TrustedOidcIssuer{}}}, {{RegisterIssuerRequest}} and the admin REST 
> resource get the new jwksCa field. Registration validates it and returns 400 
> invalid_request when:
>  -- it is set but dynamicJwks is false
>  -- it is too long
>  -- a secret: value has the wrong syntax
>  -- inline PEM does not parse
>  - {{TRUSTED_OIDC_ISSUERS}} table: new {{jwks_ca}} column ({{{}TEXT{}}}, or 
> {{CLOB}} on Oracle).
>  - {{TrustedOidcIssuerService}} exposes per-issuer TLS trust. It is used by 
> OIDC discovery (Apache HttpClient) and by the JWKS fetch (Nimbus 
> {{DefaultResourceRetriever}} with a per-issuer {{{}SSLSocketFactory{}}}).
>  - JWTokenAuthority gets an overload of verifyToken that takes the JWKS 
> SSLSocketFactory.
>  - Docs: new field, config properties and RBAC requirements. Also a 
> shared-root option: if every cluster chains to one root CA, use the same 
> bundle or Secret for every issuer.
> Acceptance criteria
>  - Issuers with different self-signed CAs all validate.
>  - Replacing an issuer's CA bundle (inline or Secret) takes effect without a 
> Knox restart.
>  - An unrelated TLS client in Knox does not trust the issuer CA.
>  - Rotating an apiserver signing key needs no Knox config change.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to