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

Reply via email to