Skip to content

Auth0 SSO/SAML Integration with CLI - #245

Merged
David Hyde (DABH) merged 26 commits into
masterfrom
auth0-sso
Aug 16, 2019
Merged

Auth0 SSO/SAML Integration with CLI#245
David Hyde (DABH) merged 26 commits into
masterfrom
auth0-sso

Conversation

@DABH

Copy link
Copy Markdown
Contributor

No description provided.

@DABH
David Hyde (DABH) requested a review from a team as a code owner August 2, 2019 07:51
Comment thread internal/pkg/auth-server/auth-server.go Outdated
@DABH David Hyde (DABH) changed the title [WIP] Auth0 SSO/SAML Integration with CLI Auth0 SSO/SAML Integration with CLI Aug 4, 2019
@codecov

codecov Bot commented Aug 4, 2019

Copy link
Copy Markdown

Codecov Report

❗ No coverage uploaded for pull request base (master@07450f3). Click here to learn what that means.
The diff coverage is 28%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #245   +/-   ##
=========================================
  Coverage          ?   40.28%           
=========================================
  Files             ?       61           
  Lines             ?     4629           
  Branches          ?        0           
=========================================
  Hits              ?     1865           
  Misses            ?     2523           
  Partials          ?      241
Impacted Files Coverage Δ
internal/pkg/sdk/user/user.go 0% <0%> (ø)
internal/cmd/local/bindata.go 0% <0%> (ø)
internal/cmd/auth/auth.go 67.42% <45.16%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 07450f3...d52dafd. Read the comment docs.

@codyaray Cody A. Ray (codyaray) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

auth code with pkce looks like the right flow for me, for now. i bet we could get a nicer "success" page, but this works for v1 anyway.

my main concerns

  1. we're opening a small security hole here that i think our auditors will dislike, in that the new check_email endpoint allows users to query whether emails exist directly. we were already flagged for giving too much info away like this at authentication time by them once or twice. Instead, can we have the user indicate whether they want to "login via SSO" with a new command or flag?

  2. we're exposing auth0 externally as part of our API and hardcoding a lot of API details into our CLI that shouldn't be there. We should really setup a proxy for a lot of this stuff (so instead of https://confluent.auth0.com/api/v2/authorize it looks like https://confluent.cloud/oauth/authorize). I think both Apache webserver and Nginx support this sort of proxying, or something like https://github.com/trondhindenes/Auth0Proxy (which configures apache in a docker container)

Comment thread .go-version Outdated
Comment thread internal/cmd/auth/auth.go Outdated
Comment thread internal/cmd/auth/auth.go
// Check if user has an enterprise SSO connection enabled. If so we need to start
// a background HTTP server to support the authorization code flow with PKCE
// described at https://auth0.com/docs/flows/guides/auth-code-pkce/call-api-auth-code-pkce
userSSO, err := client.User.CheckEmail(context.Background(), &orgv1.User{Email: email})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CheckEmail is like GetUserByEmail? And userSSO is just our normal ccloudapis User object?

This is a security hole, since it exposes an easy method for attackers to figure out which emails exist in our system without authenticating.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, except all the returned User object contains (if non-empty) is the email and sso field (everything else is blanked out).

The GUI also has always had the same "vulnerability" according to when I talked to FE team. cc laura-brouckman . So this is not an additional security hole, if you'd even consider it one.

And unfortunately there is no better way to do this without compromising the UX :(

We could consider not returning the email in the returned User object from the route, that might make it a bit more secure? So it's just sso or (no sso) or (no sso because invalid)? Wdyt?

@codyaray Cody A. Ray (codyaray) Aug 13, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should not make it obvious when a user exists or not.

Suggested output

(Nesting it inside "user" means it should be backwards compatible with the current GetUserReply-based output)

Exists with SSO:

200 OK HTTP/1.1
{
   "user": {
      "sso": {
        "enabled": true,
        "auth0_connection_name": "noah-okta-test"
      }
  }
}

Exists without SSO:

200 OK HTTP/1.1
{
   "user": {
       "sso": {
        "enabled": false,
        "auth0_connection_name": ""
      }
  }
}

Doesn't exist (identical to exists without SSO):

200 OK HTTP/1.1
{
  "user": {
      "sso": {
        "enabled": false,
        "auth0_connection_name": ""
      }
  }
}

Current Behavior

Exists with SSO

{
  "user": {
    "id": 0,
    "email": "david.hyde@confluent.io",
    "first_name": "",
    "last_name": "",
    "organization_id": 0,
    "deactivated": false,
    "verified": null,
    "created": null,
    "modified": null,
    "password_changed": null,
    "service_name": "",
    "service_description": "",
    "service_account": false,
    "sso": {
      "enabled": true,
      "auth0_connection_name": "noah-okta-test"
    }
  },
  "account": null,
  "organization": null,
  "error": null,
  "accounts": []
}

Exists without SSO:

{
  "user": {
    "id": 0,
    "email": "cody@confluent.io",
    "first_name": "",
    "last_name": "",
    "organization_id": 0,
    "deactivated": false,
    "verified": null,
    "created": null,
    "modified": null,
    "password_changed": null,
    "service_name": "",
    "service_description": "",
    "service_account": false,
    "sso": {
      "enabled": false,
      "auth0_connection_name": ""
    }
  },
  "account": null,
  "organization": null,
  "error": null,
  "accounts": []
}

Not exists

{
  "user": null,
  "account": null,
  "organization": null,
  "error": {
    "code": 404,
    "message": "User not found",
    "nested_errors": {},
    "details": [],
    "stack": null
  },
  "accounts": []
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, we will do this as a follow up PR in cc-gateway-service (should require no changes in CLI).

Comment thread internal/cmd/auth/auth.go
Comment thread internal/cmd/auth/auth.go Outdated
Comment thread internal/pkg/auth-server/auth-server.go Outdated
Comment thread internal/pkg/auth-server/auth-server.go Outdated
Comment thread internal/pkg/auth-server/auth-server.go Outdated
Comment thread internal/pkg/auth-server/auth-server.go Outdated
Comment thread internal/pkg/auth-server/auth-server.go Outdated
@DABH

Copy link
Copy Markdown
Contributor Author

Cody A. Ray (@codyaray) yeah I'm going to spruce up the success page a bit before merging. css!

@DABH

Copy link
Copy Markdown
Contributor Author

To your point #2, that URL is actually an ID, not the hostname we connect to. And I think it's provided by Auth0, I don't think we can change that. cc Eric Sirianni (@sirianni)

Comment thread internal/pkg/auth-server/auth-server.go Outdated
Comment thread internal/cmd/auth/auth.go
// Check if user has an enterprise SSO connection enabled. If so we need to start
// a background HTTP server to support the authorization code flow with PKCE
// described at https://auth0.com/docs/flows/guides/auth-code-pkce/call-api-auth-code-pkce
userSSO, err := client.User.CheckEmail(context.Background(), &orgv1.User{Email: email})

@codyaray Cody A. Ray (codyaray) Aug 13, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should not make it obvious when a user exists or not.

Suggested output

(Nesting it inside "user" means it should be backwards compatible with the current GetUserReply-based output)

Exists with SSO:

200 OK HTTP/1.1
{
   "user": {
      "sso": {
        "enabled": true,
        "auth0_connection_name": "noah-okta-test"
      }
  }
}

Exists without SSO:

200 OK HTTP/1.1
{
   "user": {
       "sso": {
        "enabled": false,
        "auth0_connection_name": ""
      }
  }
}

Doesn't exist (identical to exists without SSO):

200 OK HTTP/1.1
{
  "user": {
      "sso": {
        "enabled": false,
        "auth0_connection_name": ""
      }
  }
}

Current Behavior

Exists with SSO

{
  "user": {
    "id": 0,
    "email": "david.hyde@confluent.io",
    "first_name": "",
    "last_name": "",
    "organization_id": 0,
    "deactivated": false,
    "verified": null,
    "created": null,
    "modified": null,
    "password_changed": null,
    "service_name": "",
    "service_description": "",
    "service_account": false,
    "sso": {
      "enabled": true,
      "auth0_connection_name": "noah-okta-test"
    }
  },
  "account": null,
  "organization": null,
  "error": null,
  "accounts": []
}

Exists without SSO:

{
  "user": {
    "id": 0,
    "email": "cody@confluent.io",
    "first_name": "",
    "last_name": "",
    "organization_id": 0,
    "deactivated": false,
    "verified": null,
    "created": null,
    "modified": null,
    "password_changed": null,
    "service_name": "",
    "service_description": "",
    "service_account": false,
    "sso": {
      "enabled": false,
      "auth0_connection_name": ""
    }
  },
  "account": null,
  "organization": null,
  "error": null,
  "accounts": []
}

Not exists

{
  "user": null,
  "account": null,
  "organization": null,
  "error": {
    "code": 404,
    "message": "User not found",
    "nested_errors": {},
    "details": [],
    "stack": null
  },
  "accounts": []
}

Comment thread internal/cmd/auth/auth.go
Comment thread internal/pkg/auth-server/auth-server.go

@codyaray Cody A. Ray (codyaray) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

aside from my earlier comments lgtm

  1. you're going to update the backend check_email so it doesn't show if user/email exists or not
  2. you're adding a prettier/auto-closing page in the CLI's http server
  3. we're stuck with the auth0 identifier
  4. you'll update the Auth0ConnectionName in cc-structs and json field, but will have to deprecate it at this point and wait until we know no one would be using it to remove it.

@sirianni

Copy link
Copy Markdown
Contributor

4. you'll update the Auth0ConnectionName in cc-structs and json field, but will have to deprecate it at this point and wait until we know no one would be using it to remove it.

I'm not following this one ☝️

Comment thread internal/pkg/auth-server/auth-server.go Outdated
@DABH

Copy link
Copy Markdown
Contributor Author

Screen Shot 2019-08-16 at 9 38 44 AM

Here is what the browser callback screen looks like now. Shout out to @rob.ashe for the logo.

@sirianni

Copy link
Copy Markdown
Contributor
Screen Shot 2019-08-16 at 9 38 44 AM

Here is what the browser callback screen looks like now. Shout out to @rob.ashe for the logo.

💥

You may have a future on the frontend team! 😛

@DABH
David Hyde (DABH) merged commit bd51433 into master Aug 16, 2019
@DABH
David Hyde (DABH) deleted the auth0-sso branch August 16, 2019 19:36
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.

3 participants