[ 
https://issues.apache.org/jira/browse/KNOX-3449?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sandor Molnar updated KNOX-3449:
--------------------------------
    Description: 
*Description*

Stand up the CI harness that lets our Docker E2E suite treat the throwaway k3s 
cluster as a trusted OIDC issuer, and add all delegation/token-exchange tests 
that pass against the currently-merged backend. 

The base compose stack already runs k3s + a bootstrap job for the SPIFFE-header 
ServiceAccountValidator path, but that trust is fabric8/kubeconfig-based and 
unrelated to JWT/JWKS verification. Nothing today lets Knox fetch and trust the 
k3s OIDC JWKS, and no topology exposes the KNOXIDF_ADMIN API. This ticket 
builds that wiring and proves the token-exchange path end-to-end on real 
projected ServiceAccount tokens.

*Scope*

+In scope+
 * New compose overlay 
.github/workflows/compose/docker-compose.k8s-delegation.yml + a label-gated CI 
job in tests.yml (pattern: the existing knoxidf-federation / hashicorp-vault 
overlays).

 * Extend the k8s bootstrap so k3s issues SA tokens with a reachable issuer 
(service-account-issuer=[https://k3s:6443),] grant anonymous access to the OIDC 
discovery/JWKS endpoints (system:service-account-issuer-discovery → 
system:unauthenticated), and export the cluster CA cert + issuer URL + a 
freshly-minted projected SA token to the shared k3s-output volume.

 * Custom Knox entrypoint (mounted via the overlay, mirroring 
gateway-single-eku.sh) that imports the k3s CA into the JVM cacerts before 
starting the gateway — required because JWKS verification (Nimbus) and OIDC 
discovery both use the JVM default trust store, not 
gateway.httpclient.truststore.*.

 * New topology knoxidf-admin.xml declaring <role>KNOXIDF_ADMIN</role> behind 
ShiroProvider (basic auth) + AclsAuthz (admin-only). Reuse the existing 
knoxidf-token.xml (JWTProvider → KNOXIDF) for the exchange call.

 * New test file .github/workflows/tests/test_k8s_delegation.py covering the 
acceptance criteria below.

+Out of scope+
 * Actor-token delegation with policy enforcement (AC4) and headless 
requested_subject exchange (AC5) — blocked on backend work, tracked separately.

 * Any backend/Java changes — this ticket is harness + tests only.

*Acceptance criteria*
 * (AC1) test_k8s_delegation.py runs in CI under the new k8s delegation compose 
overlay.

 * (AC8) The bootstrap exports the k3s CA cert and issuer URL to the shared 
volume; Knox trusts the JWKS endpoint and tests can register the issuer.

 * (AC2) A setup-validation step decodes the minted SA token and asserts the 
typ JOSE header is absent (documents why the permissive verifier / KNOX-3434 is 
needed).

 * (AC9) TrustedOIDCIssuers admin API works over the wire: register (POST 
.../knoxidf/admin/v1/trusted-oidc-issuers), list (GET), refresh JWKS (POST 
.../refresh-jwks?issuerUrl=), remove (DELETE ?issuerUrl=) — with list 
assertions before/after.

 * (AC3) A same-subject exchange 
(grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_token = 
k3s projected SA token, no actor_token) succeeds with HTTP 200 after the issuer 
is registered.

 * (AC6) An exchange whose subject_token carries an unregistered issuer is 
rejected with HTTP 401 invalid_request (and no outbound JWKS fetch).

 * (AC7) An exchange whose subject_token has a past exp is rejected with HTTP 
401 "Token has expired".

*Technical notes*
 * Exchange endpoint: POST 
[https://knox:8443/gateway/knoxidf-token/knoxidf/api/v1/token.] The 
KNOXIDF_ADMIN/KNOXIDF roles auto-select the H2-backed TrustedOidcIssuerService 
(self-provisions under securityDir/h2db) — no DB stand-up or extra config 
needed.

 * Register body: 
\{"issuerUrl":"[https://k3s:6443|https://k3s:6443/]","dynamicJwks":true,"clusterName":"k3s"}.
 issuerUrl must be HTTPS or registration 400s. Leave 
knox.token.exchange.dynamic.jwks.allow.http unset (k3s JWKS is HTTPS).

 * The SA token's iss must equal the registered issuerUrl and be reachable for 
discovery; hence setting 
service-account-issuer=[https://k3s:6443|https://k3s:6443/] (the --tls-san=k3s 
cert already covers that host).

 * AC6/AC7 can use hand-crafted JWTs — expiry and issuer-trust are checked 
before signature verification, so no k3s signing key is required. Add PyJWT to 
requirements.txt or build the token manually.

 * The tests service must mount k3s-output (read-only) to read the exported SA 
token + CA; it currently does not.

  was:
*Description*

Stand up the CI harness that lets our Docker E2E suite treat the throwaway k3s 
cluster as a trusted OIDC issuer, and add all delegation/token-exchange tests 
that pass against the currently-merged backend. This is the "ready now" half of 
KNOX-3238; the policy-enforced delegation and headless-exchange tests are split 
into a separate, blocked sub-task (see Dependencies).

The base compose stack already runs k3s + a bootstrap job for the SPIFFE-header 
ServiceAccountValidator path, but that trust is fabric8/kubeconfig-based and 
unrelated to JWT/JWKS verification. Nothing today lets Knox fetch and trust the 
k3s OIDC JWKS, and no topology exposes the KNOXIDF_ADMIN API. This ticket 
builds that wiring and proves the token-exchange path end-to-end on real 
projected ServiceAccount tokens.

*Scope*

+In scope+
 * New compose overlay 
.github/workflows/compose/docker-compose.k8s-delegation.yml + a label-gated CI 
job in tests.yml (pattern: the existing knoxidf-federation / hashicorp-vault 
overlays).

 * Extend the k8s bootstrap so k3s issues SA tokens with a reachable issuer 
(service-account-issuer=[https://k3s:6443),] grant anonymous access to the OIDC 
discovery/JWKS endpoints (system:service-account-issuer-discovery → 
system:unauthenticated), and export the cluster CA cert + issuer URL + a 
freshly-minted projected SA token to the shared k3s-output volume.

 * Custom Knox entrypoint (mounted via the overlay, mirroring 
gateway-single-eku.sh) that imports the k3s CA into the JVM cacerts before 
starting the gateway — required because JWKS verification (Nimbus) and OIDC 
discovery both use the JVM default trust store, not 
gateway.httpclient.truststore.*.

 * New topology knoxidf-admin.xml declaring <role>KNOXIDF_ADMIN</role> behind 
ShiroProvider (basic auth) + AclsAuthz (admin-only). Reuse the existing 
knoxidf-token.xml (JWTProvider → KNOXIDF) for the exchange call.

 * New test file .github/workflows/tests/test_k8s_delegation.py covering the 
acceptance criteria below.

+Out of scope+
 * Actor-token delegation with policy enforcement (AC4) and headless 
requested_subject exchange (AC5) — blocked on backend work, tracked separately.

 * Any backend/Java changes — this ticket is harness + tests only.

*Acceptance criteria*
 * (AC1) test_k8s_delegation.py runs in CI under the new k8s delegation compose 
overlay.

 * (AC8) The bootstrap exports the k3s CA cert and issuer URL to the shared 
volume; Knox trusts the JWKS endpoint and tests can register the issuer.

 * (AC2) A setup-validation step decodes the minted SA token and asserts the 
typ JOSE header is absent (documents why the permissive verifier / KNOX-3434 is 
needed).

 * (AC9) TrustedOIDCIssuers admin API works over the wire: register (POST 
.../knoxidf/admin/v1/trusted-oidc-issuers), list (GET), refresh JWKS (POST 
.../refresh-jwks?issuerUrl=), remove (DELETE ?issuerUrl=) — with list 
assertions before/after.

 * (AC3) A same-subject exchange 
(grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_token = 
k3s projected SA token, no actor_token) succeeds with HTTP 200 after the issuer 
is registered.

 * (AC6) An exchange whose subject_token carries an unregistered issuer is 
rejected with HTTP 401 invalid_request (and no outbound JWKS fetch).

 * (AC7) An exchange whose subject_token has a past exp is rejected with HTTP 
401 "Token has expired".

*Technical notes*
 * Exchange endpoint: POST 
[https://knox:8443/gateway/knoxidf-token/knoxidf/api/v1/token.] The 
KNOXIDF_ADMIN/KNOXIDF roles auto-select the H2-backed TrustedOidcIssuerService 
(self-provisions under securityDir/h2db) — no DB stand-up or extra config 
needed.

 * Register body: 
{"issuerUrl":"[https://k3s:6443|https://k3s:6443/]","dynamicJwks":true,"clusterName":"k3s"}.
 issuerUrl must be HTTPS or registration 400s. Leave 
knox.token.exchange.dynamic.jwks.allow.http unset (k3s JWKS is HTTPS).

 * The SA token's iss must equal the registered issuerUrl and be reachable for 
discovery; hence setting 
service-account-issuer=[https://k3s:6443|https://k3s:6443/] (the --tls-san=k3s 
cert already covers that host).

 * AC6/AC7 can use hand-crafted JWTs — expiry and issuer-trust are checked 
before signature verification, so no k3s signing key is required. Add PyJWT to 
requirements.txt or build the token manually.

 * The tests service must mount k3s-output (read-only) to read the exported SA 
token + CA; it currently does not.


> k8s delegation E2E: CI harness + same-subject exchange, TrustedOIDCIssuers 
> admin API, and negative-path coverage
> ----------------------------------------------------------------------------------------------------------------
>
>                 Key: KNOX-3449
>                 URL: https://issues.apache.org/jira/browse/KNOX-3449
>             Project: Apache Knox
>          Issue Type: Task
>          Components: CI
>    Affects Versions: 3.1.0
>            Reporter: Sandor Molnar
>            Assignee: Sandor Molnar
>            Priority: Major
>             Fix For: 3.1.0
>
>
> *Description*
> Stand up the CI harness that lets our Docker E2E suite treat the throwaway 
> k3s cluster as a trusted OIDC issuer, and add all delegation/token-exchange 
> tests that pass against the currently-merged backend. 
> The base compose stack already runs k3s + a bootstrap job for the 
> SPIFFE-header ServiceAccountValidator path, but that trust is 
> fabric8/kubeconfig-based and unrelated to JWT/JWKS verification. Nothing 
> today lets Knox fetch and trust the k3s OIDC JWKS, and no topology exposes 
> the KNOXIDF_ADMIN API. This ticket builds that wiring and proves the 
> token-exchange path end-to-end on real projected ServiceAccount tokens.
> *Scope*
> +In scope+
>  * New compose overlay 
> .github/workflows/compose/docker-compose.k8s-delegation.yml + a label-gated 
> CI job in tests.yml (pattern: the existing knoxidf-federation / 
> hashicorp-vault overlays).
>  * Extend the k8s bootstrap so k3s issues SA tokens with a reachable issuer 
> (service-account-issuer=[https://k3s:6443),] grant anonymous access to the 
> OIDC discovery/JWKS endpoints (system:service-account-issuer-discovery → 
> system:unauthenticated), and export the cluster CA cert + issuer URL + a 
> freshly-minted projected SA token to the shared k3s-output volume.
>  * Custom Knox entrypoint (mounted via the overlay, mirroring 
> gateway-single-eku.sh) that imports the k3s CA into the JVM cacerts before 
> starting the gateway — required because JWKS verification (Nimbus) and OIDC 
> discovery both use the JVM default trust store, not 
> gateway.httpclient.truststore.*.
>  * New topology knoxidf-admin.xml declaring <role>KNOXIDF_ADMIN</role> behind 
> ShiroProvider (basic auth) + AclsAuthz (admin-only). Reuse the existing 
> knoxidf-token.xml (JWTProvider → KNOXIDF) for the exchange call.
>  * New test file .github/workflows/tests/test_k8s_delegation.py covering the 
> acceptance criteria below.
> +Out of scope+
>  * Actor-token delegation with policy enforcement (AC4) and headless 
> requested_subject exchange (AC5) — blocked on backend work, tracked 
> separately.
>  * Any backend/Java changes — this ticket is harness + tests only.
> *Acceptance criteria*
>  * (AC1) test_k8s_delegation.py runs in CI under the new k8s delegation 
> compose overlay.
>  * (AC8) The bootstrap exports the k3s CA cert and issuer URL to the shared 
> volume; Knox trusts the JWKS endpoint and tests can register the issuer.
>  * (AC2) A setup-validation step decodes the minted SA token and asserts the 
> typ JOSE header is absent (documents why the permissive verifier / KNOX-3434 
> is needed).
>  * (AC9) TrustedOIDCIssuers admin API works over the wire: register (POST 
> .../knoxidf/admin/v1/trusted-oidc-issuers), list (GET), refresh JWKS (POST 
> .../refresh-jwks?issuerUrl=), remove (DELETE ?issuerUrl=) — with list 
> assertions before/after.
>  * (AC3) A same-subject exchange 
> (grant_type=urn:ietf:params:oauth:grant-type:token-exchange, subject_token = 
> k3s projected SA token, no actor_token) succeeds with HTTP 200 after the 
> issuer is registered.
>  * (AC6) An exchange whose subject_token carries an unregistered issuer is 
> rejected with HTTP 401 invalid_request (and no outbound JWKS fetch).
>  * (AC7) An exchange whose subject_token has a past exp is rejected with HTTP 
> 401 "Token has expired".
> *Technical notes*
>  * Exchange endpoint: POST 
> [https://knox:8443/gateway/knoxidf-token/knoxidf/api/v1/token.] The 
> KNOXIDF_ADMIN/KNOXIDF roles auto-select the H2-backed 
> TrustedOidcIssuerService (self-provisions under securityDir/h2db) — no DB 
> stand-up or extra config needed.
>  * Register body: 
> \{"issuerUrl":"[https://k3s:6443|https://k3s:6443/]","dynamicJwks":true,"clusterName":"k3s"}.
>  issuerUrl must be HTTPS or registration 400s. Leave 
> knox.token.exchange.dynamic.jwks.allow.http unset (k3s JWKS is HTTPS).
>  * The SA token's iss must equal the registered issuerUrl and be reachable 
> for discovery; hence setting 
> service-account-issuer=[https://k3s:6443|https://k3s:6443/] (the 
> --tls-san=k3s cert already covers that host).
>  * AC6/AC7 can use hand-crafted JWTs — expiry and issuer-trust are checked 
> before signature verification, so no k3s signing key is required. Add PyJWT 
> to requirements.txt or build the token manually.
>  * The tests service must mount k3s-output (read-only) to read the exported 
> SA token + CA; it currently does not.



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

Reply via email to