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

KeycloakService and friends #13355

Merged
merged 4 commits into from
Sep 22, 2023
Merged

KeycloakService and friends #13355

merged 4 commits into from
Sep 22, 2023

Conversation

oleiman
Copy link
Member

@oleiman oleiman commented Sep 9, 2023

As work adding OIDC authentication to Redpanda gets underway, we would like to have
access to a locally installable/configurable identity provider service for the purposes of
experimentation and integration testing. This PR introduces a new ducktape service
(KeycloakService) to this end, built around the open source Keycloak
IAM application.

Additionally, this PR integrates OAuth/OIDC support into the existing PythonLibrdkafka
ducktape client and adds a redpanda_oauth_test.py. The latter contains a simple test
to spin up a keycloak service and demonstrate that it is alive and servicing requests.

Fixes: https://github.com/redpanda-data/core-internal/issues/748 https://github.com/redpanda-data/core-internal/issues/755

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v23.2.x
  • v23.1.x
  • v22.3.x

Release Notes

@oleiman oleiman requested a review from BenPope September 9, 2023 01:41
@oleiman oleiman requested a review from a team as a code owner September 9, 2023 01:41
@oleiman oleiman requested review from gousteris and removed request for a team September 9, 2023 01:41
@oleiman oleiman marked this pull request as draft September 9, 2023 01:42

from confluent_kafka import Producer

class OAuthProducer:
Copy link
Member

Choose a reason for hiding this comment

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

do we plan to integrate oauth support into other kafka clients we use in ducktape (at least the ones that support it)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question. There's a line item on the epic to add oauth support to a Java client, but that's it afaik.

tests/rptest/clients/oauth_producer.py Outdated Show resolved Hide resolved
tests/rptest/services/keycloak.py Outdated Show resolved Hide resolved
tests/rptest/services/keycloak.py Outdated Show resolved Hide resolved
Copy link
Member

@BenPope BenPope left a comment

Choose a reason for hiding this comment

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

tests/docker/ducktape-deps/keycloak Outdated Show resolved Hide resolved
@oleiman oleiman marked this pull request as ready for review September 11, 2023 17:02
Copy link
Contributor

@michael-redpanda michael-redpanda left a comment

Choose a reason for hiding this comment

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

This is looking pretty good! Can you maybe reorder/squash up your commits? I can't speak for everyone else, but I like to review PRs one commit at a time, and if there are substantial changes in architecture between commits (i.e. you dropped oauth_producer in favor of using python_librdkafka, which is good!), it makes it a little bit confusing to do that.

tests/rptest/services/keycloak.py Outdated Show resolved Hide resolved
tests/rptest/services/keycloak.py Outdated Show resolved Hide resolved
return len(self.pids(node)) > 0

def start_node(self, node, **kwargs):
self.logger.warn("Starting Keycloak service")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: info level I think is the typical level we use for these sort of messages (if not debug)

Copy link
Member Author

Choose a reason for hiding this comment

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

if not debug

So it is. Must have misread kerberos.py

tests/rptest/clients/oauth_producer.py Outdated Show resolved Hide resolved
tests/rptest/tests/redpanda_oauth_test.py Show resolved Hide resolved
tests/rptest/tests/redpanda_oauth_test.py Outdated Show resolved Hide resolved
@oleiman
Copy link
Member Author

oleiman commented Sep 11, 2023

reorder/squash up...commits

@michael-redpanda - yeah, sorry. made those structural changes after Noah and maybe Ben had already taken a look. I'll squash 'em up now.

@oleiman oleiman self-assigned this Sep 12, 2023
self.keycloak.clean_node(kc_node)
assert False, "Keycloak failed to start"

self.rpk.create_topic('foo')
Copy link
Member

Choose a reason for hiding this comment

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

You'll also need to create an ACL for the principal over this topic. The default mapping from the token to a principal is that the principal is extracted from the sub claim of the access token (until that becomes more configurable).

In this case that might be service-account-{CLIENT_ID}, depending on how Keycloak works.

@michael-redpanda michael-redpanda self-requested a review September 12, 2023 12:29
Copy link
Contributor

@michael-redpanda michael-redpanda left a comment

Choose a reason for hiding this comment

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

Looking great! Couple of nits

