Skip to content
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

Out of band flow not working #594

Closed
ianlewis opened this issue Aug 3, 2022 · 13 comments · Fixed by #698
Closed

Out of band flow not working #594

ianlewis opened this issue Aug 3, 2022 · 13 comments · Fixed by #698
Labels
bug Something isn't working

Comments

@ianlewis
Copy link

ianlewis commented Aug 3, 2022

Description

The auth process in gitsign outputs a URL you should be able to open in the browser to get a verification code, but the oauth2 server redirects to localhost after logging in. In this case localhost is not accessible so the auth flow cannot complete.

$ git commit -m "foo"
error opening browser: exit status 3
Go to the following link in a browser:

         https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=P69wZPuonUkCS2-LAp26XO-Ndw3GzeyATyuixsMRz7c&code_challenge_method=S256&nonce=xxx&redirect_uri=http%3A%2F%2Flocalhost%3A45077%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=xxx
Enter verification code:

Version

gitsign v0.2.0

@ianlewis ianlewis added the bug Something isn't working label Aug 3, 2022
@ianlewis
Copy link
Author

ianlewis commented Aug 3, 2022

In the case of out of band flow, I believe the redirect_uri should be urn:ietf:wg:oauth:2.0:oob

@ianlewis
Copy link
Author

ianlewis commented Aug 3, 2022

If you change the redirect_uri yourself, the client then fails to verify the code.

Enter verification code: error getting signer: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_request","error_description":"redirect_uri did not match URI from initial request."}

@dekkagaijin
Copy link
Member

Howdy!

Currently, only the redirect-based browser flow is implemented. I suppose it's been on my backlog long enough now :p

@ianlewis
Copy link
Author

ianlewis commented Aug 3, 2022

Thanks. It seems mostly there:

if err := browserOpener(authCodeURL); err != nil {
// Swap to the out of band flow if we can't open the browser
fmt.Fprintf(i.GetOutput(), "error opening browser: %v\n", err)
code = i.doOobFlow(&cfg, stateToken, opts)
} else {
fmt.Fprintf(i.GetOutput(), "Your browser will now be opened to:\n%s\n", authCodeURL)
code, err = getCode(doneCh, errCh)
if err != nil {
fmt.Fprintf(i.GetOutput(), "error getting code from local server: %v\n", err)
code = i.doOobFlow(&cfg, stateToken, opts)
}
}

If you manually change the redirect_uri in the URL you're given you do get a verification code from the server, but the client fails to verify it because the client checks the redirect_uri when it verifies the verification code.

I think it should be just a matter of making sure the redirect_uri is set to the oob URI but I haven't tested it yet.

@dekkagaijin
Copy link
Member

dekkagaijin commented Aug 10, 2022

For documentation:

Google has decided to deprecate the Out-Of-Band flow without replacement. The closest alternative is the device flow (i.e. enter this code at this URL), or simply copy-pasting the long-lived refresh_tokens over to the application. Both alternatives have their own unique downsides, which merit discussion...

@ianlewis
Copy link
Author

My personal use case is authentication on a remove development machine I access over ssh. I don't have access to a browser local to the server, though I suppose I could try to use a text based browser like lynx or something.

I could also do the normal browser-based flow with port-forwarding from the local machine to the server, but the app would need to give me the url that I can paste into my browser. I'm not sure that's a great UX but it would require minimal work to support.

@lukehinds
Copy link
Member

can we close this for now @ianlewis or do you still need anything addressed?

@ianlewis
Copy link
Author

can we close this for now @ianlewis or do you still need anything addressed?

I think there should to be some way to support authentication on a machine other than the one the browser is on (e.g. ssh to a dev server). Either by supporting the out-of-band flow, the device flow that @dekkagaijin mentioned, or explicitly support port forwarding as I mentioned. I don't really consider using a console browser as a valid workaround.

@lukehinds
Copy link
Member

We already support device flow though, is this lacking somehow https://github.com/sigstore/sigstore/blob/main/pkg/oauthflow/device_test.go ?

@ianlewis
Copy link
Author

We already support device flow though, is this lacking somehow https://github.com/sigstore/sigstore/blob/main/pkg/oauthflow/device_test.go ?

Apologies, I wasn't aware of device flow or how to invoke it. Perhaps it's simply that gitsign isn't supporting the device flow. Can gitsign theoretically fall back to using a device flow if the browser can't be opened?

gitsign seems to be using the InteractiveIDTokenGetter. IIUC, in order to implement device flow then gitsign would need to use the DeviceFlowTokenGetter.

When the browser can't be opened, the InteractiveIDTokenGetter as it stands currently falls back to the OOB flow (which is broken and apparently not supported) and not the device flow. This may be a separate issue, but if it's not supported and not intended to be supported in the future then I'm not sure why the code is there.

So as far as sigstore is concerned I'd say the following could be actionable:

  1. Consider removing the OOB code entirely.
  2. Consider falling having InteractiveIDTokenGetter fall back to device mode rather than OOB.
  3. If 2 is not feasible, what could the application do? Can the application itself implement a fallback to the device flow if the browser can't be opened? If it's not possible currently, consider adding support for a device flow fallback.

@lukehinds
Copy link
Member

Apologies, I wasn't aware of device flow or how to invoke it. Perhaps it's simply that gitsign isn't supporting the device flow. Can gitsign theoretically fall back to using a device flow if the browser can't be opened?

Not a problem. I can't confess to know the gitsign code very well, but it should in theory be capable of falling back to device flow. It makes sense to have such a feature as many folks code in remote envs.

I recommend kicking the conversation off over at sigstore/gitsign, in the meantime happy to keep this open so if we need to adjust things on this side, we can do.

@ianlewis
Copy link
Author

Apologies, I wasn't aware of device flow or how to invoke it. Perhaps it's simply that gitsign isn't supporting the device flow. Can gitsign theoretically fall back to using a device flow if the browser can't be opened?

Not a problem. I can't confess to know the gitsign code very well, but it should in theory be capable of falling back to device flow. It makes sense to have such a feature as many folks code in remote envs.

I'm not sure how that can happen currently without gitsign reimplementing the InteractiveIDTokenGetter itself as it falls back to to the out-of-band flow instead of returning an error.

I recommend kicking the conversation off over at sigstore/gitsign, in the meantime happy to keep this open so if we need to adjust things on this side, we can do.

I opened sigstore/gitsign#137 to track the issue there.

@wlynch
Copy link
Member

wlynch commented Sep 17, 2022

This problem isn't unique to gitsign - verified this also affects cosign. 🙃

Opened a fix in #698 that I've verified works with gitsign.

Google has decided to deprecate the Out-Of-Band flow without replacement.

IIUC this only affects users who are using the Google OIDC issuer directly, but this won't affect default clients using oauth2.sigstore.dev since Dex still supports the oob flow (until if/when Dex also decides to deprecate it). I'm fine with moving to device flow as the default for interactive, though would prefer to make that change in s/s so that cosign and gitsign are consistent.

The closest alternative is the device flow (i.e. enter this code at this URL), or simply copy-pasting the long-lived refresh_tokens over to the application. Both alternatives have their own unique downsides, which merit discussion...

I'd prefer not to persist long lived creds if we can avoid it. I think the device code based approach is fine, especially if we pair it with https://github.com/sigstore/gitsign/tree/main/cmd/gitsign-credential-cache so that only short-lived secrets are persisted and only need to be entered every 10 mins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants