jiangxt2 opened a new issue, #12785:
URL: https://github.com/apache/gravitino/issues/12785

   ### Version
   
   main branch
   
   ### Describe what's wrong
   
   When a client loads a table with `privileges=MODIFY_TABLE`, Gravitino 
selects the secondary modify-table authorization expression. If that 
authorization is denied, `LoadTableAuthorizationExecutor` still evaluates the 
table-like existence-probe expression and may call 
`tableDispatcher().tableExists()` when the caller has probe permissions such as 
`USE_CATALOG`, `USE_SCHEMA`, and `SELECT_TABLE`. For external JDBC catalogs, 
this existence check performs physical metadata I/O; for `jdbc-doris`, the JDBC 
table loader opens a MySQL-protocol connection before checking whether the 
table exists. A write request that should fail at authorization therefore opens 
an external connection, adds latency and resource pressure, and makes the 
authorization result depend on external catalog availability.
   
   ### Error message and/or stacktrace
   
   Expected behavior is a deterministic `403 Forbidden` for a denied 
`MODIFY_TABLE` request without contacting the configured external catalog. The 
observed behavior includes a TCP connection to the configured JDBC endpoint on 
the denied path. If the endpoint is unavailable, the connection failure can be 
caught by the authorization interceptor and returned as an internal 
authorization error instead of the original authorization denial.
   
   ### How to reproduce
   
   1. Run Gravitino main with authorization enabled and create an external 
`jdbc-doris` catalog whose JDBC and Doris endpoints can record incoming 
connections.
   2. Create a role with `USE_CATALOG`, `USE_SCHEMA`, and `SELECT_TABLE` 
allowed, and `MODIFY_TABLE` denied.
   3. Execute a Spark 3.5 write or send a table-load request carrying 
`privileges=MODIFY_TABLE` for that catalog and table.
   4. As a quick path that does not require Spark, use a Java client and call 
`RelationalCatalog.loadTable(NameIdentifier.of("schema", "table"), 
Set.of(Privilege.Name.MODIFY_TABLE))` for the same catalog and table.
   5. Observe that Gravitino denies the request but the configured JDBC 
endpoint receives a connection attempt before the denial response is completed.
   6. Point the catalog at an unavailable endpoint and observe that the failure 
can change the response from a deterministic authorization denial to an 
internal authorization error.
   
   ### Additional context
   
   The `allowCheckExistence` path is useful for ordinary load authorization 
because it distinguishes a missing table from an existing table that the caller 
cannot load. It should not run after an explicit write authorization request 
has already failed. Spark 3.5 uses `MODIFY_TABLE` to enforce write intent, and 
that authorization is required to complete before any physical write delegate 
or Doris I/O is constructed.
   
   This is not an authorization bypass: the caller is still denied the write. 
It is an authorization correctness and isolation-boundary bug that causes 
external I/O after a failed authorization check and can mask the intended error 
semantics.
   
   The fix should return the denial before any existence probing for an 
explicit failed write authorization, while ordinary load denials retain their 
existing existence-probe behavior. The intentional fail-closed consequence is 
that a missing table requested with denied `MODIFY_TABLE` may return `403` 
instead of probing to produce `404`.
   
   The behavior was introduced by the interaction between the write-aware 
load-table authorization path and the later generic table-like existence-probe 
path. Related context: 
[#12480](https://github.com/apache/gravitino/issues/12480) and 
[#12482](https://github.com/apache/gravitino/pull/12482).
   


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