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

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

                Author: ASF GitHub Bot
            Created on: 06/Sep/26 17:41
            Start Date: 06/Sep/26 17:41
    Worklog Time Spent: 10m 
      Work Description: hsheinblatt opened a new pull request, #1379:
URL: https://github.com/apache/knox/pull/1379

   KNOX-3438: Add delegation policy admin API with upsert support for RFC 8693 
token exchange
   
   ## What changes were proposed in this pull request?
   
   Adds a REST admin API for managing RFC 8693 delegation policies on the 
KNOXIDF_ADMIN service
   under /knoxidf/admin/v1/delegation-policies. The new 
DelegationPolicyResource (gateway-service-
   knoxidf) exposes POST (register), GET (list or get-by-id), PUT 
/{registrationId} (full-replace
   update), PUT to the bare collection path (create-or-update / upsert), and 
DELETE. Three DTO
   classes accompany it - DelegationPolicyRequest, DelegationPolicyResponse, and
   DelegationPolicyListResponse - along with a 
DelegationPolicyDtoImmutabilityHelper that ensures
   defensive copies of Set and Map fields on both construction and getter 
access.
   Changes to common code and other services:
     gateway-util-common: adds ResourceType.DELEGATION_POLICY, used by audit 
records emitted from
     all three mutating endpoints (register, update, delete) in the same 
Action.DELEGATION_LIFECYCLE
     / try-finally pattern already used by TrustedOidcIssuersResource.
     gateway-server: extracts the private 
isUniqueConstraintViolation(SQLException) method from
     JdbcFederatedIdentityService into a new public static on JDBCUtils (the 
existing JDBC-utility
     class in org.apache.knox.gateway.database). JdbcFederatedIdentityService 
now delegates to the
     shared copy; its own private method is deleted. The extracted helper 
classifies a SQLException
     as a unique-constraint violation portably across Derby, MySQL, PostgreSQL, 
and Oracle via
     SQLState "23"-prefix matching rather than vendor-specific syntax.
     gateway-spi: adds two new exception types in the delegation package -
     DelegationPolicyAlreadyExistsException (thrown by register() on a 
duplicate actorAuthority /
     actorId pair) and DelegationPolicyNotFoundException (thrown by update() 
and delete() when the
     supplied registrationId does not exist). The DelegationPolicyService 
interface gains a new
     registerOrUpdate(DelegationPolicy) method returning RegisterOrUpdateResult 
(a small value type
     carrying the persisted policy and a boolean indicating whether the call 
created or replaced),
     and update() now returns DelegationPolicy instead of void. Two new config 
keys and getters are
     added to GatewayConfig / GatewayConfigImpl for configurable token TTL 
bounds:
     gateway.delegation.service.min.token.ttl.sec (default 60 s) and
     gateway.delegation.service.max.token.ttl.sec (default 86400 s).
   Service and database layer (gateway-server):
     DelegationPolicyDatabase.updatePolicy() and deletePolicy() now inspect the 
affected-row count
     returned by the core UPDATE and DELETE statements. A count of zero causes 
the transaction to be
     rolled back and the call to return false, which 
JdbcDelegationPolicyService converts into a
     DelegationPolicyNotFoundException. This replaces the previous silent no-op 
on a nonexistent
     registrationId.
     JdbcDelegationPolicyService.register() now wraps the database call in a 
specific SQLException
     catch block before the generic Exception catch. Inside it, 
JDBCUtils.isUniqueConstraintViolation
     is used to throw DelegationPolicyAlreadyExistsException on a genuine 
duplicate rather than a
     plain RuntimeException; non-duplicate SQLExceptions and all other 
exceptions still produce a
     plain RuntimeException.
     JdbcDelegationPolicyService.registerOrUpdate() composes the existing 
findByActor(),
     register(), and update() methods with exactly one bounded retry per race 
branch (concurrent
     delete between findByActor and update, or concurrent insert between 
findByActor and register).
     A second race on the same actor within the same call propagates the 
resulting
     DelegationPolicyNotFoundException or 
DelegationPolicyAlreadyExistsException to the caller
     unchanged. This design adds no new SQL and no new transaction boundary.  A 
database-level
     savepoint-based upsert was considered and rejected: savepoint semantics 
differ across the
     databases supported in knox in ways that are non-trivial to handle 
portably.
   Path ACLs and coexistence with TrustedOidcIssuersResource:
     DelegationPolicyResource is a sibling of TrustedOidcIssuersResource inside 
the same KNOXIDF_ADMIN
     role. Both are served by KnoxIDFAdminServiceDeploymentContributor's 
existing Jersey package
     scan and "knoxidf/admin/**" URL pattern - no deployment-contributor 
changes are required. The
     two resources share the same base path prefix (knoxidf/admin/v1/) but have 
distinct final
     segments (trusted-oidc-issuers vs. delegation-policies), which lets 
