smolnar82 opened a new pull request, #1414:
URL: https://github.com/apache/knox/pull/1414

   [KNOX-3475](https://issues.apache.org/jira/browse/KNOX-3475) - Enforce 
delegation policy `status` at authorization time
   
   ## What changes were proposed in this pull request?
   
   A KnoxIDF delegation policy (RFC 8693 token exchange) carries a `status` 
field (`active` / `revoked`). The status was validated at the REST layer and 
stored, but **never read at authorization time**: 
`JdbcDelegationPolicyService.evaluate(...)` looked the policy up by actor and 
then checked headless/user/group/resource/scope, never the status. So a policy 
that was *revoked instead of deleted* (its row still present with 
`status="revoked"`) kept authorizing exchanges.
   
   This PR closes that gap:
   
   - **`gateway-spi` `DelegationPolicy`** — add canonical 
`STATUS_ACTIVE`/`STATUS_REVOKED` constants and an `isActive()` helper (true 
only for exactly `"active"`; revoked, null, or any unknown value is treated as 
not-active — fail-safe).
   - **`gateway-server` `JdbcDelegationPolicyService.evaluate()`** — new **Step 
1.5** immediately after the actor lookup: `if (!policy.isActive()) return 
deny("policy_not_active")`. It short-circuits before any 
user/group/resource/scope check, so a revoked-but-present policy can never 
authorize. `H2DBDelegationPolicyService` (the embedded-H2 backend that runs in 
production) inherits `evaluate()` and therefore the check.
   - **`gateway-service-knoxidf` `DelegationPolicyRequest`** — point its status 
constants at the SPI ones (single source of truth; no behavior change).
   
   Client-facing effect: a revoked actor's delegation exchange is rejected as 
every other policy denial is — `400 invalid_request` / "The token exchange 
request is rejected by policy".
   
   ## How was this patch tested?
   
   Automated unit tests (all green):
   
   - `DelegationPolicyTest.isActiveOnlyForExactlyActiveStatus` — `active` → 
true; `revoked`, `null`, and an unknown value → false.
   - `JdbcDelegationPolicyServiceTest`:
     - `testEvaluateDenyRevokedPolicy` — a registered `revoked` policy denies 
with `policy_not_active` and `effectiveTtlSec== 0`.
     - `testEvaluateDenyAfterPolicyUpdatedToRevoked` — the exact JIRA scenario: 
an `active` policy authorizes, then the **same record** is updated to `revoked` 
→ denied.
   - `H2DBDelegationPolicyServiceTest.shouldDenyEvaluateWhenPolicyRevoked` — 
proves the inherited check fires on the embedded-H2 subclass used in production.
   
   Run with `mvn -pl gateway-spi,gateway-server,gateway-service-knoxidf test` 
(build/install `gateway-spi` first, or use `-am`).
   
   ## Integration Tests
   
   Added 
`test_token_exchange.py::test_delegation_exchange_denied_after_policy_revoked` 
- the suite's first end-to-end happy-path delegation exchange. Via the 
`KNOXIDF_ADMIN` REST API (`knoxidf-admin` topology) it seeds an **active** 
`(USER, guest)` policy, proves the delegation exchange succeeds (200 + 
`access_token`), PUTs `status=revoked` on the **same record** (full-replace — 
the "revoked, not deleted" scenario), then replays the identical exchange (same 
tokens, same resource) and asserts it is now rejected with `400 
invalid_request` / "rejected by policy". No topology changes were needed: the 
policy store is a gateway-wide singleton, so a policy registered via 
`knoxidf-admin` is seen by the exchange on `knoxidf-token-delegation`.
   
   Full docker-compose suite:
   ```
   tests-1  | 
-------------------------------------------------------------------
   tests-1  | Your code has been rated at 10.00/10 (previous run: 9.97/10, 
+0.03)
   tests-1  | 
   tests-1  | Waiting for knox...
   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 92 items
   tests-1  | 
   tests-1  | test_health.py .....                                              
       [  5%]
   tests-1  | test_k8s_delegation.py ...                                        
       [  8%]
   tests-1  | test_k8s_serviceaccount_validation.py ......                      
       [ 15%]
   tests-1  | test_knox_admin_path_traversal.py ...                             
       [ 18%]
   tests-1  | test_knox_auth_service_and_ldap.py ...                            
       [ 21%]
   tests-1  | test_knox_configs.py .                                            
       [ 22%]
   tests-1  | test_knox_ldap_cache.py ...                                       
       [ 26%]
   tests-1  | test_knox_ldap_injection.py .......                               
       [ 33%]
   tests-1  | test_knox_ldap_proxy_search.py .........                          
       [ 43%]
   tests-1  | test_knoxauth_preauth_and_paths.py ......                         
       [ 50%]
   tests-1  | test_knoxidf.py ......                                            
       [ 56%]
   tests-1  | test_knoxsso_redirect.py .                                        
       [ 57%]
   tests-1  | test_knoxtoken_jwt.py ....................                        
       [ 79%]
   tests-1  | test_remote_auth.py ...                                           
       [ 82%]
   tests-1  | test_remoteauth_extauthz_additional_path.py ....                  
       [ 86%]
   tests-1  | test_token_exchange.py ............                               
       [100%]
   tests-1  | 
   tests-1  | =============================== warnings summary 
===============================
   ...
   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  | ======================= 92 passed, 84 warnings in 18.61s 
=======================
   tests-1 exited with code 0
   Aborting on container exit...
   Container compose-tests-1 Stopping 
   Container compose-tests-1 Stopped Config   w Enable Watch   d Detach
   ```
   
   ## UI changes
   
   N/A.


-- 
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]

Reply via email to