Generate TC credentials based on a CIS profile

RESOLVED FIXED

Status

Taskcluster
Login
RESOLVED FIXED
5 months ago
5 months ago

People

(Reporter: dustin, Assigned: dustin)

Tracking

Details

(Assignee)

Description

5 months ago
Breaking off from bug 1385363.
(Assignee)

Comment 1

5 months ago
Here's how the existing stuff works:

 * User authenticates with one of a few providers; gets an identity shaped like <provider>/<email>
    email/dustin@mozilla.com -- authenticate with email code
    mozilla-ldap/dustin@mozilla.com -- authenticate with LDAP
 * Based on the provider, user is further authorized by querying backend services
    email -- query mozillians, add `assume:mozillians-group:<group>` for each group
    mozilla-ldap -- mozillians as above, plus LDAP: add `assume:mozilla-group:<group>` for each LDAP group
 * add scopes to manage clientIds with the prefix `<provider>/<email>/`
 * return resulting credentials
 * periodically ensure that such clients do not have scopes beyond those allowed to the corresponding user

A few things are different with Auth0:

 * we don't get a 'provider' of any sort
 * the email is less trustworthy (there's no way to know if it was authenticated with a code or with a password/mfa)
 * group names are a little different (<provider>_<group>)
 * we need the `user_id` to call the Auth0 Management API, and that is not an email
(Assignee)

Comment 2

5 months ago
Ah, I forgot, credentials also have `assume:mozilla-user:<email>` or `assume:mozillians-user:<username>` if either one matches.

My thinking is this:

 * identify as mozilla-auth0/<user_id>
 * grant `assume:user:mozilla-auth0/<user_id>`
 * grant scopes to manage clientIds with prefix `mozilla-auth0/<user_id>/`
 * for each group `<provider>_<group>` in groups (including the special case of LDAP groups with no `<provider>_` prefix),
   grant `assume:group:<provider>:<group>`.

A few implementation notes:
 * to keep credentials small, avoid granting roles if they don't exist in the auth service

 * user_id contains `|`.  That's not currently valid in a clientId or roleId, but maybe it should be? jonas? alternately we could do some simple encoding of `|` as `@` or something (encoding `@` as `@@` to ensure it's one-to-one)

 * I have no idea how to distinguish an LDAP group from a non-LDAP group.  Take `vpn_default` for example: is that an LDAP group or the `default` group in the `vpn` provider?  Maybe we should just use the group names as given?  Or, kang, could this be disambiguated in the profile schema?
Flags: needinfo?(jopsen)
Flags: needinfo?(gdestuynder)
while we can say which groups are ldap or non-ldap right now they're indeed melded into the same attribute (because compatibility issues).

Right now: if it starts with `mozilliansorg_` (and soonish `workday_`) then it is not an LDAP group, otherwise it is (these are reserved and are not used by LDAP)
Flags: needinfo?(gdestuynder)
(Assignee)

Comment 4

5 months ago
That seems like a sec issue waiting to happen.. but I suppose it's up to the folks managing CIS and the LDAP groups to avoid any ambiguity.
I'm not sure I like the idea of using auth0 <user_id>. Is there anyway to know if it was an LDAP auth or an email-only auth?
If there is no ldap groups granted it an email-only auth, right? Hence, I think we can determine if it was a password/mfa or passwordless/email-only.

> * to keep credentials small, avoid granting roles if they don't exist in the auth service

If you're doing a major refactoring of tc-login, you could go create a clientId that is set to expire instead of creating temporary credentials..  We talked about that a while ago.
But yeah, a list of group names loaded from config also works.


> * user_id contains `|`.  That's not currently valid in a clientId or roleId, but maybe it should be?

I guess it could be... Right now clientId/roleId allows [A-Za-z0-9@/:._-]
I think this is arbitrarily determined as the minimum we needed to keep things simple.
IMO, it's nice that it's url-safe, | isn't url-safe.
Flags: needinfo?(jopsen)
(Assignee)

Comment 6

5 months ago
> I'm not sure I like the idea of using auth0 <user_id>. Is there anyway to know if it was an LDAP auth or an email-only auth?

The `identities` field of a response may contain some useful information:

