Describe the subtask
In auxiliary mode, LanceServiceIdentityFilter (registered only when auxMode is true, LanceRESTService.java:147) replaces an anonymous principal with the configured service user (gravitino.lance-rest.gravitino-simple.user-name, default lance-rest-server) before the request reaches the in-process dispatchers.
An anonymous principal can only be produced by the simple authenticator: SimpleAuthenticator.supportsToken accepts a missing header and authenticateToken returns ANONYMOUS_PRINCIPAL for a missing, blank, non-Basic or malformed header instead of null, so AuthenticationFilter never returns 401 under simple. Every other authenticator (oauth2, kerberos, idp-basic) rejects a missing credential with 401 and the filter's branch is never reached.
With gravitino.authenticators = simple and gravitino.authorization.enable = true, the combination is a privilege escalation: without the filter, BaseMetadataAuthorizationMethodInterceptor would reject anonymous with 403 at checkCurrentUser (anonymous is not a metalake user); with it, the unauthenticated request runs with whatever privileges lance-rest-server holds. #12954 documents that the fallback user needs the privileges the operation requires, but not that the fallback turns an unauthenticated request into an authorized one.
The standalone side of this was closed by #12984: LanceCallerTokenProvider rejects anonymous with 401 in the default caller mode. The auxiliary filter is untouched by that PR and is a separate code path.
How should we improve?
The filter exists so an auxiliary deployment that has not configured authentication still works. That intent is compatible with two fixes; either is enough:
- Only install
LanceServiceIdentityFilter when gravitino.authorization.enable is false. When authorization is on, an anonymous request should be denied like any other unknown user, matching what the interceptor would do on its own.
- Keep the filter but make the fallback opt-in (for example
gravitino.lance-rest.anonymous-fallback = false by default), so a deployment has to state that it wants unauthenticated requests to run as the service user.
Option 1 is smaller and needs no new configuration key. Either way, the documentation in docs/lance-rest-service.md should state plainly that simple performs no authentication, that anonymous is its artifact, and what the fallback does when authorization is enabled.
Parent issue
#13090
Describe the subtask
In auxiliary mode,
LanceServiceIdentityFilter(registered only whenauxModeis true,LanceRESTService.java:147) replaces ananonymousprincipal with the configured service user (gravitino.lance-rest.gravitino-simple.user-name, defaultlance-rest-server) before the request reaches the in-process dispatchers.An
anonymousprincipal can only be produced by thesimpleauthenticator:SimpleAuthenticator.supportsTokenaccepts a missing header andauthenticateTokenreturnsANONYMOUS_PRINCIPALfor a missing, blank, non-Basic or malformed header instead ofnull, soAuthenticationFilternever returns 401 undersimple. Every other authenticator (oauth2,kerberos, idp-basic) rejects a missing credential with 401 and the filter's branch is never reached.With
gravitino.authenticators = simpleandgravitino.authorization.enable = true, the combination is a privilege escalation: without the filter,BaseMetadataAuthorizationMethodInterceptorwould rejectanonymouswith 403 atcheckCurrentUser(anonymous is not a metalake user); with it, the unauthenticated request runs with whatever privilegeslance-rest-serverholds. #12954 documents that the fallback user needs the privileges the operation requires, but not that the fallback turns an unauthenticated request into an authorized one.The standalone side of this was closed by #12984:
LanceCallerTokenProviderrejectsanonymouswith 401 in the defaultcallermode. The auxiliary filter is untouched by that PR and is a separate code path.How should we improve?
The filter exists so an auxiliary deployment that has not configured authentication still works. That intent is compatible with two fixes; either is enough:
LanceServiceIdentityFilterwhengravitino.authorization.enableis false. When authorization is on, an anonymous request should be denied like any other unknown user, matching what the interceptor would do on its own.gravitino.lance-rest.anonymous-fallback = falseby default), so a deployment has to state that it wants unauthenticated requests to run as the service user.Option 1 is smaller and needs no new configuration key. Either way, the documentation in
docs/lance-rest-service.mdshould state plainly thatsimpleperforms no authentication, thatanonymousis its artifact, and what the fallback does when authorization is enabled.Parent issue
#13090