operators assign independent
     PathAclsAuthz rules to each, for example:
   ```
       <param>
         <name>KNOXIDF_ADMIN.rule_issuers.path.acl</name>
         
<value>https://*:*/**/knoxidf/admin/v1/trusted-oidc-issuers**;awc-svc;issuer-admins;*</value>
       </param>
       <param>
         <name>KNOXIDF_ADMIN.rule_delegation.path.acl</name>
         
<value>https://*:*/**/knoxidf/admin/v1/delegation-policies**;knox-operator;delegation-admins;*</value>
       </param>
   ```  
   This means the two admin APIs can be administered by separate groups (or the 
same group) with
     no change to PathAclsAuthorizationFilter or PathAclParser. PathAclsAuthz 
is what actually gates
     access to both resources; the resource layer itself does not reject a null 
principal but does
     audit the operator as "ANONYMOUS" in that case, matching 
TrustedOidcIssuersResource's precedent.
   
   ## How was this patch tested?
   
     DelegationPolicyResourceTest (gateway-service-knoxidf, EasyMock): covers 
every HTTP status
     code enumerated in the error-handling contract for all five endpoint 
variants. POST coverage
     includes happy paths (all-defaults, all-fields round-trip, unknown-field 
ignored, duplicate-
     array-entry collapse via Set), boundary value tests for 
actorAuthority/actorId
     (missing/null/empty/whitespace), status (omitted, empty, valid, invalid, 
wrong case), tokenTtlSec
     (absent, at-min, at-max, below-min, above-max, negative, zero, wrong JSON 
type), allowHeadless-
     Exchange (omitted defaults to false, explicit true), 
canActForUsers/canActForGroups combinations (both
     empty rejected, each individually sufficient, both non-empty), and 
resourcePolicy shapes (omitted,
     empty object, empty-scope-array entry meaning all-scopes, 
non-empty-scope-array, mixed). Error
     paths cover 409 actor_exists, 500 storage_error, and null-principal 
auditing ANONYMOUS. PUT
     (upsert) tests mirror the POST validation suite and additionally cover 201 
(create branch), 200
     (update branch), 409/404 from the retry's second-race propagation, and 
500. GET (list) covers
     no-filter, actorAuthority filter, empty-string filter treated as no 
filter, empty result, and
     hasMore=true surfaced verbatim. GET (one) covers found, not-found (404), 
and storage failure
     (500). PUT /{id} covers full-replace semantics including fields reset to 
defaults on omission,
     server-managed fields (registrationId, createdAt, createdBy, updatedAt) 
ignored when present in
     the body, 404, and 500. DELETE covers 204, 404 (not the idempotent 204 
that TrustedOidcIssuers-
     Resource returns - a deliberate divergence since the storage layer now 
surfaces not-found
     explicitly), and 500. Cross-cutting tests assert ISO-8601 serialization of 
Instant fields (guards
     against an ObjectMapper without JavaTimeModule), and that @PostConstruct 
wires both the service
     and the TTL bounds from GatewayConfig.
     DelegationPolicyDtoImmutabilityTest (gateway-service-knoxidf): confirms 
DelegationPolicyRequest
     and DelegationPolicyResponse defensively copy Set and Map fields on both 
construction and getter
     access, and that null inputs to DelegationPolicyDtoImmutabilityHelper are 
handled cleanly.
     JdbcDelegationPolicyServiceTest (gateway-server, real Derby in-memory): 
adds tests for the
     duplicate-detection upgrade (register() twice on the same 
actorAuthority/actorId throws the
     typed DelegationPolicyAlreadyExistsException with the original 
SQLException in its cause chain)
     and a negative counterpart (a non-duplicate storage failure - VARCHAR 
overflow, SQLState 22001
     - still throws plain RuntimeException, not the typed exception, confirming
     isUniqueConstraintViolation does not over-match). Not-found tests for 
update() and delete() on
     a nonexistent registrationId, and identity-immutability tests rejecting an 
actorAuthority or
     actorId change on update(), verify the database-layer not-found detection. 
Two real Derby-backed
     tests cover registerOrUpdate()'s create branch (new actor, isCreated() 
true) and update branch
     (same actor called twice, same registrationId both times, isCreated() 
false on the second call,
     mutable fields updated, createdAt unchanged, updatedAt advances).
   
   ## Integration Tests
   Integration tests will follow once the rest of the delegation flow has been 
implemented.
   
   ## UI changes
   N/A




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

            Worklog Id:     (was: 1039840)
    Remaining Estimate: 0h
            Time Spent: 10m

> Delegation policy admin API for Knox IDF
> ----------------------------------------
>
>                 Key: KNOX-3438
>                 URL: https://issues.apache.org/jira/browse/KNOX-3438
>             Project: Apache Knox
>          Issue Type: Task
>          Components: JWT
>            Reporter: Harrison Sheinblatt
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Implement the Admin API for managing delegation policies for knoxidf



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

Reply via email to