tests/setup.py Outdated Show resolved Hide resolved
tests/rptest/services/keycloak.py Show resolved Hide resolved
Comment on lines 81 to 83
# 'standardFlowEnabled': True, # authorization flow grant
# 'directAccessGrantsEnabled': True, # resource owner password grant
# 'implicitFlowEnabled': True, # implicit grant
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Any reason these should remain here? For code clarity can we remove commented out code.

Copy link
Member Author

Choose a reason for hiding this comment

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

These are the flags to enable different grant types on the client; left them in for pseudo-documentation purposes because they're slightly obtuse. PRD calls exclusively for client-credentials though; will remove.

tests/rptest/tests/redpanda_oauth_test.py Show resolved Hide resolved
Copy link
Member

@dotnwat dotnwat left a comment

Choose a reason for hiding this comment

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

plz add a PR description

@oleiman
Copy link
Member Author

oleiman commented Sep 13, 2023

plz add a PR description

oops, not sure what happened there. done

@oleiman oleiman force-pushed the keycloak-DT branch 3 times, most recently from e931538 to baaaa30 Compare September 14, 2023 18:56
@oleiman
Copy link
Member Author

oleiman commented Sep 19, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

@oleiman
Copy link
Member Author

oleiman commented Sep 19, 2023

/cdt
dt-repeat=3
tests/rptest/tests/redpanda_oauth_test.py

@oleiman
Copy link
Member Author

oleiman commented Sep 20, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

@oleiman
Copy link
Member Author

oleiman commented Sep 20, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

@oleiman
Copy link
Member Author

oleiman commented Sep 20, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

@oleiman oleiman force-pushed the keycloak-DT branch 2 times, most recently from b22a158 to a8552fe Compare September 20, 2023 21:14
@oleiman
Copy link
Member Author

oleiman commented Sep 20, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

@oleiman
Copy link
Member Author

oleiman commented Sep 20, 2023

force push to (actually) fix CDT finally

Comment on lines 153 to 154
# assert len(self.produce_messages) == 3, f"Expected 3 messages, got {len(self.produce_messages)}"
# assert len(self.produce_errors) == 0, f"Expected 0 errors, got {len(self.produce_errors)}"
Copy link
Contributor

Choose a reason for hiding this comment

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

THe idea is that these will be uncommented once paired with a working OIDC implementation in RP?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep

Copy link
Contributor

Choose a reason for hiding this comment

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

So my feeling with this is, uncommented them, mark the test @ok_to_fail and then remove it once OIDC is integrated. Thoughts @BenPope ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Eh, maybe better to remove them? I still think the other assertions here have some value in terms of testing the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Other option would be to just have this test be a simple service test (does this service actually work) and remove any comms with Redpanda and add them back later.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ripped a bunch of it out. Left a few things in to demonstrate service user manipulation and that librdkafka does the correct thing when passed the OAUTHBEARER algorithm, but the rest, I agree, was just noise.

- Makes use of keycloak-python
  - Requires a lightly patched fork to get around a urllib3
    version mismatch.
- Methods for creating and updating users, clients
- Spins up a redpanda cluster and a KeycloakService
- Creates a user under the demo realm, with realm-admin priv
- Registers a client with keycloak
- Update client's service account to include an email address
  - This will appear in the access token as the grant includes
    the 'email' scope.
- Initializes PythonLibrdkafka with appropriate info (client ID, secret)
- Sends some messages (this will fail without backend support)
@oleiman
Copy link
Member Author

oleiman commented Sep 21, 2023

force pushed a rebase on dev - I think the branch fell a bit too far behind for CI

@oleiman
Copy link
Member Author

oleiman commented Sep 22, 2023

/ci-repeat 1

Copy link
Member

@BenPope BenPope left a comment

Choose a reason for hiding this comment

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

Looks great!

@oleiman
Copy link
Member Author

oleiman commented Sep 22, 2023

/cdt
tests/rptest/tests/redpanda_oauth_test.py

Copy link
Contributor

@michael-redpanda michael-redpanda left a comment

Choose a reason for hiding this comment

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

lgtm

@oleiman oleiman merged commit 3a8ffdd into redpanda-data:dev Sep 22, 2023
9 checks passed
@oleiman oleiman deleted the keycloak-DT branch September 22, 2023 18:31
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.

5 participants