I generally agree with Ryan's framing. My issue is with stating that we need the client capabilities as is currently proposed. Either this is a forward compatible feature and we don't need capabilities, or it's not a forward compatible feature and we need a v2 endpoint to signify the change in expected behavior.
The discussion around using capabilities to augment endpoint behavior is very concerning to me. There are fields we've added like Yufei mentioned, but those are a different category in that they truly are forward compatible; they do not require a change in behavior. I'm fine putting the onus on the administrator and the catalog to decide when/what to return, but trying to share that responsibility between the library, the engine integration and the catalog through the capabilities makes the situation more complicated, but not more secure. I would add that I do think there are mechanisms to augment endpoint behaviors in a structured and narrowly targeted way to allow for forward compatibility, but the current proposal doesn't strike the right balance. -Dan On Fri, Jun 5, 2026 at 1:13 PM Ryan Blue <[email protected]> wrote: > I’m not sure moving the feature behind a v2 endpoint meaningfully reduces > the diligence required from administrators. It may reduce one class of > misconfiguration, but it does not eliminate the need for an explicit trust > and compatibility decision. > > I agree with this. > > My rationale is that if we want to *require* a client behavior then it > should be v2 or some other mechanism for signaling to the service that the > client opts in. If we want read restrictions to be informational, then we > can use v1. > > If we don't want this to be a requirement then it is not a compatibility > breaking change. We would just have to change the spec language to state > that clients SHOULD fail if restrictions aren’t enforced rather than MUST > fail if restrictions aren’t enforced. > > Then that puts more responsibility on administrators. Administrators would > have to verify that an engine is not malicious and actually supports read > restrictions. > > Maybe an example would help? Say I’m an administrator setting up a new > Trino cluster using a Docker image from the project. Because I’m using a > public Docker image from the Trino community, have verified its hash, and > am the one deploying it, I trust that it doesn’t have malicious code. I > think as an admin, I would consider that “trusted” when I set up the > identity for that cluster. If we don’t use a v2 endpoint (or other option) > then I would also have to check the Trino version to see if it supports > read restrictions and test them out. > > I would rather make the administrator role simpler here. But maybe we can > do both: we could allow read restrictions on the v1 path and require admins > to include enforcement in their trust decision. And on the v2 path we could > make support required for the future. Is that a good compromise? > > Ryan > > On Fri, Jun 5, 2026 at 12:19 PM Yufei Gu <[email protected]> wrote: > >> We have added fields (e.g., storage-credentials and ETags) to LoadTable >> before and generally haven't treated them as compatibility issues. I think >> the difference here is that this change affects the correctness contract >> for reading data. If a client does not understand or cannot enforce the >> returned restrictions, ignoring the field could result in behavior that the >> catalog administrator did not intend. >> >> That said, I'm not sure that preventing those violations is primarily a >> protocol versioning concern. If a catalog is configured to return >> restriction-bearing responses, it already needs an administrative mechanism >> to determine which principals or engines are expected to honor those >> restrictions. >> >> One reason I'm not fully convinced by the accidental violation argument >> is that, the operational burden seems roughly the same, regardless of >> whether restrictions are delivered through v1 or v2. For a >> security-sensitive feature, I would expect admins to explicitly verify that >> a given engine or client can handle restrictions before enabling >> restriction-bearing responses. In practice, checking "does this client >> support read restrictions?" does not feel materially different from >> checking "does this client support loadTable v2?". >> >> Because of that, I'm not sure moving the feature behind a v2 endpoint >> meaningfully reduces the diligence required from administrators. It may >> reduce one class of misconfiguration, but it does not eliminate the need >> for an explicit trust and compatibility decision. If the goal is to avoid >> accidental violations, the safer rule is that catalogs should not return >> restriction-bearing responses, unless an admin has explicitly enabled them >> for a given principal or engine, regardless of whether the request is made >> through v1 or v2. >> >> Yufei >> >> >> On Fri, Jun 5, 2026 at 11:05 AM Ryan Blue <[email protected]> wrote: >> >>> There are a few issues all mixed together so I want to try to separate >>> them: >>> >>> 1. How do we introduce forward-incompatible changes? >>> 2. What does support for read restrictions mean in this context? >>> 3. What does “trusted” or “untrusted” mean? >>> 4. Why would we make read restriction support a forward-incompatible >>> change? >>> >>> How do we introduce forward-incompatible changes? >>> >>> First, what I mean by “forward-incompatible” is that an older client >>> can’t correctly interact with a newer server. Making table location optional >>> is a good example: older clients require it and will fail if a server >>> doesn’t send it. >>> >>> This is what Dan and I talked about last week and where I think we have >>> the most alignment. I think that the capability header was really an >>> alternative way to make a forward-incompatible change. Using the same >>> location example, we could continue using v1 but signal that a client can >>> handle a missing location with a capability, like >>> supports-optional-location. With this simpler example I think it is >>> more clear that this isn’t a good solution. Why deal with the problem of >>> signaling support generally when it is unclear what this means for >>> loadView or loadFunction? >>> >>> I think we all probably agree that for cases like location, a v2 >>> endpoint is the right way forward. >>> >>> What does support for read restrictions mean in this context? >>> >>> The support that Dan and I are talking about is not evaluating and >>> applying read restrictions. It is parsing and failing if there are >>> restrictions that won’t be applied. The minimal commitment is to parse the >>> “read-restrictions” field and fail if there are any column masks or row >>> filters. >>> >>> That just means checking for a key and failing if either list is not >>> empty. >>> >>> What does “trusted” or “untrusted” mean? >>> >>> Trusted means that an administrator trusts that a client is not >>> malicious. A malicious client can say it supports and will even enforce >>> read restrictions, but may do something else because it’s malicious. We >>> really only care about the trusted case where the client is trusted to not >>> lie or purposely violate requirements. But it might *accidentally* violate >>> requirements! >>> >>> Why would we make read restriction support a forward-incompatible change? >>> >>> The reason to make read restrictions support a forward-incompatible >>> change (v2 rather than v1) is to avoid the accidental violation. I think >>> that administrators will use the “is this client malicious” definition of >>> trust and could overlook client versions and abilities. >>> >>> By putting read restrictions in the v2 endpoint, we are saying that the >>> client has to guarantee that it will look for read restrictions and fail if >>> any are not enforced. This closes the possibility that a client that >>> doesn’t support read restrictions will be trusted (by the “is this client >>> malicious” definition) and receive them. A client that doesn’t support read >>> restrictions will use the v1 endpoint. >>> >>> Independently, I think it makes sense that additional requirements that >>> we way constitute “correct” behavior — applying masks and filters — are >>> forward-incompatible changes. Trust aside, if we have additional >>> requirements or change the contract, I think that’s a forward-breaking >>> change. >>> >>> I know I didn’t address points directly, but I thought it would be >>> helpful to outline my logic and cover the relevant questions. I think we >>> can also address this in the discussion on Tuesday. >>> >>> Ryan >>> >>> On Fri, Jun 5, 2026 at 8:26 AM Daniel Weeks <[email protected]> wrote: >>> >>>> Christian, >>>> >>>> I think we're conflating two things: knowing about read restrictions >>>> and fully supporting read restrictions. >>>> >>>> A major point of contention regarding why read restrictions cause >>>> issues as a forward-compatible change is that clients don't know about the >>>> new fields and may not fail/apply correctly. >>>> >>>> The claim: "If using v2 also requires implementing read-restrictions, >>>> every client that just wants those cleanups is forced to handle >>>> restrictions too." is overstating the effort. They just need to fail if >>>> they see that field provided. It doesn't force implementation; it forces >>>> knowledge about the behavior. >>>> >>>> In many ways, I think we're trying to design the API based on our >>>> reference client's behavior. But each endpoint should really stand on its >>>> own and if there's a behavior change clients need to know about, it should >>>> be explicit. >>>> >>>> I'm pretty opposed to introducing side effect behaviors when we have a >>>> path to do it explicitly. >>>> >>>> -Dan >>>> >>>> >>>> On Thu, Jun 4, 2026 at 11:32 PM Christian Thiel < >>>> [email protected]> wrote: >>>> >>>>> I want to push back on one idea in the thread: the sentiment that a v2 >>>>> loadTable should "mandate that clients must fail if there are unsupported >>>>> restrictions." A v2 endpoint will mostly be adopted for the unrelated >>>>> cleanups — optional location, optional snapshots, creds out of properties. >>>>> If using v2 also requires implementing read-restrictions, every client >>>>> that >>>>> just wants those cleanups is forced to handle restrictions too. That's >>>>> coupling, not opt-in, and it'll drag on v2 adoption. So read-restrictions >>>>> shouldn't be the leading motivation for v2 — I think it can just as well >>>>> be >>>>> introduced in v1. >>>>> >>>>> On versioned endpoints as the path to maturity: versioning is the >>>>> right tool for genuinely forward-breaking changes like the metadata >>>>> cleanups, but if it becomes the default way to extend the spec we're >>>>> looking at a version bump and a client migration for every additive field. >>>>> >>>>> And as Russell points out, the mandate doesn't actually bind an >>>>> untrusted caller anyway — spec language can't. Enforcement of >>>>> read-restrictions is an out-of-band trust decision the catalog makes about >>>>> a principal/engine. A trusted client honors them whether they arrive over >>>>> v1, a header, or v2; an untrusted one ignores them regardless. So the >>>>> capability flag is advisory at best, and a v2 endpoint is redundant for >>>>> this feature with the trust decision the catalog already has to make. >>>>> >>>>> Kurtis — I share your unease with the global header; a single signal >>>>> that mixes "what I'm requesting" with "what I can handle" is exactly the >>>>> conflation that makes it awkward. On versioned endpoints as the path to >>>>> maturity, though, I'd be a bit careful: versioning is the right tool for >>>>> genuinely forward-breaking changes like the metadata cleanups, but if it >>>>> becomes the default way to extend the spec we're looking at a version bump >>>>> and a client migration for every additive field. >>>>> >>>>> So I'd back Russell's recommendation: ship read-restrictions in v1 and >>>>> pursue v2 in parallel for the genuinely forward-breaking metadata changes >>>>> — >>>>> that's where mandating client understanding actually buys something. >>>>> >>>>> Christian >>>>> >>>>> On Fri, 5 Jun 2026 at 03:05, Russell Spitzer < >>>>> [email protected]> wrote: >>>>> >>>>>> I don't really have an issue with a v2 endpoint, there are some good >>>>>> reasons on Ryan's list (optional location, optional snapshots, creds >>>>>> out of properties) but I don't see how a v2 actually changes the read >>>>>> restrictions story. >>>>>> >>>>>> From my perspective read restrictions aren't a client capability the >>>>>> client gets to opt into in the first place. Either the admin has set >>>>>> up the catalog to send restrictions for a particular principal/engine >>>>>> or it hasn't, the client doesn't really get a vote. Both proposals >>>>>> are trying to use the protocol to establish that the caller will >>>>>> honor restrictions, the header does it by advertising support and v2 >>>>>> does it by mandating it in the spec, but neither one actually does >>>>>> that. >>>>>> >>>>>> A client that says "I support read-restrictions" can ignore >>>>>> them, a client calling v2 can ignore them, spec language doesn't bind >>>>>> an untrusted caller. The catalog still has to decide out of band >>>>>> whether this principal is trusted to receive a restriction-bearing >>>>>> response, and once that decision has been made the header and the >>>>>> endpoint version don't really add anything. >>>>>> >>>>>> So the header is advisory at best (a "fail fast if misconfigured" >>>>>> hint), and a v2 endpoint, for this particular feature, is redundant >>>>>> with whatever admin configuration is already required. I don't think >>>>>> we should be encoding a trust signal into the protocol that the >>>>>> protocol can't actually enforce. >>>>>> >>>>>> I recommend we move ahead with read-restrictions without >>>>>> the capability flag in the V1 interface and do V2 work in parallel. >>>>>> >>>>>> On Thu, Jun 4, 2026 at 5:56 PM <[email protected]> wrote: >>>>>> >>>>>>> Thank you for sending this to the dev list Dan. I was having >>>>>>> connectivity issues during the previous meeting and didn’t quite wrap my >>>>>>> head around the proposal at that time. >>>>>>> >>>>>>> +1 to creating a v2 loadTable api. >>>>>>> >>>>>>> I worry (maybe needlessly) about the pattern a generic global >>>>>>> capabilities header might set and how future spec changes might try to >>>>>>> leverage this header. It feels itchy that a client could make a request >>>>>>> for >>>>>>> something, but also inform the server that it doesn’t have the >>>>>>> capability >>>>>>> to handle the response. I know it’s a slippery slope argument, but it >>>>>>> doesn’t seem like a reason not to be concerned about that potential use. >>>>>>> >>>>>>> I am of the opinion currently that now establishing the pattern of >>>>>>> using versioned endpoints to extend Iceberg functionality is a greater >>>>>>> step >>>>>>> towards maturity of the project. >>>>>>> >>>>>>> Best Regards, >>>>>>> Kurtis C. Wright >>>>>>> >>>>>>> On Jun 4, 2026, at 15:48, Ryan Blue <[email protected]> wrote: >>>>>>> >>>>>>> >>>>>>> Ugh, I tried to send this on Saturday but ended up having it blocked >>>>>>> because I used my personal gmail. Here's my original email. I think I'm >>>>>>> saying much the same thing as Dan. >>>>>>> >>>>>>> I was talking to Dan about the REST capabilities header earlier this >>>>>>> week and he convinced me that one problem with the generic header is the >>>>>>> association with endpoints. If we say that the "read-restrictions" >>>>>>> capability requires certain behavior of the load table endpoint, then >>>>>>> what >>>>>>> happens if we later realize that other endpoints should also >>>>>>> participate? >>>>>>> We would need additional headers and this is the key idea behind Dan's >>>>>>> point that we would need to associate capabilities with specific >>>>>>> endpoints >>>>>>> -- and there's not a great way to document that. >>>>>>> >>>>>>> In that discussion, I had an idea that I think might be a good third >>>>>>> option. Adding a capability is a way for clients to opt into new >>>>>>> forward-breaking changes. But we already have a way to introduce >>>>>>> forward-breaking changes: versioned endpoints. With a new endpoint, >>>>>>> clients >>>>>>> are required to understand payloads and behave certain ways. If we >>>>>>> introduced a v2 loadTable endpoint, we could add read restrictions and >>>>>>> mandate that clients must fail if there are unsupported restrictions. >>>>>>> >>>>>>> There are other reasons to introduce a v2 endpoint as well: we are >>>>>>> making table location optional in v4, we have discussed making snapshots >>>>>>> optional (an empty list means an empty table!), and we could default the >>>>>>> snapshot loading behavior to refs. >>>>>>> >>>>>>> I think we should seriously consider adding a v2 endpoint since >>>>>>> that's the way that we already have to introduce new required >>>>>>> functionality. Then we don't have to worry about either too many custom >>>>>>> headers or associating values from a generic header with endpoints and >>>>>>> behavior. I think this is much cleaner than either head-based solution. >>>>>>> >>>>>>> On Thu, Jun 4, 2026 at 8:45 AM Daniel Weeks <[email protected]> >>>>>>> wrote: >>>>>>> >>>>>>>> Thanks Prashant, >>>>>>>> >>>>>>>> I added some comments to the various PRs, but wanted to follow up >>>>>>>> here as well. >>>>>>>> >>>>>>>> I have several concerns regarding the complexity this approach >>>>>>>> would introduce. While this may seem simple initially, a number of >>>>>>>> artifacts emerge when you start to dig into it: >>>>>>>> - Capabilities are not just what the client supports, it's what the >>>>>>>> engine supports and how the environment has been configured in some >>>>>>>> cases >>>>>>>> (like read restrictions) >>>>>>>> - A global header means that if associated behaviors apply only to >>>>>>>> a subset of endpoints, it's not clear where the behavior is targeted >>>>>>>> - Evolution is already being discussed through the addition of >>>>>>>> versioning to the labels >>>>>>>> - This can lead to a proliferation of capabilities that have >>>>>>>> behaviors orthogonal (or at least nuanced variations) to what is >>>>>>>> defined in >>>>>>>> the OpenAPI spec >>>>>>>> >>>>>>>> I feel like what we're actually doing is trying to work around >>>>>>>> introducing new versioned endpoints (e.g. v2 loadTable). We already >>>>>>>> have >>>>>>>> versioning in the path, but we have yet to justify introducing a new >>>>>>>> version. Now we're taking extreme steps and introducing new features to >>>>>>>> continue down that path. >>>>>>>> >>>>>>>> I think it's worth looking at what it would take to introduce a v2 >>>>>>>> loadTable endpoint and correct for a number of issues with the original >>>>>>>> endpoint (creds duplicated in properties, required metadata location) >>>>>>>> and >>>>>>>> introduce new response objects so that it's clear the calling client >>>>>>>> clearly understands the endpoint. >>>>>>>> >>>>>>>> I'm not fundamentally opposed to client capabilities at this point, >>>>>>>> but it feels like we're creating complexity that isn't narrowly >>>>>>>> targeted. >>>>>>>> >>>>>>>> -Dan >>>>>>>> >>>>>>>> On Wed, May 27, 2026 at 11:50 PM Prashant Singh < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> 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 >>>>>>>>>>>>> > >>>>>>>>>>>>> >>>>>>>>>>>>
