yuqi1129 opened a new issue, #12405: URL: https://github.com/apache/gravitino/issues/12405
### Version main branch ### Describe what's wrong `CatalogDispatcher.loadCatalog()` returns a live `BaseCatalog` to its callers. After #12403 the load itself is covered by a `CatalogLease`, but the lease is released before the object is returned, so the returned catalog can still be closed by a concurrent cache eviction (expiry, remote change-log invalidation, or drop) while the caller is using it. `BaseCatalog.close()` closes the authorization plugin and sets it to `null` (`BaseCatalog.java:323-334`). `AuthorizationUtils.callAuthorizationPluginImpl()` skips the call **silently** when the plugin is `null`, so the failure mode is not an exception but a lost privilege update — stale grants can be left behind in the external authorization system. The most visible path is `CatalogHookDispatcher.dropCatalog()`: 1. `dispatcher.loadCatalog(ident)` — lease already released; 2. `AuthorizationUtils.getMetadataObjectLocation(...)`; 3. `AuthorizationUtils.removeCatalogPrivileges(catalog, locations)` — no-op if the catalog was closed in between; 4. `dispatcher.dropCatalog(ident, force)` — catalog is gone, privileges never revoked. The same shape applies to the other `loadCatalog()` callers in `AuthorizationUtils` (`callAuthorizationPluginForSecurableObjects`, `loadMetadataObjectCatalog`, `checkCatalogType`) and should be checked for the future-grant path after `createCatalog()`. This predates #12403 (before it, `loadCatalog` held no lease at all, so the window was wider); #12403 fixed the wrapper lifecycle and explicitly left this one out because it is a refactor of the authorization call graph. ### Error message and/or stacktrace No exception is raised. The symptom is a missing privilege update in the external authorization system after a catalog drop, rename, or grant/revoke that raced with a catalog cache eviction. ### How to reproduce 1. Create a catalog with an `authorization-provider` and grant privileges on it. 2. Enter `CatalogHookDispatcher.dropCatalog()` and pause after `loadCatalog()`. 3. Invalidate the catalog cache entry (expiry or remote change-log invalidation) and let the wrapper's cleanup run. 4. Resume: `removeCatalogPrivileges` silently does nothing and the drop completes. ### Additional context Suggested direction: - Give the authorization call path a lease-scoped API (`CatalogManager.acquireCatalogLease` or a callback-style variant) so the plugin invocation happens inside the lease. Note that several call sites only hold a `CatalogDispatcher`, so the API has to be reachable from there. - Make `callAuthorizationPluginImpl` log (or fail) when a `BaseCatalog` configured with an `authorization-provider` has a `null` plugin, so this class of bug stops being silent. - `loadCatalog`'s returned `BaseCatalog` outliving its lease is the root shape — worth deciding whether the public return contract should stay a live catalog object. Related: #12403, #12404 -- 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]
