smolnar82 opened a new pull request, #1396: URL: https://github.com/apache/knox/pull/1396
[KNOX-3449](https://issues.apache.org/jira/browse/KNOX-3449) - Prove Knox accepts Kubernetes ServiceAccount tokens on the RFC 8693 token-exchange path (CI evidence) ## What changes were proposed in this pull request? This delivers the "ready-now" half of the k8s-delegation story: CI evidence that Knox accepts a real Kubernetes ServiceAccount projected token on the OAuth 2.0 Token Exchange path once its issuing cluster is registered as a trusted OIDC issuer, plus the fix that path needs to work under server-managed token state. Two commits: 1. CI test harness - folds a lightweight single-node k3s cluster into the main Compose test stack and turns it into a real OIDC issuer at `https://k3s:6443`. A one-shot bootstrap applies the SA fixtures, opens anonymous access to the OIDC discovery/JWKS endpoints, and exports a freshly minted projected token to a shared volume. Knox imports the k3s serving CA into the JVM cacerts on startup so it can fetch discovery/JWKS over HTTPS. New `test_k8s_delegation.py` covers: - AC2 — the exported token is a genuine k3s-issued JWT (permissive typ); - AC3 — same-subject exchange of the real SA token yields a Knox access token; - AC6 — a token from an unregistered issuer is rejected without a JWKS fetch; - AC7 — an expired token is rejected before signature verification; - AC8/AC9 — the full `TrustedOIDCIssuers` admin API lifecycle (register / list / conflict / refresh-jwks / remove). 2. Token-exchange fix - `AbstractJWTFilter` server-managed-state lookups are keyed by the Knox token id (the `knox.id` claim). An externally-issued token (e.g. a k8s SA token) has no knox.id, so `getTokenId` returns null; the previous code passed that `null` id to the state service, raising `IllegalArgumentException` (HTTP 500) on the expiration lookup and `UnknownTokenException` (spurious 401) on the metadata lookup. Both lookups now skip a null/empty id and fall back to the token's own exp/enabled defaults. The metadata guard is centralized in a single private `getTokenMetadata(tokenId)` helper used by all four call sites, so the guard can't be forgotten at a future site. ## How was this patch tested? - Unit — `mvn -pl gateway-provider-security-jwt` test: BUILD SUCCESS. Added `JWTFederationFilterTokenExchangeTest.testExternalSubjectTokenWithServerManagedStateSkipsStateLookup`, which injects a strict (no-expectation) TokenStateService mock and asserts the state service is never consulted for a token without knox.id; confirmed it fails without the guard. Updated CommonJWTFilterTest so its mock JWT carries a knox.id (its bare mock previously relied on the now-guarded null-id path). - Integration — full Compose suite via `docker compose -f ./.github/workflows/compose/docker-compose.yml up --exit-code-from tests tests` ``` tests-1 | ============================= test session starts ============================== tests-1 | platform linux -- Python 3.10.20, pytest-9.0.3, pluggy-1.6.0 tests-1 | rootdir: /tests tests-1 | collected 80 items tests-1 | tests-1 | test_health.py ..... [ 6%] tests-1 | test_k8s_delegation.py ... [ 10%] tests-1 | test_k8s_serviceaccount_validation.py ...... [ 17%] tests-1 | test_knox_admin_path_traversal.py ... [ 21%] tests-1 | test_knox_auth_service_and_ldap.py ... [ 25%] tests-1 | test_knox_configs.py . [ 26%] tests-1 | test_knox_ldap_cache.py ... [ 30%] tests-1 | test_knox_ldap_injection.py ....... [ 38%] tests-1 | test_knox_ldap_proxy_search.py ......... [ 50%] tests-1 | test_knoxauth_preauth_and_paths.py ...... [ 57%] tests-1 | test_knoxidf.py ...... [ 65%] tests-1 | test_knoxsso_redirect.py . [ 66%] tests-1 | test_knoxtoken_jwt.py .................... [ 91%] tests-1 | test_remote_auth.py ... [ 95%] tests-1 | test_remoteauth_extauthz_additional_path.py .... [100%] tests-1 | tests-1 | =============================== warnings summary =============================== tests-1 | ../usr/local/lib/python3.10/site-packages/ldap3/utils/asn1.py:50 tests-1 | /usr/local/lib/python3.10/site-packages/ldap3/utils/asn1.py:50: DeprecationWarning: tagMap is deprecated. Please use TAG_MAP instead. tests-1 | from pyasn1.codec.ber.encoder import tagMap, typeMap, AbstractItemEncoder tests-1 | tests-1 | ../usr/local/lib/python3.10/site-packages/ldap3/utils/asn1.py:50 tests-1 | /usr/local/lib/python3.10/site-packages/ldap3/utils/asn1.py:50: DeprecationWarning: typeMap is deprecated. Please use TYPE_MAP instead. tests-1 | from pyasn1.codec.ber.encoder import tagMap, typeMap, AbstractItemEncoder tests-1 | tests-1 | test_health.py: 5 warnings tests-1 | test_k8s_delegation.py: 2 warnings tests-1 | test_k8s_serviceaccount_validation.py: 6 warnings tests-1 | test_knox_admin_path_traversal.py: 3 warnings tests-1 | test_knox_auth_service_and_ldap.py: 3 warnings tests-1 | test_knox_configs.py: 1 warning tests-1 | test_knox_ldap_cache.py: 3 warnings tests-1 | test_knox_ldap_injection.py: 7 warnings tests-1 | test_knoxauth_preauth_and_paths.py: 6 warnings tests-1 | test_knoxidf.py: 6 warnings tests-1 | test_knoxsso_redirect.py: 1 warning tests-1 | test_knoxtoken_jwt.py: 20 warnings tests-1 | test_remote_auth.py: 3 warnings tests-1 | test_remoteauth_extauthz_additional_path.py: 4 warnings tests-1 | /usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py:1110: InsecureRequestWarning: Unverified HTTPS request is being made to host 'knox'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings tests-1 | warnings.warn( tests-1 | tests-1 | -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html tests-1 | ----------------- generated xml file: /tests/test-results.xml ------------------ tests-1 | ======================= 80 passed, 72 warnings in 13.80s ======================= ``` ## Integration Tests Added `.github/workflows/tests/test_k8s_delegation.py` (see above) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
