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

Abstract authentication flow into new interface #20

Merged
merged 1 commit into from
Jun 1, 2022

Conversation

szh
Copy link
Contributor

@szh szh commented May 20, 2022

Note: To see implementation in the CLI, see cyberark/cyberark-conjur-cli#410

Desired Outcome

Create a new AuthenticationStrategy interface that will allow us to abstract the authentication flow. The interface should
take a CredentialProvider and Conjur account as inputs, as well as any other arguments that are needed to authenticate,
such as service_id for LDAP. The interface should have a authenticate method which returns a Conjur auth token. All details of authentication should be handled by the AuthenticationStrategy interface.
Include unit tests and update existing unit and integration tests.

Implemented Changes

  • Added AuthenticationStrategyInterface to abstract authentication logic
  • Added AuthnAuthenticationStrategy which implements the interface for the default authn strategy
  • Updated the Api class to use the interface to implement authentication

Connected Issue/Story

CyberArk internal issue link: ONYX-20429

Changelog

  • The CHANGELOG has been updated, or
  • This PR does not include user-facing changes and doesn't require a
    CHANGELOG update

Test coverage

  • This PR includes new unit and integration tests to go with the code
    changes, or
  • The changes in this PR do not require tests

Documentation

  • Docs (e.g. READMEs) were updated in this PR
  • A follow-up issue to update official docs has been filed here: insert issue ID
  • This PR does not require updating any documentation

Behavior

  • This PR changes product behavior and has been reviewed by a PO, or
  • These changes are part of a larger initiative that will be reviewed later, or
  • No behavior was changed with this PR

Security

  • Security architect has reviewed the changes in this PR,
  • These changes are part of a larger initiative with a separate security review, or
  • There are no security aspects to these changes

@szh szh self-assigned this May 20, 2022
@szh szh force-pushed the auth-strategry-refactor branch 10 times, most recently from ceac461 to d122bf9 Compare May 23, 2022 19:16
@szh szh force-pushed the auth-strategry-refactor branch 2 times, most recently from 715fc6e to 2b2566d Compare May 23, 2022 20:43
@szh szh marked this pull request as ready for review May 24, 2022 15:13
@szh szh requested a review from a team as a code owner May 24, 2022 15:13
@szh szh requested review from jvanderhoof and rpothier May 24, 2022 19:06
@szh szh force-pushed the auth-strategry-refactor branch 3 times, most recently from b3d4298 to 370bb5b Compare May 25, 2022 15:37
CHANGELOG.md Outdated Show resolved Hide resolved
@szh szh force-pushed the auth-strategry-refactor branch from 370bb5b to 3c5b1ae Compare May 25, 2022 18:51
Copy link

@doodlesbykumbi doodlesbykumbi left a comment

Choose a reason for hiding this comment

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

Left some comments

CHANGELOG.md Show resolved Hide resolved
"""

@abc.abstractmethod
async def authenticate(self, api_key: str, ssl_verification_data: SslVerificationMetadata) -> str:

Choose a reason for hiding this comment

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

I might be missing something on the authenticate signature on this interface. Not all authenticators use the api_key parameter. I think they each have their own set of parameters required to carry out authentication.

Copy link
Contributor Author

@szh szh May 26, 2022

Choose a reason for hiding this comment

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

Can you give me an example of an authenticator that doesn't use an api key? If you're referring to the JWT or GCP authenticators, they still have a string value that takes the place of an api_token. Maybe we can call this something else to make it more general?

Choose a reason for hiding this comment

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

I agree w/ @doodlesbykumbi. Only the default authenticator uses the API key. All other authenticators validate the external identity and return a Conjur Auth token.

What about injecting the strategy along the lines of:

credentials = CredentialsData(username=username, password=password, machine=conjur_url)
credentials_provider = SimpleCredentialsProvider()
credentials_provider.save(credentials)
del credentials

client = Client(connection_info,
                authentication_strategy=Authn(credentials_provider=credentials_provider)
                ssl_verification_mode=ssl_verification_mode)

client = Client(connection_info,
                authentication_strategy=AuthnLdap(credentials_provider=credentials_provider)
                ssl_verification_mode=ssl_verification_mode)

client = Client(connection_info,
                authentication_strategy=AuthnJwt(jwt='path-to-jwt')
                ssl_verification_mode=ssl_verification_mode)

If the Authentication Strategy interface includes a method (maybe authenticate), and returns a Conjur Auth Token, we can inject the "how" into our client.

conjur_api/providers/authentication_strategy_factory.py Outdated Show resolved Hide resolved
self._account = account
self._login_id = login_id

async def authenticate(self, api_key: str, ssl_verification_data) -> str:

Choose a reason for hiding this comment

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

As mentioned above, having this method take CredentialsData via a SimpleCredentialsProvider allows the authentication to be handled here.

As a note, we may need to add a second/alternative CredentialsData type to handle hostname/api key. Users exchange a username/password for an api key, then authenticate with the username/api key combination. Hosts authenticate with host/<hostname>/api key combination (note the host in front of the hostname).

@szh szh force-pushed the auth-strategry-refactor branch 4 times, most recently from 766b11e to 1e6432b Compare May 26, 2022 16:07
@szh szh force-pushed the auth-strategry-refactor branch 8 times, most recently from 15bacd1 to 89ac4c1 Compare May 26, 2022 19:09
@szh szh mentioned this pull request May 26, 2022
13 tasks
@szh szh force-pushed the auth-strategry-refactor branch from 89ac4c1 to deb6615 Compare May 26, 2022 20:30
Copy link

@rpothier rpothier left a comment

Choose a reason for hiding this comment

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

LGTM, if there are remaining items from Jason or Kumbi they can be addressed in a follow up so this can move forward.

@szh szh merged commit 24a1133 into main Jun 1, 2022
@szh szh deleted the auth-strategry-refactor branch June 1, 2022 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

4 participants