Closed Bug 1395349 Opened 7 years ago Closed 7 years ago

Invent a way to support CLI logins

Categories

(Taskcluster :: Services, enhancement)

enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: dustin, Assigned: dustin)

References

Details

We do this sort of thing a lot: $ taskcluster login <browser opens at https://login.taskcluster.net?redirect=http://localhost:1234> <user clicks around> <server on localhost gets credentials, puts them on disk> Currently that will get you 3-day temporary credentials. The new endpoint would give you 15-minute credentials, which aren't that useful on the command line. Users will probably want to use a permacred for this purpose.
One solution I can see is for the CLI tool to send the browser to a tools page with ?redirect=..&name=.. Tools would then offer to create clientId mozilla-ldap/<email>/<name> or, if it exists, offer to reset its accessToken. In either case, it would redirect back to the URL with the clientId and accessToken. It feels like this would have UX issues with accessTokens getting reset if you try to use the same tool on two machines. And what scopes would this credential have by default? What expiration? --- Another solution is to amend the access-token modal to include some copy-pastable blob of text that includes both the clientId and the accessToken. The user flow would be: $ taskcluster login Login to https://tools.taskcluster.net/auth/clients and create a client for your use. When finished, paste the resulting credentialCode here: Y2xpZW50SWQ6IG1vemlsbGEtbGRhcC9kbWl0Y2hlbGxAbW96aWxsYS5jb20vdGMtY2xpLXRlbXAK YWNjZXNzVG9rZW46IFpHOWxjeUJ1YjNRZ2NtVnNiMkZrNG9DZExBazBNem8zWkRRMk5tRmxaVEF6 TlRjS01UWXNDVUoxWnlBNU1qWTBOalk2SUdacGVDQmgK Found clientId: mozilla-ldap/dmitchell@mozilla.com/tc-cli-temp Testing credentials.. success! $ https://github.com/taskcluster/taskcluster-client/pull/40 touched on this, and we rejected it at the time as too complex. But now the login process is more sophisticated and incompatible with an ad-hoc webserver on localhost, so this is more appealing. It has the advantage of being a lot simpler than automatically creating/resetting clientIds (the first option). It also encourages users to create clients with the scopes they need rather than "all the scopes".
Could this be implemented entirely in the shell (i.e. no browser required, you log in on the command line directly)?
No, OIDC doesn't support that.
Eli, what do you think? The second ("another") solution is simpler but does require users to create a client in the UI. Do you think we could make that process a little easier for first-timers somehow?
Flags: needinfo?(eperelman)
I've been trying to think about this, as neither situation seems ideal for a CLI user. What about something like the following flow? 1. `taskcluster login` opens a browser to some login page with an ID in the URL to poll/listen for credentials, e.g. login.taskcluster.net/cli/abdef123456 2. The user continues through the browser login flow. Browser window closes on completion. 3. In the background, the CLI polls/listens for credentials at a URL correlating to the poll ID, e.g. login.taskcluster.net/wait-for/abcdef123456. This endpoint will publish credentials upon the browser logging in with the previous poll ID (or publish an error if failed). --- Still not ideal, but I think it gets us closer.
Flags: needinfo?(eperelman)
Those credentials will only last for 15 minutes, though.
Jonas, do you have thoughts here?
Flags: needinfo?(jopsen)
I like Eli's idea of not requiring the CLI tool listens to localhost. I see a few ways to workaround that: i) CLI client includes a public key in the query-string, accessToken is encrypted and published on pulse (notice that clients can listen to pulse over a websocket via. events.taskcluster.net) ii) Same as (i) but instead of using a public key, the CLI just includes 64 random bytes in the query-string to be used as a one-time pad (ie. we publish <random-bytes> XOR <accessToken> on pulse) (one-time pads are easier to use) iii) We build a taskcluster-token service or extend tc-auth or tc-secrets to cover the use-case where: 1) Process A creates a random token and passes it to process B 2) Process B starts polling for a secret using the random token 3) Process A creates secret associated with random token 4) Process B gets the secret (this can be retried until step 5 is done) 5) Process B calls delete for random token (invalidating the token) (this flow is also useful for aws-provisioner when issuing temporary credentials to workers) As for the 15min limit we probably want to use taskcluster-tools, like tools.taskcluster.net/sessions, this tool would create permanent credentials set to expire in 3-7 days (or so) and auto-delete. The clientId would be named: mozilla-ldap/<email>/sessions/<session-id> Hence, the tools.taskcluster.net/sessions would ask the user for <session-id>, maybe ask what the expiration should be, and what scopes to pass to the session. All these could have sane defaults. I suggest a flow like: A) CLI client generates random <token> B) CLI client opens URL in browser: tools.taskcluster.net/sessions/new#token=<token> (choice of # is deliberate, as fragment is never sent to the server) We probably also include: &sessionId=...&scopes=...&description=...&expiration=... Where these are default values or suggestions. C) tools.taskcluster.net/sessions/new#... 1) Reads the window.location.hash, clears it, and fills out a form (putting -N on session-id if already used) 2) user logins on tools.taskcluster.net, adjusts scopes, expiration, session name, etc.. and clicks "Grant Access" 3) ClientId is created with expiration, description, scopes, etc... 4) Access token is posted to tc-secrets or something where it can fetched using <token> D) CLI client is long-polling tc-secrets for <token> For added security, maybe we include two random tokens, one for polling for the secret, and one for use as one-time pad.
Flags: needinfo?(jopsen)
It's mostly the tools flow I was interested in. I like your suggestion of using "sessions". When tc-login starts generating permacreds -- and especially when those are using a variety of scopes -- it can use the session model, too. Maybe we'll make permacreds with less than full-user-credentials last more than 15 minutes :) I'd like to avoid storing the accessToken, and I'd like to avoid implementing long-polling. For the first, I think we could have the CLI tool hit an API endpoint, and that endpoint would verify the token and sessionId against an Azure table, then call resetAccessToken on the clientId and return the accessToken. And remove the table row. Some kind of additional verification on that endpoint would be nice. For the second, I think the CLI tool could ask the user to hit enter once the session was complete, and also prompt them to do so in the tools UI -- and just call the API endpoint at that time. It seems like the session backend would be best implemented in the login service, with the session frontend implemented in tools. We'll need to implement the CLI side support in at least Python, JS, and Go (to heck with Java). Suddenly this becomes a pretty substantial scope of work. Is it worth it? Over the last 3 days (as much logging as papertrail keeps), there is exactly one CLI login.
After an irc chat, I think we all agree something like the above would be pretty cool, although there's details to work out. But for the moment something simpler is called for. The proposal we roughly nodded along to was this: * keep with the localhost server and redirect flow, but open a browser to a https://tools.tc.n URL * that URL will allow the user to create a new client, with details filled in based on info from the CLI tool (name, description, expiration, etc.) * expiration will default to 24h and have a maximum of 30 days - if you want permanent permacreds, use the client editor * if necessary, tools will send the user through the Auth0 login process first * once the client is created, the tools page will redirect back to the localhost server with the resulting clientId/accessToken This has a few advantages: * no new services or endpoints * minor change to the clients (and we can add a redirect from https://login.taskcluster.net to help) * usable for "development logins" for apps requiring TC creds, such as tools
Eli, any chance I could lean on you to implement this?
Eli's going to work on the UI side of this. I'll change the CLI clients and the "development login" for tools.
Assignee: dustin → eperelman
Blocks: 1404461
Assignee: eperelman → helfi92
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
I still have my half of this project to complete :)
Assignee: helfi92 → dustin
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Commits pushed to master at https://github.com/taskcluster/taskcluster-tools https://github.com/taskcluster/taskcluster-tools/commit/fda958b198cf1efe00c82633f631e3b03b0fad13 Bug 1395349 - use the production site for devel logins https://github.com/taskcluster/taskcluster-tools/commit/1665d4db0c52d4dc9afe76c07cb0bab7b613287c Bug 1395349 - allow no scopes at all in client creator This allows `?scopes=` to defeat the default (`?scopes=*`) and create a client with no scopes at all (unless the user adds scopes, of course).
Status: REOPENED → RESOLVED
Closed: 7 years ago7 years ago
Resolution: --- → FIXED
Component: Login → Services
You need to log in before you can comment on or make changes to this bug.