Skip to content

Conversation

@sungwy
Copy link
Contributor

@sungwy sungwy commented Sep 25, 2025

Resolves #138

RFC: https://docs.google.com/document/d/1HadMFygjbuZathZZPanO6cFVorx0Ju0FopkICxX1tCE/edit?tab=t.0
Mailing list discussion: https://lists.apache.org/thread/54qdbsxs3j7wwhv3tsccqj6qng5lqgmz

Some followup items highlighted as a part of this PR review:

  • introduce OpaHttpClientFactory that utilizes PoolingHttpClientConnectionManager to get opa-http-client to be more production ready
  • publish user-facing docs on OPA authorization
  • publish json schema for docs and opa server checks
  • introduce per-realm configuration support

Copy link
Contributor

@adutra adutra left a comment

Choose a reason for hiding this comment

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

Thanks @sungwy for this draft PR, I couldn't resist and took a look 😄

This is really interesting imho and a very nice addition to Polaris. We need to start thinking about ways to make Polaris RBAC fully pluggable.

Copy link
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

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

Very interesting idea! Just some preliminary comments below :)

@flyrain
Copy link
Contributor

flyrain commented Sep 25, 2025

Thanks for working on it @sungwy ! Looking forward to the RFC/design doc!

@sungwy sungwy marked this pull request as ready for review October 8, 2025 02:05
@sungwy sungwy requested review from adutra and dimas-b October 8, 2025 02:14
Comment on lines 119 to 123
if (Strings.isNullOrEmpty(cachedToken)) {
throw new RuntimeException(
"Bearer token is unexpectedly empty. This should not happen after successful construction.");
}
return cachedToken;
Copy link
Contributor

Choose a reason for hiding this comment

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

technically this is still racy since cachedToken is volatile... it is not likely to materialize as a bug, but the code pattern looks a bit worrisome 😅 why not load the value into a local var, check and return from local?

e.g. return Preconditions.checkNotNull(cachedToken, "Bearer token is unexpectedly empty ...")

Copy link
Member

Choose a reason for hiding this comment

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

I guess this is outdated now with the new commits.

Copy link
Member

@snazy snazy left a comment

Choose a reason for hiding this comment

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

One nit, everything else beside int-tests LGTM.

For integration-tests, I'm thinking of having non-Quarkus integration tests against an OPA testcontainer in the "main" OPA module.

I've prepared some stuff for tests in this commit (here as well):

  • Add a starter for an integration test in the "main" module
  • Updated the existing int tests

Idea is to have the majority of integration-tests in the "main" module and only a smoke-test in runtime-service.

I think we can then get rid of the opa-tests module and can move the "main" module one directory level up.

BTW: Please add an entry for the "main" module to :polaris-bom.

WDYT?

Comment on lines 119 to 123
if (Strings.isNullOrEmpty(cachedToken)) {
throw new RuntimeException(
"Bearer token is unexpectedly empty. This should not happen after successful construction.");
}
return cachedToken;
Copy link
Member

Choose a reason for hiding this comment

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

I guess this is outdated now with the new commits.

reduce volatile reads from 2 -> 1

Co-authored-by: Robert Stupp <[email protected]>
@sungwy
Copy link
Contributor Author

sungwy commented Oct 24, 2025

For integration-tests, I'm thinking of having non-Quarkus integration tests against an OPA testcontainer in the "main" OPA module.

I've prepared some stuff for tests in this commit (here as well):

  • Add a starter for an integration test in the "main" module
  • Updated the existing int tests

Idea is to have the majority of integration-tests in the "main" module and only a smoke-test in runtime-service.

I think we can then get rid of the opa-tests module and can move the "main" module one directory level up.

Thanks again @snazy :) Let me take a look at your draft PR and see if I can get rid of the test module and bring impl back up to main. I had some trouble achieving this because of the dependency on :polaris-runtime-service.

Just so I'm clear: is your suggestion to move the QuarkusIntegrationTest annotated tests back into polaris-runtime-service?

@snazy
Copy link
Member

snazy commented Oct 24, 2025

Just so I'm clear: is your suggestion to move the QuarkusIntegrationTest annotated tests back into polaris-runtime-service?

Yes and no ;)

Have non-Quarkus integration tests (like OpaAuthorizerIT) in the "main" OPA module and have a minimal set of OPA integration tests in polaris-runtime-service just to verify the integration with Quarkus. I suspect we don't need that many ITs in runtime-service, probably more or less just a "smoke test".
I'm not really familiar with what's worth being integration tested in the non-Quarkus ITs.
Test coverage for the OPA factory and the authorizer itself is pretty good.

}

private void scheduleRefreshAttempt(Duration delay) {
this.refreshTask = asyncExec.schedule(this::refreshTokenAttempt, delay);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice reuse of existing functionality 🚀

// In this case we wait for the configured amount of time
// (5 seconds in production, much lower in tests).
try {
return initialTokenFuture.get(initialTokenWaitMillis, TimeUnit.MILLISECONDS);
Copy link
Contributor

Choose a reason for hiding this comment

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

optional: I do not want to disturb the impl. at this stage as it looks pretty solid to me... but I suppose it could be simplified this way:

  • keep a volatile reference to a CompletionStage with token data
  • getToken always calls .get() with a timeout
  • the initial ref. to the CompletionStage is make in the constructor by scheduling a refresh task
  • when refresh completes it will update the CompletionStage and reschedule
  • the CompletionStage will be "complete" in all cases but the initial refresh, so .get() calls will not wait except possibly on the first call.
  • we have less fields and less ifs (hopefully) in this class (only refreshTask and the CompletionStage)

WDYT?

testFixturesApi(libs.jakarta.ws.rs.api)

compileOnly(libs.jakarta.annotation.api)
compileOnly(libs.jakarta.enterprise.cdi.api)
Copy link
Contributor

Choose a reason for hiding this comment

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

IIRC, we had some prior discussions about avoiding CDI annotations in core as a convention...

If it's required only for @Identifier("internal") on DefaultPolarisAuthorizerFactory, I'd propose remove the annotation from the class and make a producer method for it in ServiceProducers.

Alternatively, we could remove DefaultPolarisAuthorizerFactory completely and update ServiceProducers to "manually" use PolarisAuthorizerImpl if Instance<PolarisAuthorizerFactory> is not resolvable in CDI.

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @dimas-b these are great suggestions. Thank you for giving me the background context on the package discussions.

I've added a Producer method in ServiceProducers and removed the cdi dependency from polaris-core

@sungwy
Copy link
Contributor Author

sungwy commented Oct 24, 2025

I suspect we don't need that many ITs in runtime-service, probably more or less just a "smoke test".
I'm not really familiar with what's worth being integration tested in the non-Quarkus ITs.

I actually found it very helpful to have the Quarkus integration tests because it helped verify the smallrye Configs. Maybe that's a matter of me being new to CDIs but I think it's still helpful to have that coverage.

@dimas-b - I would love to get your thoughts on this suggestion as well

@sungwy
Copy link
Contributor Author

sungwy commented Oct 26, 2025

BTW: Please add an entry for the "main" module to :polaris-bom.

I've added the polaris-extensions-auth-opa module to :polaris-bom. I also noticed that the other extensions polaris-extensions-federation-hive and polaris-extensions-federation-hadoop are missing. Should these be added as well? (maybe in a separate PR)

@flyrain
Copy link
Contributor

flyrain commented Oct 27, 2025

I've added the polaris-extensions-auth-opa module to :polaris-bom. I also noticed that the other extensions polaris-extensions-federation-hive and polaris-extensions-federation-hadoop are missing. Should these be added as well? (maybe in a separate PR)

Yes, we will need them in BOM as well. A separate PR sounds good to me.

Copy link
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

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

Sorry about the delay. This PR LGTM in its current state, except the dep. on CDI annotations in polaris-core.

The current tests layout LGTM. So, if @snazy is ok with that, I think we're pretty close to merging.

Re: CDI in core, we can probably discuss that on the dev ML if you prefer to keep the annotation. The reason I flagged it is not my personal objection, but the fact that IIRC it was discussed before and the agreement in the community was to avoid CDI-specific annotations in core.

@sungwy
Copy link
Contributor Author

sungwy commented Oct 28, 2025

@dimas-b - I've addressed the concern regarding the polaris-core dependency. Appreciate the review!

Copy link
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

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

LGTM 👍 @sungwy : Many thanks for the contribution and for bearing with the long review process 😉

@dimas-b
Copy link
Contributor

dimas-b commented Oct 28, 2025

Let's give some more time to @flyrain, @adutra and @snazy for final thoughts / comments. I suppose we could also follow up with test adjustments relocations after merging this PR (it's been in review for a long time 😅 )

@sungwy
Copy link
Contributor Author

sungwy commented Oct 28, 2025

Woohoo!

Thank you @dimas-b ! And @snazy @flyrain and @adutra for the reviews as well.

This was a great way for me to get up to speed with the project, so thanks for your interest and patience in reviewing this PR as well.

I'll be following this up with some more PRs (docs, schema, etc) and we'll start integrating this into our platform.


implementation(libs.jakarta.servlet.api)

runtimeOnly(project(":polaris-async-vertx"))
Copy link
Contributor

@flyrain flyrain Oct 30, 2025

Choose a reason for hiding this comment

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

Why do we need this dependency? Is this only for test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe this actually is the CDI implementation of polaris-async-api AsyncExec that's optimized for Quarkus applications. Hence, we need it as a runtimeOnly dependency in polaris-runtime-service

Copy link
Contributor

Choose a reason for hiding this comment

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

I’m good with using the Vert.x async executor since we’re already on Quarkus. The polaris-async-vertx module currently lives under /persistence/nosql, but it’s really part of the async infrastructure rather than a NoSQL implementation detail. We could consider moving it out of that directory, though it doesn’t need to be done in this PR.

@flyrain flyrain merged commit 577b32a into apache:main Oct 31, 2025
15 checks passed
@github-project-automation github-project-automation bot moved this from Ready to merge to Done in Basic Kanban Board Oct 31, 2025
@flyrain
Copy link
Contributor

flyrain commented Oct 31, 2025

Thanks a lot for working on it, @sungwy ! Thanks @snazy @dimas-b @jbonofre for the review.

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.

[FEATURE REQUEST] Support OPA integration

7 participants