I think we had a productive call today in https://www.w3.org/events/meetings/b2f840e0-5593-4164-908e-dfaf26e8b3b7/20260519T080000/, discussing #815, thanks for all that contributed. We resolved that neither a request's destination nor its eventual Sec-Fetch-Dest need to be "preserved" by the IDP's service worker that intercepts FedCM's client-less requests that get modified (with something like DPoP) and sent to the IDP's servers.
Reviewing https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md after the fact, I think "Approach C" laid out in that explainer is on the right track, although I want to make a few corrections, and use it as a jumping off point to seed the next call's agenda.
The section introducing "Approach C" describes a new event type IdentityRequestEvent that is not a FetchEvent, somewhat following the Payment Handler API spec. It says:
Being a different event entirely sidesteps the "is this foreign fetch in disguise?" critique against reusing FetchEvent.
While we may want a new event type, I think this statement is probably not accurate. I'll admit that foreign fetch was before my time, but I think the concern was with double-key cache privacy causing lack of utility, since client-having requests couldn't naturally invoke cross-origin service workers in a double-key-cached world, and bypassing that would be bad. We bypass that here not by merely using a non-FetchEvent type, but by requesting things from the UA in a special blessed FedCM flow, not with the RP's client, and manually selecting the service worker to invoke. So I suspect the real reason that we "sidestep the 'is this foreign fetch in disguise?' critique" is the fact that our request is sent by a trusted path in the browser, not accessible to ordinary web content/scripts, so we're not providing a generic double-key-cache bypass for ordinary web requests like foreign fetch might've if we didn't rip it out.
Event type
This brings me to the next point: the IdentityRequestEvent. Approach C mentions that we follow the Payment Handler Spec, which conveys payment information to a service worker in a very specific format best packaged in a new event type, with new attributes to represent payment information. But our Approach C shows a new event that has a request member and a Promise<Response> respondWith() which is identical to FetchEvent, so it's unclear that we need a new event type! The only new thing we provide is the endpoint member. And the fact that our respondWith() method actually processes its Promise<Response> differently: it processes the response in an FedCM-specific way, expects JSON, etc, and passes it along to FedCM internals. It makes sense that the Payment Handler Spec would do this, since the fire-er of the event doesn't want a Response, it wants a totally different interface, so it needs a totally different method. It might feel weird for us to mirror FetchEvent's signature but have a different processing model for Response objects, but the more I think about it, the more it makes sense since all of this is FedCM-specific anyways. I'm fine with it if @yoshisatoyanagisawa and @slightlyoff are.
Response type restriction?
I don't follow the requirements in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#response-type-restriction. Where do they come from? You say that the response has to have type=default, as if the response were constructed from script manually, but the example code shows:
event.respondWith(
fetch(event.request)
.then(response => {
if (response.ok) {
caches.open('fedcm').then(c => c.put(event.request, response.clone()));
}
return response;
})
.catch(() => caches.match(event.request))
);
Which violates this rule. Also, I think this rule doesn't protect against anything, since the service worker can just fetch the information from any origin it has CORS-access to, extract the data, construct a synthetic response with that data, and feed it back to respondWith(). So I vote we remove this requirement, unless there is some crucial reason it exists that I'm not aware of. Thoughts?
Similarly, that section mentions enforcing that the resolved response object has a URL that's same-origin with the IDP's SW. Why? The section says:
Any other origin is rejected, blocking the SW from laundering cross-origin data through the FedCM channel.
But as I pointed out above, I think the service worker can just fetch something from any origin it has CORS-access to, extract the data, and feed it back through respondWith() manually. Does this protect against anything really?
Configuration endpoints + service worker
https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#configuration-endpoints-are-protected says they remain with service-workers mode=none because:
If intercepted, the SW could correlate user identity (via cookies from its own origin) with RP identity (from client_metadata URL parameters)
How is this true? The requests are already going to the IDP's server, so anything we send there should be safe to expose to the IDP's service worker, right?
Service worker registration and matching
This is the big one. The direction in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#b-service-worker-registration borrowing from payments seems pretty clean, however I'm still trying to figure out why it's necessary? Since opt-in is explicit with the new event type, why can't we invoke pre-existing service workers registered with the IDP's origin that own the scope of the request? Why do we need a separate FedCM-specific service worker and mapping? Does a customer requirement need this?
Nits
@pottis can you remove [RaisesException] in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#2-browser-dispatches-identityrequestevent-to-the-sw? That is a Blink-specific extended attribute, and does not exist in https://webidl.spec.whatwg.org/.
/cc @samuelgoto @cbiesinger @pottis @slightlyoff @wanderview @will-bartlett @bengreenstein @yoshisatoyanagisawa @jyasskin
I think we had a productive call today in https://www.w3.org/events/meetings/b2f840e0-5593-4164-908e-dfaf26e8b3b7/20260519T080000/, discussing #815, thanks for all that contributed. We resolved that neither a request's destination nor its eventual
Sec-Fetch-Destneed to be "preserved" by the IDP's service worker that intercepts FedCM's client-less requests that get modified (with something like DPoP) and sent to the IDP's servers.Reviewing https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md after the fact, I think "Approach C" laid out in that explainer is on the right track, although I want to make a few corrections, and use it as a jumping off point to seed the next call's agenda.
The section introducing "Approach C" describes a new event type
IdentityRequestEventthat is not aFetchEvent, somewhat following the Payment Handler API spec. It says:While we may want a new event type, I think this statement is probably not accurate. I'll admit that foreign fetch was before my time, but I think the concern was with double-key cache privacy causing lack of utility, since client-having requests couldn't naturally invoke cross-origin service workers in a double-key-cached world, and bypassing that would be bad. We bypass that here not by merely using a non-
FetchEventtype, but by requesting things from the UA in a special blessed FedCM flow, not with the RP's client, and manually selecting the service worker to invoke. So I suspect the real reason that we "sidestep the 'is this foreign fetch in disguise?' critique" is the fact that our request is sent by a trusted path in the browser, not accessible to ordinary web content/scripts, so we're not providing a generic double-key-cache bypass for ordinary web requests like foreign fetch might've if we didn't rip it out.Event type
This brings me to the next point: the
IdentityRequestEvent. Approach C mentions that we follow the Payment Handler Spec, which conveys payment information to a service worker in a very specific format best packaged in a new event type, with new attributes to represent payment information. But our Approach C shows a new event that has arequestmember and aPromise<Response> respondWith()which is identical toFetchEvent, so it's unclear that we need a new event type! The only new thing we provide is theendpointmember. And the fact that ourrespondWith()method actually processes itsPromise<Response>differently: it processes the response in an FedCM-specific way, expects JSON, etc, and passes it along to FedCM internals. It makes sense that the Payment Handler Spec would do this, since the fire-er of the event doesn't want aResponse, it wants a totally different interface, so it needs a totally different method. It might feel weird for us to mirrorFetchEvent's signature but have a different processing model forResponseobjects, but the more I think about it, the more it makes sense since all of this is FedCM-specific anyways. I'm fine with it if @yoshisatoyanagisawa and @slightlyoff are.Response type restriction?
I don't follow the requirements in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#response-type-restriction. Where do they come from? You say that the response has to have
type=default, as if the response were constructed from script manually, but the example code shows:Which violates this rule. Also, I think this rule doesn't protect against anything, since the service worker can just fetch the information from any origin it has CORS-access to, extract the data, construct a synthetic response with that data, and feed it back to
respondWith(). So I vote we remove this requirement, unless there is some crucial reason it exists that I'm not aware of. Thoughts?Similarly, that section mentions enforcing that the resolved response object has a URL that's same-origin with the IDP's SW. Why? The section says:
But as I pointed out above, I think the service worker can just fetch something from any origin it has CORS-access to, extract the data, and feed it back through
respondWith()manually. Does this protect against anything really?Configuration endpoints + service worker
https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#configuration-endpoints-are-protected says they remain with service-workers mode=none because:
How is this true? The requests are already going to the IDP's server, so anything we send there should be safe to expose to the IDP's service worker, right?
Service worker registration and matching
This is the big one. The direction in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#b-service-worker-registration borrowing from payments seems pretty clean, however I'm still trying to figure out why it's necessary? Since opt-in is explicit with the new event type, why can't we invoke pre-existing service workers registered with the IDP's origin that own the scope of the request? Why do we need a separate FedCM-specific service worker and mapping? Does a customer requirement need this?
Nits
@pottis can you remove
[RaisesException]in https://github.com/w3c-fedid/FedCM/blob/main/explorations/identity_handler.md#2-browser-dispatches-identityrequestevent-to-the-sw? That is a Blink-specific extended attribute, and does not exist in https://webidl.spec.whatwg.org/./cc @samuelgoto @cbiesinger @pottis @slightlyoff @wanderview @will-bartlett @bengreenstein @yoshisatoyanagisawa @jyasskin