Skip to content

rfc: OAuth Login#43

Merged
alanshaw merged 2 commits intomainfrom
feat/email-based-oauth-login
Feb 25, 2025
Merged

rfc: OAuth Login#43
alanshaw merged 2 commits intomainfrom
feat/email-based-oauth-login

Conversation

@alanshaw
Copy link
Member

@alanshaw alanshaw commented Feb 22, 2025

@alanshaw alanshaw requested a review from a team February 22, 2025 21:55
Copy link
Member

@fforbeck fforbeck left a comment

Choose a reason for hiding this comment

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

Looks pretty solid. I have only one question about the max URL length.


When authenticatiing against OAuth applications it is often possible to pass state from the client requesting authorization to the OAuth callback that is called on successful authentication.

We propose passing a signed `access/authorize` delegation as the state.
Copy link
Member

Choose a reason for hiding this comment

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

I like the idea. We should double-check whether the base64-encoded delegation might exceed any maximum URL length, in case the provider/third party has a hard limit. Do you know if there is one?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a self signed delegation so not too big. It ends up looking something like this:

https://github.com/login/oauth/authorize?scope=read:user,user:email&client_id=Ov23liRdyizj8EndxxAf&state=uOqJlcm9vdHOB2CpYJQABcRIgE9uVvE_TQhXk_1QQuJEhy9j7GSubl45VA9ig-ghIqVpndmVyc2lvbgHVAgFxEiAUNo1mMe-tBMFo3ab7kV4JgsZcLdzTKemQXYYmBSwOCKdhc1hE7aEDQNeAJWBBbGVPmzvbGFz3MSj3b78PSH3ag19LshSv5wum31oZ0U-7tIpyAVSjzg5moUz2i_FLJJlw1rX4APkvFQZhdmUwLjkuMWNhdHSBo2JuYqJjYXR0gaFjY2FuYSpjaXNzeBtkaWQ6bWFpbHRvOmV4YW1wbGUuY29tOnRlc3RjY2FucGFjY2Vzcy9hdXRob3JpemVkd2l0aHg4ZGlkOmtleTp6Nk1rdWRpQ3pwSm1zWlR1WTVCWGFYaUpSRGZlYVFCUDhDbzU2UzdUQTNvaEpMVWtjYXVkWBmdGndlYjp1cC5zdG9yYWNoYS5uZXR3b3JrY2V4cBpnuuK0Y2lzc1gi7QHhjLGTccIfFS-FIq_HARfXjbABkFk7JE_umxm1Y03W3WNwcmaAWQFxEiAT25W8T9NCFeT_VBC4kSHL2PsZK5uXjlUD2KD6CEipWqFqdWNhbkAwLjkuMdgqWCUAAXESIBQ2jWYx760EwWjdpvuRXgmCxlwt3NMp6ZBdhiYFLA4I

I have a test repo and can confirm this works fine. We create the delegation and login link here and decode and access it in the oauth callback here.

Copy link
Member

@fforbeck fforbeck left a comment

Choose a reason for hiding this comment

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

Looks good to me!

Copy link

@travis travis left a comment

Choose a reason for hiding this comment

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

I'm happy shipping this as-is, but I do have a question about using what is, according to our spec, a deprecated capability...


### Implementation details

Typically clients call `access/authorize` specifying the capabilities they want. Currently the client knows the `did:mailto` of the issuer they want to receive the authorization from, since this is the email address the user is trying to login with. As such it is currently a _required_ parameter of the invocation (`nb.iss`). In the OAuth flow we do not know the email address beforehand, so the (backwards compatible) proposal is to make this field **optional**.
Copy link

Choose a reason for hiding this comment

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

I just went to look up access/authorize and noticed it's deprecated:

https://github.com/storacha/specs/blob/main/w3-access.md#access-authorize

I don't actually remember why it was deprecated, and the "replacement" function seems not to be implemented yet:

https://github.com/storacha/specs/blob/main/w3-access.md#access-request

I think it was part of this work - I think this was part of the auth/client refactor we were trying to get out last year?

storacha/specs#104

Overall I'm not sure if this means we should try to get this new auth method in to access/authorize or access/request but I do wonder if this means we have another option here - access/request might be implemented in a way that supports this new OAuth stuff and we can fully deprecate access/authorize once we move the classic behavior in there too.

Open to whatever you think makes sense here!

Copy link
Member Author

Choose a reason for hiding this comment

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

The scope of adding access/request is too large for me to get done in time here. I think we'd also like to re-visit the replacement - the format for requesting capabilities looks like a precursor to the policy documents in UCAN 1.0.

Copy link

Choose a reason for hiding this comment

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

ok cool that makes sense to me!

alanshaw added a commit to storacha/w3up that referenced this pull request Feb 25, 2025
refs storacha/RFC#43

This PR adds a new method `externalLogin()` that allow login to the
system via an external method (e.g. OAuth). It essentially bypasses
email confirmation, assuming this is done out of band. We re-join the
regular auth flow at the point when we claim the delegation (and
attestation) from an email to the agent.
@alanshaw alanshaw merged commit 7acfdce into main Feb 25, 2025
@alanshaw alanshaw deleted the feat/email-based-oauth-login branch February 25, 2025 11:16
alanshaw added a commit to storacha/w3cli that referenced this pull request Feb 25, 2025
Allows login via github via:

```sh
w3 login --github
```

refs storacha/RFC#43
depends on storacha/w3up#1629
alanshaw added a commit to storacha/w3infra that referenced this pull request Feb 25, 2025
refs storacha/RFC#43

This PR adds a GitHub OAuth callback handler. It expects an
`access/authorize` delegation to be passed in the `state` querystring
paremeter. It completes the login flow by issuing a `access/confirm`
invocation on behalf of the user, which in turn issues the requested
delegations and attestations.

If the user is a new user they will be automatically enrolled in the
"trial" plan (`did:web:trial.storacha.network`). This plan does not
require payment details and so their `account` in the `customer` table
is blank.

The billing run will not consider these customers and neither will
egress accounting.

New signups with GitHub accounts must be at least 1 day old.
@Peeja
Copy link
Member

Peeja commented Mar 3, 2025

@alanshaw Apologies for the post-facto review, but one question: Can't the Agent/Client call the callback URL directly and get Storacha to attest it as any account it wants? We need Storacha to validate that the redirect actually came from the auth provider. We need to do something with the auth code we get back—that maybe means we need to exchange it for a token, even if we're never going to actually use that token. We need to see that exchange succeed.

@alanshaw
Copy link
Member Author

alanshaw commented Mar 3, 2025

@alanshaw Apologies for the post-facto review, but one question: Can't the Agent/Client call the callback URL directly and get Storacha to attest it as any account it wants? We need Storacha to validate that the redirect actually came from the auth provider. We need to do something with the auth code we get back—that maybe means we need to exchange it for a token, even if we're never going to actually use that token. We need to see that exchange succeed.

We do. We use the code sent to the callback to obtain an access token from github and then use the access token to obtain user profile details and email addresses.

@Peeja
Copy link
Member

Peeja commented Mar 3, 2025

@alanshaw Ah, great! Is that in here? Or was that decided afterwards/elsewhere? That's what I was looking for and couldn't find.

@alanshaw
Copy link
Member Author

alanshaw commented Mar 3, 2025

@Peeja #44

tx-ravenxbsw3 added a commit to tx-ravenxbsw3/w3up that referenced this pull request Sep 29, 2025
refs storacha/RFC#43

This PR adds a new method `externalLogin()` that allow login to the
system via an external method (e.g. OAuth). It essentially bypasses
email confirmation, assuming this is done out of band. We re-join the
regular auth flow at the point when we claim the delegation (and
attestation) from an email to the agent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants