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

Support SSO authentication #142

Open
davidgeiger opened this issue Feb 3, 2021 · 33 comments
Open

Support SSO authentication #142

davidgeiger opened this issue Feb 3, 2021 · 33 comments
Assignees
Labels
enhancement New feature or request

Comments

@davidgeiger
Copy link
Contributor

User story
As a CLI user, I want to authenticate with API Manager using the configured SSO mechanism.

Additional context
When (SAML-based) SSO is used to log into API Manager, regular users do not have a username and password. In order to use the CLI, everyone needs to create a technical user (~ service account), which is not scalable and potentially insecure, especially if password are stored locally. Ideally, the APIM CLI would support an (interactive?) login with API Manager using the configured SSO mechanism. Similar mechanisms are supported, for instance, by the Amplify Central CLI and the gcloud CLI.

@davidgeiger davidgeiger added the enhancement New feature or request label Feb 3, 2021
@davidgeiger davidgeiger changed the title Support SSO login Support SSO authentication Feb 4, 2021
@cwiechmann
Copy link

Hi @davidgeiger, this would be a big change, as the authentication would then have to be stored in an external token, which is a completely different concept than how it is done now.

And the CLI currently uses two users. So the default user (Org-Admin) and if specified an admin account (e.g. service account) which performs all the tasks the default user can't do. The admin account is then stored in the pipeline if necessary.

I am not sure how this can be brought together with the SSO concept. Any thoughts?

@gwandwingor
Copy link
Collaborator

@cwiechmann Maybe a simpler alternative (or intermediary) way to see this would be to allow decoupling the login part by providing the session cookie in an environment variable.
This way, in the apim-cli code, changes would be limited to using this env variable if present. On the other hand, the SSO login sequence would still have to be implemented somewhere but it would be a different custom development.

Just my 2 cents here

@emmanuel-galindo
Copy link

this. pls. but it can tricky, as org IDP might be enforcing browsers..

we can't issue local accounts to users.
another example, similar as above: other systems (openshift) allow you to issue a token from the ui

but something. pls.

@cwiechmann
Copy link

I think the CLI must support a command like: apim auth and perhaps supports then different options:
apim auth login --> Login as it works today, using a standard APIM account based on HTTP-Basic
apim auth loginsso --> Would then behave as the AMPLIFY-CLI

Ultimately the generated Session-ID returned by the API-Manager will be stored in a local config file, no matter which authentication option was used.
But Still the CLI will use, if given, an Admin-Account to create the required Admin-Session.

@emmanuel-galindo, can you please elaborate a bit more on this example?
another example, similar as above: other systems (openshift) allow you to issue a token from the ui

@davidgeiger
Copy link
Contributor Author

Sounds good to me. I believe both of the above examples (Amplify and gcloud CLI) open a browser window for an interactive OAuth auth code flow. I assume a similar approach could be used to open a browser window for authentication with API Manager's SSO endpoint via a SAML flow. The resulting user authentication token would be a generated session cookie instead of an OAuth JWT.

@emmanuel-galindo
Copy link

opening a browser to get the token seems a good to me, and if you have already done for amplify-cli maybe it will avaialble soon?

@cwiechmann in ocp webadmin, you have a way to copy to your clipboard a string similar to:
occlient --token XXX login

@emmanuel-galindo
Copy link

@cwiechmann any update on this feature? or is there any plan to include some alternative to having to login with a non-sso api admin in the next releases?

@emmanuel-galindo
Copy link

@cwiechmann I just got to "2.2 Create a service account using the Amplify Central UI
" from https://docs.axway.com/bundle/axway-open-docs/page/docs/central/cli_central/cli_install/index.html and remembered about this issue, do you think something like that could be enabled for apim-cli? that would be awesome to have

@davidgeiger
Copy link
Contributor Author

Same here, this would be an important feature to reduce the number of password-based "service accounts". They may still be required for technical clients that cannot obtain a SAML token, but anyone else - in particular the average org admin - should be able to use the CLI with their SSO identity.

@cwiechmann: Have you considered integrating the API Mgr CLI functionality into the Axway CLI given that it already supports interactive authentication? This would also reduce the number of CLIs that a user has to install. ;) Not sure if there is an efficient way to port or emulate the Java-based codebase.

@cwiechmann
Copy link

Unfortunately there was no time at all to work in this. As you may guess it's a major undertaking to implement this.
Making the apim-cli part of the axway-cli looks not feasible to me, as the Axway-CLI is based on node.Js vs. Java for the APIM-CLI.

@davidgeiger
Copy link
Contributor Author

davidgeiger commented Nov 17, 2021

Haven't thought this through, but perhaps it is feasible to create a simple wrapper around the apim-cli in order to turn it into an Axway CLI extension? A command such as "axway apimgr import" would then trigger the apim-cli (JRE) execution. This could also be helpful.

Assuming that the available (interactive) authentication framework could be adjusted to interact with API Manager, it could pass the obtained SAML assertion as a parameter to the apim-cli. Leveraging the package manager for apim-cli installation also seems interesting.

@stale
Copy link

stale bot commented Apr 14, 2022

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 14, 2022
@davidgeiger
Copy link
Contributor Author

Any new thoughts on how to approach this? I believe an interactive authentication is crucial to ensure CLI usability with an SSO-enabled distributed setup. Having to request dedicated technical users (with passwords) for each use case introduces security risks and a significant adoption barrier.

@stale stale bot removed the stale label Apr 14, 2022
@stale
Copy link

stale bot commented Aug 11, 2022

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Aug 11, 2022
@davidgeiger
Copy link
Contributor Author

Would it help to engage with the Axway CLI team to see if the same logic can be used? The need to create a technical username/password account for each user who wants to use the CLI creates a lot of overhead.

@stale stale bot removed the stale label Aug 12, 2022
@saper
Copy link

saper commented Aug 31, 2022

@davidgeiger is there any way to login to the API manager API (port 8075) by not using username/password?

https://apidocs.axway.com/swagger-ui-NEW/index.html?productname=apimanager&productversion=7.7.0&filename=api-manager-V_1_4-oas3.json#/Login/login seems to accept only login and password parameters and sets some cookies to let the API client work.

@rathnapandi
Copy link
Member

@saper and @davidgeiger, One option i think of doing IDP initiated SSO - In that case APIM CLI will act as IDP, it accepts username, generate SAML token, sign it and send it API manager to generate user session. The session will be used by APIM CLI to make subsequent API call to API manager.

What do you think about it?

@davidgeiger
Copy link
Contributor Author

Hi @rathnapandi. I might have misunderstood but this doesn't seem feasible to me. A user's identity needs to be authenticated by the central identity provider. Otherwise, users can easily impersonate each other.

I believe the approach that was outlined in the previous discussion is a best practice for CLIs (incl. the axway cli): In addition to the existing password-based authentication, offer an interactive SSO option. This opens the API Manager SSO login in a browser window, which will trigger the SAML authentication flow with the IdP via redirects and result in an API Manager session. At this point the browser window can be closed and the session id can be used for all subsequent API calls (@saper).

Implementation is mainly a matter of orchestration since this approach leverages the existing API Manager SSO mechanism and session authentication. As an alternative, it may be worth looking into leveraging the existing axway cli or its authentication framework (as suggested before).

I want to stress the importance of supporting SSO authentication in the CLI again. At this point the average API Manager user can not use the CLI with an SSO-integrated API Manager instance. Every CLI user needs a password-based account, which would negate the benefits of an SSO integration.

@rathnapandi
Copy link
Member

Hi @davidgeiger,

I agree with your concerns.

During SSO, API manager generates cookie and CSRF token after successful login and assign roles based on the service-proivder.xml configuration. The cookie and CSRF token can be used for REST API call. Challenge is how do we know the authentication is complete and how can we read the cookies from browser?

Amplify CLI uses following process during authentication. The CLI uses Oauth2 OIDC.

  1. CLI listens on http port (3000) to handle http redirect request
  2. Open nup browser window with redirect URI ( redirect URI refers to host and port used by amplify cli) e.g https://login.axway.com/auth/realms/Broker/protocol/openid-connect/auth?access_type=offline&client_id=xxx&code_challenge=TYhIItr6KCcsFcKJI11fwl1p-C_JsO5hbFJEWQ1dXIk&code_challenge_method=S256&grant_type=authorization_code&redirect_uri=**http%3A%2F%2Flocalhost%3A3000%2Fcallback%2F694F2B75**&response_type=code&scope=openid
  3. After successful login IDP redirects to redirect URI
  4. CLI receives a callback request from IDP and read access token and id token
  5. Use access token for subsequent api calls.

Amplify platform acting as IDP if Amplify tenant is not configured with SSO, if the tenant is configured with SSO, it will act as IDP broker.

I am thinking of a hybrid approach.

  1. Create an open-id application on IDP with redirect URI as localhost:port (used by cli)
  2. apim-cl listens on specific port, open browser window for login, receives ID token as part of redirect request if login is successful.
  3. APIM CLI parses id token and get the user id, organization name, role, email, username etc.. , generates SAML token with user id and other attributes.
  4. Call API manger SSO endpoint (IDP initiated SSO flow) to generate SSO related cookie and CSRF token.
  5. If SSO call is success, API Manager generate session and CSRF token which can be used by APIM cli to make subsequent calls.

Challenge :
SAML attributes are signed by default, to do that we need a private key used by IDP which might be difficult to get an access.

To overcome the above challenge, we can configure additional profile on service-provider.xml and manage our own private key or ignore the signing validation.

@davidgeiger
Copy link
Contributor Author

davidgeiger commented Nov 16, 2022

Hi @rathnapandi. I see several challenges with the described hybrid approach. It will not be possible to use private keys of our IdP. More generally, if the CLI issues or signs the SAML assertions, this would require the gateway to trust all CLI instances (run by any user), which is not feasible (risk of impersonation).

Couple of thoughts on other SAML options (although I am not terribly familiar with the protocol):

  • Is it be possible to implement the outlined Amplify CLI flow entirely with SAML? I guess that would require the CLI to dynamically pass a localhost redirect URI to the IdP (instead of the default API Manager SSO endpoint) in order to catch the assertion. I am not sure if this is possible with SAML.
  • If it is not possible to pass a redirect URI, perhaps a second IdP config (with a localhost redirect URI) and a corresponding second provider configuration in API Manager could be used? Not sure if two provider configs are supported by API Manager.
  • Or we could stick with a single config and change the static redirect URI (in the IdP config) to a custom endpoint that is backed by an API gateway policy. By default, this policy will simply redirect the client (browser) again to the API Manager SSO endpoint. If the login flow was initiated by the CLI (*), however, it would redirect to localhost instead, thus passing the assertion to the CLI. (*) This information would need to be passed through the entire SAML flow.

As an alternative to SAML, the CLI could use OIDC exclusively to authenticate with API Manager. This would be largely the same flow as with the Amplify CLI. It would require the configuration of account authentication+information policies in API Manager whose behavior is in line with the SAML SSO configuration (extracting and mapping the same information from the tokens). I understand there have already been some activities to also enable OIDC as a general SSO option besides SAML, so there might be some synergies. The only reason that we went with SAML so far was really the lack of support for OIDC in the UI (redirect flows etc.) - which wouldn't be an issue with the CLI.

@rathnapandi
Copy link
Member

Thanks @davidgeiger for your suggestion and validation.

Why do you think it is risk of impersonation? CLI is going to do token mediation (OIDC to SAML). the user will be validated with IDP via OIDC flow. As i mentioned earlier, we can create a second IDP provider configuration by disabling SAML signature verification and encryption.

SAML uses redirect URI aka relaystate from idp metadata configuration file. Hence we can't change the redirect URL on API gateway side.

API manager supports two IDP providers.

A combination of the first and second options might work. We create two SAML applications on IDP. one points to API manger another one points to APIM CLI by changing relaystate to localhost on IDP and configure second IDP provider on API manger via service-provider.xml.

  1. CLI listens on port to process redirect request and open up IDP initiated SAML SSO URL
  2. After successful authentication, IDP redirects to localhost with SAML assertion.
  3. CLI uses SAML assertion and connects to API manager to do authentication and get the session information. (We may need to do IDP hostname whitelisting)
    image

I need to check with R&D on the timeline of APIM OIDC support.

@davidgeiger
Copy link
Contributor Author

davidgeiger commented Nov 16, 2022

Re impersonation: If the CLI generates its own SAML assertions that are trusted by API Manager (signed or not), what prevents a user from changing the username in those assertions (e.g., by changing the CLI code)?

I did some more digging into implementing the Amplify CLI behavior with SAML and still think this should be possible.

  • In a SP-initiated flow, the SP can pass an AssertionConsumerServiceURL in the AuthNRequest. This is the equivalent to OIDC's redirectUri and needs to match the list of allowed ACS URLs on IdP side. See, e.g., here.
  • The CLI would have to generate a SAML authentication request with an AssertionConsumerServiceURL=localhost parameter, send it to the IdP, retrieve the authentication response, send it to API Manager's SSO endpoint and store the resulting session cookie + CSRF token.
  • In case some IdPs do not support multiple ACS URLs (not sure about this), it may still be possible to create a second IdP application that has a static localhost ACS URL. I don't know if API Manager will accept corresponding authentication responses, though, as they probably contain another id.

Alternatively, using OIDC instead should already be possible today. It merely requires a client that orchestrates the login flow, which essentially means redirecting unauthenticated users to the IdP where they authenticate and are redirected back to API Manager. IMHO this orchestration is the only part missing in API Manager to support OIDC SSO, but it is not relevant here since the CLI would handle the orchestration. Everything else is already supported and we are doing this in other places:

  • The CLI can send the access token from the IdP response as a password parameter to the login API.
  • An IdP-specific account authentication policy validates the token and extracts the relevant user id. This can be done both with self-contained, signed JWTs or through remote validation at the IdP in case of opaque tokens.
  • If no account for the token's user id exists in KPS, API Manager invokes an account information policy, which extracts or obtains additional information on the user (name etc.) and creates an account.

Finally, using either approach, I am wondering if there isn't an easier way for the CLI process to access the response data from the browser that it launches, i.e., without having to redirect it to a localhost HTTP port first? To illustrate what I mean: If we were to send an authentication request to the IdP using curl (which would be a bit cumbersome), we would get the authentication response directly as a command output. Are we sure this doesn't work with a graphical browser?

@rathnapandi
Copy link
Member

Some challenges with your SAML suggestion.
Some IDP expects SAML login request be signed to establish a trust, which requires certificate exchange.
Okta does not support multiple relaystate URIs
image

I like the second approach. it would be feasible to implement it.

What kind of authentication request? If you mean saml request, IDP will redirect to the login page if the user does not have valid session. How do we handle user interaction from CLI for login? Am I missing anything?

@davidgeiger
Copy link
Contributor Author

davidgeiger commented Nov 16, 2022

Agreed, an SP-initiated login with authentication requests generated by the CLI will not work if the IdP expects signed requests. Signing requests does not seem to add any value in this case, however, since the actual user authentication happens at the IdP. If that is a concern, handling CLI authentication via a second IdP application without request signatures may be a possibility (if the resulting assertions are accepted by API Manager - see above).

When using an SP-initiated login, the relevant parameter for passing a dynamic redirect URL is the AssertionConsumerServiceURL that can be added to the authentication request (Azure AD docs). AFAIK the RelayState can be used for a similar purpose in IdP-initiated logins but requires some logic on the SP side: The IdP still sends the authentication response to the configured (in this case static) ACS URL and simply passes the RelayState as an additional parameter. I don't think this helps here.

Re the last point: I am not suggesting to use curl to handle the user login. I was merely wondering if there might be a more direct way to read the SAML assertion or access token from the IdP response of a browser window - besides redirecting the IdP response to a localhost port? Since the CLI launches the browser window, it may be able to get the HTTP response values through another means (comparable to the verbose output of a curl command).

@rathnapandi
Copy link
Member

Once we launch browser window, we will lose control of request and responses unless we are acting as http proxy to intercept request and response.

@davidgeiger
Copy link
Contributor Author

Ok. Either way, the approach with a redirect to localhost may work with both options. Any preferences or further relevant points on your end?

  • SAML login would be straightforward to set up for existing API Manager environments: add a localhost ACS URL to the IdP config. It also requires that authentication request signature validation is disabled or a second app w/o signature validation (to be verified).
  • OIDC login does not require changes to the SAML setup but requires a redundant implementation of the SSO mapping rules in account authentication + information policies. This increases overall complexity as long as the API Manager UI itself does not support OIDC (at which point OIDC could be used exclusively).

@stale
Copy link

stale bot commented Mar 25, 2023

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Mar 25, 2023
@stale
Copy link

stale bot commented May 21, 2023

This issue has been automatically closed because it has not had activity in the last month and a half. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted". Thank you for your contributions.

@stale stale bot closed this as completed May 21, 2023
@davidgeiger
Copy link
Contributor Author

This continues being very relevant for a full SSO experience with API Manager. Please reopen.

@rathnapandi rathnapandi reopened this May 22, 2023
@stale stale bot removed the stale label May 22, 2023
@stale
Copy link

stale bot commented Sep 17, 2023

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 17, 2023
@saper
Copy link

saper commented Nov 24, 2023

unstale

@stale stale bot removed the stale label Nov 24, 2023
@emmanuel-galindo
Copy link

will this be completed? or at least some alternative (ie tokens issues from api manager)

it seems the only way is to build an api on top of all these to obscure these admin accounts, but yet provide tools for developers. It is a bit of an overhead.

@rathnapandi
Copy link
Member

Hi @emmanuel-galindo,
API Manager supports only SAML, but we can extend API manager Identity provider polices (policy can get username, password, add client id, secret to call external IDP for authentication and authorization) to implement SSO
image

A workaround is CLI can initiate the SSO to IDP by sending SAML sign in request and get the SAML response from IDP, then CLI sends to API manager to get a session token. This approach requires additional configuration on IDP as well as API manager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants