-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A proposal for framing the Login Status API that reconciles how FedCM/SAA are planning to use it #54
Conversation
I think the shape of the API is good and reflects the extensibility required here. The proposal here doesn't include a key feature of Johann's idea in #53 though. It must be "impossible for a website to read its state directly". I interpreted that to mean that APIs that consume the logged in state must not have web(-developer)-observable behavior based upon that state. This is a big part of the abuse story for this API; we don't want to leak even this one bit per origin to all callers. An explicit statement to this effect would be nice. |
Yeah, I think that's a fair callout though I don't think any of what's proposed here goes against that idea. |
Ah yes, that makes sense. Before I do that, I think we have at least chrome and firefox roughly agreeing to the shape of this API, and we can discuss this further in more details in subsequent PRs (e.g. a proper spec). @annevk @johnwilander where can we go from here as far as Safari is concerned? is this something that you are interested in or not? If Safari isn't immediately interested in / able to participating in the development of this API, could you please merge this and give @bvandersloot-mozilla and I write access to this repo while we polish this up? @erik-anderson @hober does that sound reasonable? |
Hi! I was not aware of this proposal. I’ve requested that I get a heads up notification from CG chairs when one of my specs is on the agenda since I’ve found myself overbooked the last year or so. I’m generally in favor of a shared editorship for this proposal. And the name change to Login Status API of course. However, I want to make sure that the original intent is preserved. That is, to enable browsers to 1) empower sites where the user is logged in, and 2) restrict sites where the user is not logged in. The web has been lacking this signal forever (bar Basic/Digest Auth) and it could serve as a great boundary between allowing powerful but risky features and providing privacy-friendly casual browsing. To connect to an old debate – “it should be safe to click a link.” Would y’all say we are in agreement there? |
There is also another aspect that has grown in our interest regarding Login Status, and that is to formalize the success state of authentication and formalize the logout transition. The former is currently down to heuristics such as HTTP 200 after auth and the latter has never been dealt with, not even with Basic/Digest auth. These are important pieces for the web platform in our mind. |
Ugh, apologies if this didn't get to you sooner. I kicked this off in April and got word from @annevk in May, but somehow we didn't manage to find you in the process.
I believe the original intent in (1) and (2) are preserved. I think, one of the differences from the original text, is that we turn (1) and (2) into concrete ways that it helps very specific APIs (e.g. the FedCM API and the Storage Access API) in very concrete terms. So, while the intent and intuitions are kept, the concrete first step in applying them is probably less ambitious than the full potential of this API, which is that's by design and deliberate: in one hand, we designed the API to be extensible such that it can be used, incrementally and gradually, to more and more meaningful ways that the Web Platform can take this signal in and on the other hand, we defined a couple of specific ways that it can be useful right now to specific applications. I think the only way to bootstrap this API is to start with concrete and useful ways in which it provides value to the Web Platform.
I believe we are in agreement, but I think you should be the judge of that. Read/review the explainer text in this PR, and make suggestions to make sure that your intent is captured.
Logout is defined in this PR, and needed by FedCM. Would that be sufficient? |
|
||
```javascript | ||
Sign-in-Status: type=idp, action=signin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw, this needs to be ; instead of ,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also prefer Signin-Status over Sign-in-status
I didn't mean to imply that Anne hasn't discussed it with me. I only meant that I assume this has been discussed at PrivacyCG meetings and I haven't been present. |
This has been discussed in a Privacy CG meeting indeed (and you were, indeed, not present), albeit briefly: meeting notes here. The AI that I took was to kick off this bug and go from there (which is this PR). |
|
||
interface LoginStatusOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably be a dictionary and should have a boolean idp
member?
I am undecided on whether logout should also have the idp member or not, hmm
Here’s how the API for checking the login status could look: | ||
```javascript | ||
partial interface Navigator { | ||
Promise<void> setLoggedIn(optional LoginStatusOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would recordLogin be a better name?
Also, with the header being named Signin-Status
, should this use setSignedIn
/recordSignin
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my preference is to consistent with the header, so setSignedIn()
and setSignedOut()
. I dislike the record
prefix, that feels foreign (is there any other API that has that prefix?), but not a hill I'm wiling to die on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no strong opinion; @bvandersloot-mozilla suggested record* in w3c-fedid/FedCM#430 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The set
prefix is also weird because it seems like a setter but this is not. How about just logIn
/ logout
or signIn
/ signOut
? Or maybe report
instead of record
since it’s the site telling the browser?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also what’s with the Signin-Status
header and is that beyond being renamed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the header, we got feedback that a JS API is not enough for certain cases, so we also added an HTTP header for that purpose. It works more naturally IMO when a website redirects to the real destination after login; you'll just send the header in response to the form POST + redirect to the real destination without needing an intermediate page that calls the JS API (or adding the JS call to every page that you might get redirected to)
We are totally open to renaming it and/or changing the syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think report
makes sense as the word used here.
This removes "IDP" from the HTTP header and JS API names so that they are more compatible with the is-logged-in API: https://github.com/privacycg/is-logged-in See also privacycg/is-logged-in#54 Open question: Should the JS API use the exact name in the current is-logged-in explainer (recordLoggedIn) or the more consistent name that this PR uses (recordSignedIn)?
* Use generic names for the header and JS API This removes "IDP" from the HTTP header and JS API names so that they are more compatible with the is-logged-in API: https://github.com/privacycg/is-logged-in See also privacycg/is-logged-in#54 Open question: Should the JS API use the exact name in the current is-logged-in explainer (recordLoggedIn) or the more consistent name that this PR uses (recordSignedIn)? * grammar fixes
A bit late to this but wanted to add my support for this statement by Sam:
and note that based on @johnwilander it sounds like we're thinking of different APIs, with the main difference being whether or not the login status is a "trusted" signal (one that can't be set by the site for their own gain) or a site-provided signal that the browser will use to enhance the user experience and provide utility to sites in ways that won't be desirable for other sites without the signal. For the former use case, I'm not sure I really see any concrete ideas of execution / utility on the web right now, which is likely to further stall development of the API because of unclear timelines and requirements. I'd like to focus on what we know we can achieve. |
It is critical that we get the design of incentives right, but I don't think that what @johnwilander has in mind is necessarily in conflict with he API that has been proposed in this PR here: we could decide later to create an extension that has the properties that make the signal "trusted", e.g. via prompting the user (either as a modal dialog or a non-modal dialog -- such as a status indicator) such that the browser would be able to be confident enough to respect this signal. We can cross this bridge when we get there, but here is a code snippet of what that might look like, with what's being proposed: // Prompts the user for confirmation
navigator.setLoggedIn({
prompt: true, // prompts the user for confirmation, prompt: "indicator" may not prompt but indicate
profile: {
name: "John Doe",
picture: "https://website.com/john-doe/profile.png",
}
}); That is, we designed the API to be extensible enough that it can cover a good amount of ground between "self-declared" signals to "user-approved" signals, so I think a good spectrum of UX choices can be covered with this design. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR contains many not entirely related changes, resulting in a near-total rewrite. Some are style changes, some are API signature changes, and some totally change the security model. It would be easier to review if broken up into smaller PRs.
That said I left some comments.
Here’s how the API for checking the login status could look: | ||
```javascript | ||
partial interface Navigator { | ||
Promise<void> setLoggedIn(optional LoginStatusOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The set
prefix is also weird because it seems like a setter but this is not. How about just logIn
/ logout
or signIn
/ signOut
? Or maybe report
instead of record
since it’s the site telling the browser?
Here’s how the API for checking the login status could look: | ||
```javascript | ||
partial interface Navigator { | ||
Promise<void> setLoggedIn(optional LoginStatusOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also what’s with the Signin-Status
header and is that beyond being renamed?
### Defending Against Abuse | ||
|
||
If websites were allowed to set login status whenever they want, it | ||
would not constitute a trustworthy signal and would most likely be | ||
abused for user tracking. We must therefore make sure that login status | ||
can only be set when the browser is convinced that the user meant to log | ||
in or the user is already logged in and wants to stay logged in. | ||
|
||
Another potential for abuse is if websites don’t call the logout API | ||
when they should. This could allow them to maintain the privileges tied | ||
to login status even after the user logged out. | ||
|
||
There are several ways the browser could make sure the login status | ||
is trustworthy: | ||
|
||
* Require websites to use WebAuthn or a password manager (including | ||
Credential Management) before calling the API. | ||
* Require websites to take the user through a login flow according to | ||
rules that the browser can check. This would be the escape hatch for | ||
websites who can’t or don’t want to use WebAuthn or a password manager | ||
but still want to set login status. | ||
* Show browser UI acquiring user intent when login status is set. | ||
Example: A prompt. | ||
* Continuously show browser UI indicating an active login session on | ||
the particular website. Example: Some kind of indicator in the URL | ||
bar. | ||
* Delayed browser UI acquiring user intent to stay logged in, shown some | ||
time after the login status was set. Example: Seven days after login | ||
status was set – “Do you want to stay logged in to news.example?” | ||
* Requiring engagement to maintain login status. Example: Require user | ||
interaction as first party website at least every N days to stay | ||
logged in. The browser can hide instead of delete the credential token | ||
past this kind of expiry to allow for quick resurrection of the login | ||
session. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the justification for the removal of this section and replacement with the much weaker “Assumption of Abuse”? It seems like the new explainer doesn’t require or even permit UAs to try to prevent dishonest use of the login status API, and instead tells them to assume the signal may be dishonest. This defeats the original purpose of this API as described by @johnwilander .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think spirit of this section is represented through the explainer via specific and concrete ways in which a browser can "defending against abuse". That is, rather than a section on "ways the browser could make sure the login status is trustworthy" we are proposing "two specific ways (FedCM and SSA) that the browser could read this signal and trust its veracity -- and, in the future, if we find other ways, we can extend this API to introduce them".
I'd be happy to bring parts of this section back, but I hope that we didn't go as far as defeating the original purpose of this API as @johnwilander intended it to be.
If we did, and you and @johnwilander don't feel that this explainer reconciles with the spirit Login Status API, we could still go back to using our FedCM-specific Sign-in-Status API, and we'd be OK with that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happy to bring parts of this section back, but I hope that we didn't go as far as defeating the original purpose of this API as @johnwilander intended it to be.
Maybe we could start by iterating on the PR to bring all of it back? I do not understand why deleting any of it is necessary to your other changes. If it is, please explain.
If we did, and you and @johnwilander don't feel that this explainer reconciles with the spirit Login Status API, we could still go back to using our FedCM-specific Sign-in-Status API, and we'd be OK with that too.
I'm confused. Are you saying you are willing to bring back some/all of this section (b/c I think removing it does not align with the original spirit of Login Status API), or we have to take this PR as-is or you'll diverge and ship your own thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think that there's an initial conflict between the goals stated in the original explainer ("If websites were allowed to set login status whenever they want, it would not constitute a trustworthy signal") and how this PR changes things (by allowing websites to set login status whenever they want).
As Sam mentions in #54 (comment) this can probably be overcome, so I think the larger question here is can we find some convergence between the two ideas that leaves the door open for WebKit's login status idea, for the benefit of developers who wouldn't have to deal with two very similar signals.
If we think we can, then I don't think it makes sense to restore this section as-is, as that would be incompatible with some new ideas presented in this PR. Rather, we should adapt it to whatever compromise we arrive at (e.g. a prompt
or trusted
flag in the setLoggedIn
call as Sam suggests in his comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do those things, but shouldn't trustworthiness considerations in the Explainer cover the whole span of envisioned use cases, not just the FedCM one?
I think the key part here to make sure we are on the same page is to whether to capture in the explainer (and the spec) what we hypothetically could do or what we are actively planning to do: we propose we focus on the latter. We don't have any active plans to use this API outside of the direct use of FedCM and (possibly) SAA, which are both described in the explainer as concrete things that we would like to do do. We think it is plausible that it could hypothetically be used for other things, so we think it makes sense to have this more general API, but we wanted to be clear that we haven't yet found other uses where the design of incentives and the economics of abuse align.
I'm confused. Are you saying you are willing to bring back some/all of this section (b/c I think removing it does not align with the original spirit of Login Status API), or we have to take this PR as-is or you'll diverge and ship your own thing?
It is important to make sure that we are clear that we haven't found (nor are proposing) use of the Login Status API outside of FedCM (and, as I said, possibly, the Storage Access API), so if you are expecting that this proposal will offer a concrete way in which a website can declare their Login Status in a way that we think that the browser can generally trust (again, outside of how FedCM/SAA would use), then yes, I think this proposal isn't aligned with the original spirit of the Login Status API (and hence, naturally, we'd be happy to make it FedCM-specific).
We do, however, remain of the opinion that, while this is a constrained use of the Login Status API (for FedCM and SAA specifically), it can be designed to be extensible for further user, and hence, is worth using a generalizable/extensible API, so our preference is this PR to be accepted so that we can make FedCM depend on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t know where it got lost in this conversation, but we’ve been clear from the get go that we want a trustworthy signal as to 1) which websites it’s most important to maintain state for, and 2) which websites the user has an established relationship with and is more likely to want to enable powerful but risky features for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t know where it got lost in this conversation, but we’ve been clear from the get go that we want a trustworthy signal as to 1) which websites it’s most important to maintain state for, and 2) which websites the user has an established relationship with and is more likely to want to enable powerful but risky features for.
I think the disconnect may be on how we are using the term trustworthy
: what's written in this PR is trustworthy within the thread model of the specific proposals trying to consume it (FedCM and SAA).
We haven't thought it through, but the intuition is that it is not trustworthy
within other threat models, including ones involving what's listed here (e.g. clearing storage, etc), so we are hesitant in introducing those models without having any plans to ship them.
In this proposal, we are (a) proposing a couple of uses that we think that the bit can be used in a trustworthy
way (again, within the threat model of how FedCM and SAA operate) and (b) leaving the extensibility points so that other abuse models can be introduced as it goes along (e.g. so that, as they get introduced, it is easier / incremental for developers to adopt).
1. Self-declared: any website can and will lie to gain any advantage | ||
2. Client-side: the state represent the website's client-side knowledge of the user's login status, which is just an approximation of the server-side's state (which is the ultimate source of truth) | ||
|
||
One potential for abuse is if websites don’t call the logout API when they should. This could allow them to maintain the privileges tied to login status even after the user logged out. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the potential for abuse if sites call the login API when the user is not actually logging in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specific use being proposed as the first extension of the Login Status API is for FedCM (and possibly the Storage Access API) to use the signal.
In both of these cases, the consumers (FedCM/SAA) have to construct the use of the signal in such a way that assume the signal is self-declared. So, for FedCM specifically, we show an "Error/mismatch UI" when the information we get from (a) the Login Status API and (b) the accounts endpoint returns. The user experience of the Error UI is constructed in such a way that a valid / honest Identity Provider wouldn't want to abuse itself (by lying to the browser), and an dishonest IdP would just show Error UIs to users.
The same occurs for dishonest/honest Identity Providers lying about the user logging-out.
We have constructed the extension of the Login Status API such that a website self-declares its status as an Identity Provider:
// Records that the user is logging-in to a FedCM-compliant Identity Provider.
navigator.setLoggedIn({
idp: true
});
The idp: true
parameter indicates that the website is declaring itself as a FedCM-compatible IdP (which is not game-able). Any other Web Platform API that wanted to consume this signal would have to either (a) have to work within the FedCM assumptions of abuse or (b) extend the Login Status API.
For example, @johannhof is making the case that the SSA API can take this signal as is, so could reuse this signal with:
// Records that the user is logging-in, which allows the Storage Access API to conditionally dismiss its
// UX.
navigator.setLoggedIn();
// In another cross-site top-level document, auto-reject rSA (with some delay to avoid timing attacks) unless the user is logged in
document.requestStorageAccess({rejectUnlessLoggedIn: true}).then(...);
The signal doesn't have to always be self-declared, it can be mediated by the user too. So, for example, we could extend the Login Status API to have a browser prompt (or perhaps just a status indicator), that would make the change visible enough that a browser would be able to trust it as acknowledged by the user.
navigator.setLoggedIn({
profile: {
name: "John Doe",
picture: "https://website.com/john-doe/profile.png",
}
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do those things, but shouldn't trustworthiness considerations in the Explainer cover the whole span of envisioned use cases, not just the FedCM one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does cover use cases that are designed in a way where site-declared login status can safely provide user benefits. Maybe it makes sense to call this a "base" or "untrusted" tier and have another tier for "trusted" applications of the API?
Agreed that it makes it harder to review, but it seemed useful for the original authors to look at the entirety of the changes proposed as a whole, rather than in isolation.
Yeah, we don't feel too strongly about what the names of the methods are ... I agree that What about
Nope, not beyond renaming, it is part of this proposal. We have the
Responding to other comments inline. |
I'm going to close this pull request based on the conclusion that we all collectively arrived at TPAC here. |
Hey all,
Just following on #53.
I took the time to write down how, concretely, we think FedCM could reconcile with the Login Status API in this PR. You can see a preview of the text here.
@bvandersloot-mozilla, does this make more or less sense to you?
I didn't include a spec, since I wanted to try to gather some convergence at a high level before writing spec language.
I worked with @johannhof who is also interested in exploring how/whether this would help the Storage Access API, and he wrote a section on how that may play out to give you all a sense of how we think this may evolve.
@johnwilander WDYT?