Closed
Bug 1395349
Opened 7 years ago
Closed 7 years ago
Invent a way to support CLI logins
Categories
(Taskcluster :: Services, enhancement)
Taskcluster
Services
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.
Assignee | ||
Comment 1•7 years ago
|
||
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".
Comment 2•7 years ago
|
||
Could this be implemented entirely in the shell (i.e. no browser required, you log in on the command line directly)?
Assignee | ||
Comment 3•7 years ago
|
||
No, OIDC doesn't support that.
Assignee | ||
Comment 4•7 years ago
|
||
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)
Comment 5•7 years ago
|
||
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)
Assignee | ||
Comment 6•7 years ago
|
||
Those credentials will only last for 15 minutes, though.
Comment 8•7 years ago
|
||
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)
Assignee | ||
Comment 9•7 years ago
|
||
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.
Assignee | ||
Comment 10•7 years ago
|
||
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
Assignee | ||
Comment 11•7 years ago
|
||
Eli, any chance I could lean on you to implement this?
Assignee | ||
Comment 12•7 years ago
|
||
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
Assignee | ||
Updated•7 years ago
|
Assignee: eperelman → helfi92
Comment 13•7 years ago
|
||
Commits pushed to master at https://github.com/taskcluster/taskcluster-tools
https://github.com/taskcluster/taskcluster-tools/commit/3169ac172a7d54a12acad37d58b9cf4238e25f9b
Bug 1395349 - Invent a way to support CLI logins
https://github.com/taskcluster/taskcluster-tools/commit/edb67d523a8302313b1046448d7cbfda33c6d196
Merge pull request #364 from helfi92/login
Bug 1395349 - Invent a way to support CLI logins
Updated•7 years ago
|
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 14•7 years ago
|
||
I still have my half of this project to complete :)
Assignee: helfi92 → dustin
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Assignee | ||
Comment 15•7 years ago
|
||
Assignee | ||
Comment 16•7 years ago
|
||
Assignee | ||
Comment 17•7 years ago
|
||
Comment 18•7 years ago
|
||
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).
Assignee | ||
Updated•7 years ago
|
Status: REOPENED → RESOLVED
Closed: 7 years ago → 7 years ago
Resolution: --- → FIXED
Updated•6 years ago
|
Component: Login → Services
You need to log in
before you can comment on or make changes to this bug.
Description
•