Hi Dan,
Wanted to follow up specifically on your concerns since we re-discussed
this at the 05/26 sync (you weren't there for
the final stretch). Recording: https://www.youtube.com/watch?v=-KEesN1udyY
*On the per-endpoint vs. generic header pattern*: the room leaned
generic, mostly on the argument that
X-Iceberg-Access-Delegation is doing a different job - it's a per-request
directive ("vend credentials for this
call"), not a static declaration of what the client understands. Modeling
capabilities the same way conflates two
patterns: one is runtime preference, the other is a build-time fact about
the client.
*On the OpenAPI tooling concern (the "spec within a spec" point **from
sync)*: the values are still a constrained enum in the
OpenAPI schema - same shape as X-Iceberg-Access-Delegation. Generated
clients validate values; servers get a closed
list; adding a capability is a one-line enum edit. There's no parallel
registry - it's a normal header whose schema
happens to be enum-typed.
* On bundling all capabilities per request*: Russell raised the same -
could a client send only the relevant subset per
endpoint? The sync's view was that since capabilities don't change
between calls, per-endpoint subsetting adds client
bookkeeping without much benefit. Open to revisiting if you have a use
case in mind where conditional advertisement
matters (e.g., a client that wants to suppress a capability it
technically supports).
Looking forward to hearing from you.
Thanks,
Prashant
On Mon, May 25, 2026 at 12:47 PM Prashant Singh <[email protected]>
wrote:
> Thanks everyone for the feedback. Apologies for the delayed response on
> the
> list, I wasn't receiving mailing list emails and had only been
> responding on
> the PR so far.
>
> * On versioning (Sung):*
>
> I don't think we need versioning if we bake into the spec that clients
> MUST
> fail when they encounter something they don't understand within a
> capability's
> payload. The capability signal means "I understand this payload exists
> and I
> will do the right thing with it" — not "I understand every possible value
> within it forever." The fail-closed contract gives us forward
> compatibility
> without version suffixes.
>
> *On single generic header vs. per-feature headers (Dan, Russell):*
>
> Re-listening to the sync, I don't think we landed on a hard conclusion
> either
> way. I went with the generic approach based on how other protocols handle
> this.
>
> *Precedents*:
>
> - Anthropic's API : single *anthropic-beta* header with comma-separated
> feature
> tokens; different endpoints consume different tokens, client sends the
> union.
> - Delta Sharing : single *delta-sharing-capabilities* header mixing
> different
> feature dimensions, server acts only on what's relevant per endpoint.
>
> One distinction that helped me think about it: per-feature headers like
> X-Iceberg-Access-Delegation are directives for a specific request - "vend
> credentials for this call." A capabilities header is different - it's a
> passive, static advertisement of what the client understands. Bundling
> these
> into one header keeps them distinct from per-request directives.
>
> The practical benefit: adding a new capability is a one-line enum
> addition.
>
> I don't have a strong preference between the two approaches and am happy
> to
> revise the PR based on community consensus. Russell, to your point about
> scoping it to relevant endpoints - Sung raised the same on the PR and
> I'm open
> to that.
>
> Happy to discuss more in the upcoming sync (05/26).
>
> Thanks,
> Prashant
>
>
>
> On Fri, May 22, 2026 at 1:15 PM Russell Spitzer <[email protected]>
> wrote:
>
>> This seems matched to what I thought we went over, I'm also not sure why
>> the shape *capabilities : {foo, bar}* necessarily mean the client has to
>> send all the capabilities with every request. Can the client just decide to
>> send *capabilities:{foo}* to those endpoints that care about foo?
>>
>> On Tue, May 19, 2026 at 2:54 PM Daniel Weeks <[email protected]> wrote:
>>
>>> Thanks for following up on this, Prashant.
>>>
>>> My recollection of the conversation was not to add a single header that
>>> allows an arbitrary number of capabilities set, but rather to follow the
>>> pattern established with the `x-iceberg-access-delegation' and use specific
>>> headers applicable to endpoints where they would apply.
>>>
>>> I'm not convinced we want to have all the capabilities bundled up and
>>> sent for every request (though this might be easier to implement in some
>>> cases). There may be scenarios where you want to advertise capabilities or
>>> not depending on the client configuration and would make managing the set
>>> of properties more difficult.
>>>
>>> After reviewing the conversation, this doesn't quite correspond to how
>>> we ended the discussion.
>>>
>>> -Dan
>>>
>>> On Tue, May 19, 2026 at 7:06 AM Sung Yun <[email protected]> wrote:
>>>
>>>> Thanks Prashant, I’m supportive of introducing a generic client
>>>> capabilities header. I agree with the direction of treating this primarily
>>>> as capability advertisement for compatibility and response shaping rather
>>>> than as a trust mechanism.
>>>>
>>>> I left a couple comments on the PR. One thing I’m wondering is whether
>>>> we should discuss and define the versioning and compatibility model for
>>>> capability header values as part of this proposal.
>>>>
>>>> Capabilities like `read-restrictions` seem very likely to evolve over
>>>> time in ways that older clients may not be able to safely consume. I’m
>>>> curious whether the community thinks capability values should represent
>>>> versioned compatibility contracts (like read-restrictions.v1) and whether
>>>> we want to define any expectations around cross-version compatibility
>>>> behavior now as we introduce the header.
>>>>
>>>> Sung
>>>>
>>>> On 2026/05/18 18:51:52 Prashant Singh wrote:
>>>> > Hi all,
>>>> >
>>>> > I'd like to propose adding a new HTTP header,
>>>> > X-Iceberg-Client-Capabilities,
>>>> > to the REST catalog spec. This was brought up at the Read
>>>> Restrictions
>>>> > community sync on May 12, 2026; I'm bringing it to the broader list
>>>> now
>>>> > for
>>>> > wider feedback.
>>>> >
>>>> > PR: https://github.com/apache/iceberg/pull/16394
>>>> > Recording: https://youtu.be/b9p6mI-k-0I
>>>> >
>>>> > *Context*
>>>> >
>>>> > Iceberg's REST protocol keeps evolving — server-side scan
>>>> > planning, remote signing, and the in-flight ReadRestrictions
>>>> proposal
>>>> > (PR #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. One direction discussed at the
>>>> community
>>>> > sync was to introduce a single generic capability header rather than
>>>> > per-feature negotiations; this thread is to gather broader input on
>>>> that
>>>> > proposal.
>>>> >
>>>> > *Proposal*
>>>> >
>>>> > Send X-Iceberg-Client-Capabilities on every catalog request:
>>>> >
>>>> > ex: X-Iceberg-Client-Capabilities:
>>>> > vended-credentials,remote-signing,scan-planning
>>>> >
>>>> > The Java SDK adds it via HTTPClient.baseHeaders — the same path
>>>> used for
>>>> > X-Client-Version and X-Client-Git-Commit-Short today. Other client
>>>> > implementations (PyIceberg, Rust, Go, etc.) can mirror the same
>>>> enum.
>>>> >
>>>> > Initial capability set for Java SDK:
>>>> > - vended-credentials
>>>> > - remote-signing
>>>> > - scan-planning
>>>> >
>>>> > read-restrictions will be added once PR #13879 lands.
>>>> >
>>>> >
>>>> > * Design notes worth feedback*
>>>> > 1. 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 spec parameter description states this
>>>> explicitly.
>>>> >
>>>> > 2. enum: constraint on the schema. Mirrors
>>>> X-Iceberg-Access-Delegation.
>>>> > Adding
>>>> > a new capability is a one-line spec edit; generated clients can
>>>> > validate
>>>> > values; servers get a machine-readable closed list of recognized
>>>> > values.
>>>> >
>>>> > 3. Skipped for /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.
>>>> >
>>>> > *Links*
>>>> >
>>>> > - PR: https://github.com/apache/iceberg/pull/16394
>>>> > - May 12 sync recording: https://youtu.be/b9p6mI-k-0I
>>>> > - Related: PR #13879 <
>>>> https://github.com/apache/iceberg/pull/13879>
>>>> >
>>>> > Thanks,
>>>> > Prashant
>>>> >
>>>>
>>>