https://auth0.com/docs/api/management/v2#!/Users/get_users_by_id
https://auth0.com/docs/user-profile/normalized#additional-attributes
  "identities": [
    {
      "user_id": "Mozilla-LDAP|djmitche",
      "provider": "ad",
      "connection": "Mozilla-LDAP",
      "isSocial": false
    }
  ],

That still doesn't give us an LDAP email, but does break out the connection and provider. Still, I'm not sure why we need that information?  Aside from compatibility with current per-user roles..

> If there is no ldap groups granted it an email-only auth, right? Hence, I think we can determine if it was a password/mfa or passwordless/email-only.

As Guillaume and I discussed above, the groups information doesn't give any indication as to what is an LDAP group and what is not.  I'm not sure whether we will even get CIS profiles for email logins..

> If you're doing a major refactoring of tc-login, you could go create a clientId that is set to expire instead of creating temporary credentials..  We talked about that a while ago.
> But yeah, a list of group names loaded from config also works.

I'd like to avoid config in taskcluster-login.  We currently have a group whitelist, and I'd like to get rid of that, instead only including a role if that role is defined in tc-auth.

There are other options that would involve more configuration or even a UI, but for the moment the future behavior of OIDC with regard to profiles, account linking, and so on is a big unknown, so I would like to remain a thin wrapper around what we are given -- at least until that stabilizes.
(Assignee)

Comment 7

5 months ago
Just scheduled a brainstorming session about this, so hopefully we can together come up with an idea better than anything I can do alone.  https://public.etherpad-mozilla.org/p/dustin-tc-auth0-profiles
(Assignee)

Comment 8

5 months ago
We selected this option:

Proposal 2 (COMPAT):
     * return clientId based on profile.identities
        for ad|Mozilla-LDAP: `mozilla-ldap/<profile.email>`
        for email|email: `email/<profile.email>`
        for github|github: `github/<profile.nickname>`
     * create groups using existing code (querying the LDAP servers and Mozillians directly)
     * add support for querying github repos as above for `github/<nickname>`

This nicely maintains compatibility with the roles and clientIds we have set up now.

It relies on the Mozillians API and LDAP server for authorization; it just uses auth0 for authentication.

From a client's perspective, this is forward-compatible -- whatever we do on the backend to better generate scopes, it will still be the same API call, and the same `full-credentials` scope.

This basically amounts to keeping our existing "account linking" support (login with LDAP -> get mozillians groups anyway) until such time as IAM's linking is more mature.

Comment 10

5 months ago
Commits pushed to master at https://github.com/taskcluster/taskcluster-login

https://github.com/taskcluster/taskcluster-login/commit/743ce964934477bb6b2fb7670515b6799b30f194
Bug 1392307 - use auth0 profile only to authenticte the user

Translate the auth0 profile to the existing user identity (email/..,
mozilla-ldap/.., or a new github/<nick>).  Continue to use the existing
authorizers to add scopes based on those identities.

We can improve on this when richer profiles are available from auth0.

https://github.com/taskcluster/taskcluster-login/commit/07f22b8969e2ee958389f9eb8d480f0f5c1ef311
Merge pull request #56 from djmitche/bug1392307

Bug 1392307 - use auth0 profile only to authenticate the user
(Assignee)

Comment 11

5 months ago
This is creating the following scopes for me (omitting mozilla-group:<group> and mozillians-group:<group>)

    assume:mozilla-user:dmitchell@mozilla.com
    assume:project:taskcluster:tutorial
    auth:create-client:mozilla-ldap/dmitchell@mozilla.com/*
    auth:delete-client:mozilla-ldap/dmitchell@mozilla.com/*
    auth:reset-access-token:mozilla-ldap/dmitchell@mozilla.com/*
    auth:update-client:mozilla-ldap/dmitchell@mozilla.com/*
    queue:create-task:aws-provisioner-v1/tutorial
    secrets:get:garbage/*
    secrets:set:garbage/*
(Assignee)

Comment 12

5 months ago
Fixed in

https://github.com/taskcluster/taskcluster-login/commit/1b3de7d5eaa4330974f5eb90e438df829399e89a

I now get creds with the appropriate scopes in the oidc demo.  YAY!
Status: NEW → RESOLVED
Last Resolved: 5 months ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.