Skip to content

Core, OpenApi: Add X-Iceberg-Client-Capabilities header#16394

Open
singhpk234 wants to merge 1 commit into
apache:mainfrom
singhpk234:x-iceberg-client-capabilities-header
Open

Core, OpenApi: Add X-Iceberg-Client-Capabilities header#16394
singhpk234 wants to merge 1 commit into
apache:mainfrom
singhpk234:x-iceberg-client-capabilities-header

Conversation

@singhpk234
Copy link
Copy Markdown
Contributor

@singhpk234 singhpk234 commented May 18, 2026

Summary

Introduces a new X-Iceberg-Client-Capabilities HTTP header that lets REST clients
advertise the capabilities they support to the catalog server. The header is
informational, sent on every catalog request, and is intended as a forward-compatibility
mechanism — not a security mechanism.

This was brought up at the Read Restrictions community sync on May 12, 2026
(recording); a dev list thread is being raised
in parallel for broader discussion.

Motivation

Iceberg's REST protocol keeps evolving — server-side scan planning, vended
credentials, remote signing, and the in-flight fine-grained access control
proposal (#13879) are all features that catalogs may return but older clients
can't handle. Today there's no standard way for a client to declare "I
understand X" to the server. This PR introduces a single, generic mechanism
for the client to declare its capability set up front.

The header pattern mirrors X-Client-Version and X-Client-Git-Commit-Short
(already added on every request via HTTPClient.baseHeaders) — it is a stable
SDK-attribute hint, not a per-request preference.

Design notes

  • Forward-compat hint, not security. The header is informational — clients
    can trivially spoof its value, so servers MUST NOT base trust or
    authorization decisions on it. Trust establishment (mTLS, OAuth, etc.) is
    out of scope. The parameter description in the spec calls this out
    explicitly so it can't be missed.

  • enum: constraint on the schema. Mirrors the existing
    X-Iceberg-Access-Delegation parameter. Adding a new capability is a
    one-line spec edit. Generated clients can validate values; servers get a
    machine-readable closed list of recognized tokens.

  • Independent of X-Iceberg-Access-Delegation. Despite token overlap
    (vended-credentials, remote-signing appear in both), the headers carry
    different semantics: data-access is a per-request preference ("I want
    this for this call"); client-capabilities is a static SDK attribute
    ("I am built to handle this").

  • Excluded from /v1/oauth/tokens. OAuth token endpoints may be served
    by external IdPs (Okta, Auth0, etc.) where Iceberg-specific headers are
    noise. Mirrors how X-Iceberg-Access-Delegation is handled.

  • SDK overrides user config. The Java SDK's static value overrides any
    user-configured header.X-Iceberg-Client-Capabilities property — same
    pattern as the existing X-Client-Version / X-Client-Git-Commit-Short
    headers. Pinned by an explicit test.

Future work

  • Add read-restrictions to the enum once [SPEC] Add finer grained read restrictions as part of loadTable #13879 (FGAC) lands. The framing
    in that PR's review (catalogs MUST NOT return read-restrictions to
    clients that don't advertise the capability) depends on this header being
    available.
  • Other client SDKs (PyIceberg, Rust, Go) can mirror this enum to advertise
    the same capability set.

Changes from the prior draft:

  • Added the May 12 sync reference + recording link in the Summary
  • Replaced the "free-form, no enum" design note with the "enum: constraint" rationale
  • Added the spoof-disclaimer note explicitly
  • Added a new bullet about SDK-overrides-user-config (now pinned by test)

@singhpk234 singhpk234 changed the title Core, REST: Add X-Iceberg-Client-Capabilities header Core, OpenApi: Add X-Iceberg-Client-Capabilities header May 18, 2026
Introduces a new HTTP header that lets REST clients advertise their
supported capabilities to the catalog server on every request.

* New ClientCapability enum (vended-credentials, remote-signing,
  scan-planning) as the single source of truth for supported
  capabilities, with javadoc describing the protocol each capability
  implies.
* HTTPClient sets X-Iceberg-Client-Capabilities statically in build()
  alongside X-Client-Version and X-Client-Git-Commit-Short, so the
  header is included on every request and overrides any user-supplied
  header.* property.
* OpenAPI client-capabilities parameter component documents the
  defined values without an enum constraint, allowing new capabilities
  to be added without schema changes. The header is optional; servers
  must not fail if it is absent.
@sfc-gh-prsingh sfc-gh-prsingh force-pushed the x-iceberg-client-capabilities-header branch from eb2cb6f to b453c26 Compare May 18, 2026 18:40
@singhpk234 singhpk234 marked this pull request as ready for review May 18, 2026 20:58
Copy link
Copy Markdown
Contributor

@steveloughran steveloughran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented as someone who has read far too many RFCs.

- `scan-planning`: The client supports server-side scan planning.


Clients should include all capabilities they support. Servers must
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capitalisation; clarify "fail"

Clients SHOULD include all capabilities they support. Servers MUST
treat this header as optional and SHALL NOT reject the request if it is absent.

treat this header as optional and must not fail if it is absent.


Client SDKs that support this header should set it statically and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SHOULD


Client SDKs that support this header should set it statically and
include it on every request. Clients that do not yet support this
header statically can configure it via client side headers.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/can/r/MAY/

summary: Create a namespace
parameters:
- $ref: '#/components/parameters/idempotency-key'
- $ref: '#/components/parameters/client-capabilities'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we are adding client capabilities header to /v1/{prefix}/namespaces?
read-restrictions, vended-credentials and remote-signing are not capabilities related to namespace maintenance requests. Would it make more sense to leave it out until capability negotiation is needed for namespaces?

Comment on lines +2076 to +2084
Defined capability values:

- `vended-credentials`: The client supports receiving and using
storage credentials vended by the catalog server.

- `remote-signing`: The client supports delegating request signing
to a remote signing service provided by the catalog server.

- `scan-planning`: The client supports server-side scan planning.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if these capability values should include a major compatibility version, since values like read-restrictions may evolve in ways that older clients cannot safely consume. Would read-restrictions.v1 make more sense, so that incompatible future semantics can be represented as read-restrictions.v2?

This would allow us to introduce a new column mask subtype in read-restrictions without worrying about breaking the existing capability header contract, by simply introducing a new capability version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants