Hi Prithvi, thanks for driving this. One thing that might simplify this: Polaris already stamps every request with a requestId (RequestIdFilter) and returns it to the client as the X-Request-ID response header and it's on every server log line via the logging MDC (https://polaris.apache.org/in-dev/unreleased/telemetry/). So an operator can already correlate a client-side 403 to the server logs today, which means the detailed "missing X on entity Y" text could live in a server-side log rather than the client response.
To Robert's point about not relying solely on a client-supplied value: X-Request-ID can be client-supplied. For deployments that turn on OpenTelemetry, the server-generated traceId is probably an alternate and more robust server generated correlation key (also already in the MDC). We could perhaps surface that as an additional X-Trace-ID header for those setups? Sung On 2026/06/26 09:02:59 Robert Stupp wrote: > Hi all, > > Our security threat model [1] sets a strong default for generic "forbidden" > error messages to clients, stating that client-visible errors must not > disclose secrets or unauthorized metadata, including names and > relationships of principals, roles, catalogs, namespaces, tables, views, > and policies, unless that disclosure is explicitly documented and accepted. > > However, emitting more details to an operator/admin-facing sink might be > acceptable. > > There is a standard for this kind of problem: RFC 9457 [2]. Unfortunately, > the `application/problem+json` response fields do not fit Iceberg's > `ErrorModel` error response payload type directly, but RFC 9457 could still > be used as inspiration. > > I'd be generally careful about changing Iceberg error messages, because > many of them are effectively part of the API contract. > > You'll likely need to correlate the client-facing error with the > operator/admin-facing problem details. That's not impossible, but I > wouldn't rely solely on a client-supplied value in this case. > > Robert > > [1] > https://github.com/apache/polaris/blob/02bd8f1f99a9f3d4f87d8db88cf7317fcac76c36/SECURITY-THREAT-MODEL.md > [2] https://www.rfc-editor.org/info/rfc9457/ > > > On Fri, Jun 26, 2026 at 2:07 AM Dmitri Bourlatchkov <[email protected]> > wrote: > > > Hi All, > > > > I'm replying with the same suggestion I made in GH just to revive > > this thread. > > > > My preference is towards NOT exposing details about the authZ denial to the > > client, but returns a random ID which could be correlated (by a Polaris > > Admin) to the full details in a log message. > > > > WDYT? > > > > Cheers, > > Dmitri. > > > > On Sun, Jun 14, 2026 at 2:50 PM Prithvi S <[email protected]> > > wrote: > > > > > Hi all, > > > > > > I'm opening this discussion as suggested by @dimas-b in the review of PR > > > #4406 (https://github.com/apache/polaris/pull/4406), which touches > > > authorization behavior. > > > > > > Background: > > > Today, `PolarisAuthorizerImpl.authorizeOrThrow` produces a generic denial > > > message: > > > > > > Principal 'alice' with activated PrincipalRoles '[reader]' and > > activated > > > grants via '[]' is not authorized for op CREATE_TABLE_DIRECT > > > > > > This gives operators no indication of *which* privilege is missing or on > > > *which* entity, forcing them to grep the codebase to figure out the right > > > grant to add. > > > > > > What PR #4406 does: > > > It enriches the 403 message to include the missing privilege and target > > > entity, e.g.: > > > > > > ...is not authorized for op CREATE_TABLE_DIRECT; missing TABLE_CREATE > > on > > > NAMESPACE 'ns1' > > > > > > The legacy prefix is preserved verbatim so existing log scrapers continue > > > to work. This is a diagnostic-only change — authorization decisions > > > (allow/deny) are unchanged. > > > > > > Concern raised: > > > @dimas-b and @flyrain raised a valid security concern: returning AuthZ > > > details in the client-facing 403 response could expose information that a > > > malicious client might use to probe the permission model. > > > > > > The alternative suggested was to log the missing privilege details > > > server-side and surface only a correlation/trace ID in the client > > response, > > > allowing Polaris admins to correlate the client error to the server log > > > without leaking grant structure to untrusted clients. > > > > > > questions I have: > > > 1. Is the security concern significant enough to block enriching the > > > client-facing 403 message, or does the operator convenience justify it > > > (e.g., given that the privilege/entity names are not secret in most > > > deployments)? > > > 2. Should we pursue the log + correlation-ID approach instead? If so, is > > > there an existing logging/tracing infrastructure in Polaris we should > > hook > > > into? > > > 3. Are there precedents in other Iceberg catalog implementations for how > > > AuthZ denial details are surfaced? > > > > > > Happy to update the PR in whichever direction the community prefers. > > > > > > Regards, > > > Prithvi S > > > > > >
