Repository navigation
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3273 +/- ##
============================================
+ Coverage 58.42% 58.44% +0.02%
+ Complexity 6903 3080 -3823
============================================
Files 779 779
Lines 69391 69418 +27
Branches 9567 9578 +11
============================================
+ Hits 40539 40570 +31
+ Misses 25179 25168 -11
- Partials 3673 3680 +7
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
bitflicker64
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: The Ranger authorizer hook can be bypassed. When its rate limiter has no permit left it allows the request, so per-label deny policies stop working for list reads. Separately, init-store now creates the admin with the public default password pa for every built-in-auth install, whether or not Ranger is used. Within the plugin, the default-graph and default-role calls fail through reflection, Ranger grants never apply outside graph space DEFAULT, the pinned Ranger 2.4.0 has a critical CVE, and CI never builds the module. The branch also carries 37 commits already on master, replayed with new SHAs (#3140 to #3218), so GitHub shows 370 files. The PR conflicts with master (mergeStateStatus DIRTY). Rebasing onto current master would cut the diff down to the 31 files this PR really changes. Evidence: compared head 4057f3f with upstream 0a3e4ae (#3218, the last replayed commit). That diff is the full delta: 31 files, +8697/-9. I read every hand-written Java, POM, Dockerfile and compose file in it, plus the service definition and the integration README's policy model. I traced the callers in HugeGraphAuthProxy, HugeAuthenticator.RolePerm, GraphManager, AuthenticationFilter, GraphsAPI, GraphSpaceAPI and InitStore. Local repros: Guava RateLimiter.create(1000.0) granted 2 of 10000 back-to-back tryAcquire() calls, and a JDK 17 two-package repro showed that a reflective call on a package-private class throws IllegalAccessException. CI: dependency-review fails on GHSA-c87w-642h-m97h, which this PR introduces. dependency-check failed on a Maven Central 429, which is not caused by this PR.
apache#3272 - Ranger Plugin implementation
apache#3272 - Fixed CI Errors. THe ranger plugin is opt-in, ensured that flag is placed at all places so that unrequired dependencies are not shipped in in normal flows.
- Fix minor issues
…- Rebase onto master, Ranger 2.9.0 on Java 17 Adapt to master after rebase: - ResourceObject: Nameable -> Namifiable; RangerAuthManager: Id moved to org.apache.hugegraph.id. - Ranger plugin: drop the maven-shade-plugin 3.4.1 pin and inherit 3.6.1 (3.4.1 cannot read the Java 24 classes in byte-buddy 1.17.6). Move to Ranger 2.9.0 running on Java 17: - ranger.version 2.4.0 -> 2.9.0; add ranger-audit-dest-solr (audit destinations are separate artifacts since 2.7) and exclude its slf4j-api 2.x, which turned all HugeGraph server logging into NOP. - RangerHugeGraphService: decrypt the service password Ranger Admin passes re-encrypted (resource lookup always got HTTP 401), and make Test Connection probe an authenticated endpoint and fail on 401/403. Add RangerHugeGraphServiceTest. Integration stack (docker/hgRangerIntegration): - Build and run on Java 17; Ranger image on apache/ranger:2.9.0 with a Temurin 17 JRE; copy the plugin jar without a hardcoded version. - docker-compose: pull_policy build, Ranger 2.9.0 credential variables, DB-backed healthcheck. - Test stack only: allow unauthenticated policy download, which Ranger 2.9 rejects by default. - README: create the service instance before verifying lookups, register bob/alice in Ranger before creating policies, versions and troubleshooting updates. Remove the unrelated AML showcase notebook (docker/aml_sql_showcase_hugegraph.ipynb) and its RAT excludes; license-eye cannot check .ipynb headers.
…- Never skip Ranger decisions under audit rate limiting HugeGraphAuthProxy.checkResourceAuthorizer() returned "allowed" without asking the external authorizer once the per-shape rate limiter was exhausted. The limiter key ignored label and action, so after enough allowed checks a user could pass a per-label deny, or write/delete without a Ranger decision, for the rest of the window. - ResourceAuthorizer.isAllowed() takes an audit flag; the decision must not depend on it. - Non-admin checks always ask the authorizer; the limiter only decides whether the check is audited. Admin checks stay audit-only and are skipped once the limiter is exhausted. - RangerHugeGraphPlugin evaluates unaudited checks with a null result processor, which skips the audit handler but not the policy. - Tests: authorizer can deny a locally allowed request, every call is decided when auditing is rate-limited, admin is never denied, and ResourceObject.label() for each resource kind.
bitflicker64
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: The rate-limiter bypass, the Ranger 2.4.0 CVE, the hard-coded Dockerfile version, the notebook and the Test Connection 401/403 handling are fixed at this head, and HugeGraphAuthProxyTest now covers the authorizer hook. A Ranger policy scoped to a graph space or graph still grants nothing at login, so Ranger-only users with such policies cannot log in, and the earlier comments on init-store, the reflective default-role calls, the DEFAULT-only role, CI never building the module, and the per-request probes still apply.
The earlier review comments below still apply at f02c8f4; this head does not fix them.
- Important: Blocking: yes. Summary:
init-store.shno longer asks for the admin password. Before this change the line called the privateinitAdminUser(), which reads the password from the console or stdin. It now passesauth.admin_pa, whose default is the public valuepa. A bare-metal install that enables the built-in authenticator and does not setauth.admin_panow gets an admin account with passwordpa, with no prompt and no warning. This affects everyStandardAuthenticatoruser, not only Ranger users. Evidence: at0a3e4ae5f(master's #3218, the base this PR replays) this line isauth.initAdminUser();, and that method callsthis.initAdminUser(this.inputPassword()).ServerOptions.ADMIN_PAdefaults to"pa", and the shippedconf/rest-server.propertiesleaves#auth.admin_pa=pacommented out.hugegraph-dist/docker/docker-entrypoint.sh(line 222) still documents that init-store reads the password from stdin. With this change,initAdminUser()andinputPassword()are dead code. Fix: useauth.admin_paonly when the file sets it explicitly (config.containsKey(ServerOptions.ADMIN_PA.name())with a non-empty value, the same testInitStore.checkAdminBootstrapReachableuses), and otherwise keep the prompt. The Ranger stack setsauth.admin_pa=admin, so it would still work. (#3273 (comment)) - Important: Blocking: yes. Summary: With the Ranger authenticator enabled, every default-graph and default-role call fails with
IllegalAccessException, so those REST endpoints return 500. The delegate isHugeGraphAuthProxy.AuthManagerProxy, a package-private inner class inorg.apache.hugegraph.auth.getClass().getMethod(...)returns the method declared on that class, andMethod.invokefromorg.apache.hugegraph.rangeris refused. The affected callers reach this class throughGraphManager.authManager():GraphsAPI(setDefaultGraph,getDefaultGraph),GraphSpaceAPIandManagerAPI(createDefaultRole,createSpaceDefaultRole,isDefaultRole,deleteDefaultRole). Evidence:RangerHugeGraphAuthenticator.setup()passesthis.graph.authManager()as the delegate. Withgremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy, that isAuthManagerProxy, declared asclass AuthManagerProxy implements AuthManager(HugeGraphAuthProxy.java line 1592). A two-package repro of the same shape on JDK 17 throwsIllegalAccessException: class b.Main cannot access a member of class a.Outer$AuthManagerProxy with modifiers "public", while the direct interface call works. All of these methods are already declared onAuthManagerat this head (AuthManager.java lines 259-281), so the reflection is not needed. Fix: calldelegate.setDefaultGraph(...)and the others directly, mark them@Override, and removecallDelegate. (#3273 (comment)) - Important: Blocking: yes. Summary: The role built from the Ranger grants is keyed only under graph space
DEFAULT.RolePerm.matchResource()looks uproles.get(requiredResource.graphSpace())by exact key, so a user whose access comes only from Ranger is refused in every other graph space, even under agraphspace=*policy. The per-request authorizer never gets a say, becauseverifyResPermissionconsults it only after the local match has already passed. In a PD/HStore deployment with several graph spaces, Ranger cannot grant anything outsideDEFAULT. Evidence: this line hard-codes{"roles":{"DEFAULT":{"*":{...}}}}. HugeAuthenticator.java line 438 isthis.roles.get(requiredResource.graphSpace()), which returns false when the result is null. InHugeGraphAuthProxy.verifyResPermissionthe authorizer branch is guarded byif (matched && RESOURCE_AUTHORIZER != null). Fix: build the role for the graph space being accessed (or for every graph space the user can reach), and add a test where a Ranger-only user reads a graph in a graph space other thanDEFAULT. (#3273 (comment)) - Important: Blocking: yes. Summary: The new module is built only with
-Dwith-ranger-plugin, and no workflow passes that flag. CI never compiles the module, andRangerHugeGraphPluginTestnever runs. The comment above names the trade-off, but it means the next change toAuthManagerorHugeGraphAuthProxycan breakRangerAuthManagerwithout anyone noticing. The authorizer branch added toHugeGraphAuthProxy.verifyResPermissionalso has no test: no test registers aResourceAuthorizer. A test that did would have caught the rate-limiter allow above. Evidence:git grep ranger -- .github/at this head returns nothing, and every check run on this head builds only the default reactor. Fix: add a CI job (or a server-ci step) that builds and tests the module with-Dwith-ranger-plugin. Also add aHugeGraphAuthProxyTestcase that registers an authorizer denying one label and checks that a burst of element reads filters out every element with that label. (#3273 (comment)) - Minor: Every authenticated REST request goes through this method, and
enrichWithRanger()then makes up to fiveisAccessAllowedcalls (ADMIN, READ, WRITE, DELETE and EXECUTE on*/*/all/*).RangerHugeGraphPlugin.init()setsRangerDefaultAuditHandler, so each of these calls is audited. Ranger therefore gets up to five synthetic audit records per request, on top of the real per-resource checks. Evidence:AuthenticationFilter.filter()callsauthenticate()on every non-whitelisted request, which reachesGraphManager.authenticate(), thenRangerHugeGraphAuthenticator.authenticate(), then this method. The probes are inmergeRangerRole()(lines 202-228). Fix: cache the merged role per user for a short TTL, the wayusersRoleCachedoes for the local role, or turn off auditing for these probe requests. (#3273 (comment))
…- Cover StandardAuthenticator.initAdminUserIfNeeded with unit tests
…- Address review comments: graph-space wildcard role, cached scoped login probe, init-store admin prompt, no reflection, Ranger CI job
Fixed formatting issue
Purpose of the PR
Main Changes
Added a new module:
hugegraph-server/hugegraph-ranger-pluginRangerHugeGraphAuthenticator: plugs Ranger into HugeGraph auth flow viaauth.authenticator.RangerAuthManager: delegates identity CRUD/login to existing HugeGraph auth manager, then merges Ranger grants intoRolePermission.RangerHugeGraphPlugin: wrapsRangerBasePlugin, maps HugeGraph resource/permission model to Ranger access requests, and enables audit result processing.RangerHugeGraphService: Ranger Admin-side service for Test Connection and policy editor resource autocomplete (graphspace -> graph -> resource-type -> label).RangerOptions: adds keys forauth.ranger.service_nameandauth.ranger.config.ranger-servicedef-hugegraph.jsonranger-hugegraph-security.xmlRangerHugeGraphPluginTest.Added end-to-end integration assets under
docker/hgRangerIntegrationDockerfile.hugegraph: builds HugeGraph image with Ranger plugin enabled.Dockerfile.ranger: bakes thin HugeGraph Ranger service jar into Ranger Admin classpath.docker-compose.yml: 4-service stack (Ranger Admin + Postgres + Solr + HugeGraph).ranger-audits-conf/*,solr-init.sh,ranger-hugegraph-security.xml,rest-server.properties,hugegraph.properties).docker/hgRangerIntegration/README.mddocker/hgRangerIntegration/ranger-integration-test-guide.mdPackaging/compatibility notes
Verifying these changes
mvn -pl hugegraph-server/hugegraph-ranger-plugin -am -Dtest=RangerHugeGraphPluginTest -DfailIfNoTests=false test -DskipITs -DskipIntegrationTests -Drat.skip=true -Dcheckstyle.skip=trueTests run: 4, Failures: 0, Errors: 0, Skipped: 0)docker/hgRangerIntegration/README.mdordocker/hgRangerIntegration/ranger-integration-test-guide.mdfor policy enforcement, cache-refresh, dynamic policy update, and audit checks.DDoes this PR potentially affect the following parts?
Documentation Status
Doc - TODO: required documentation is pending; complete it before merging.Doc - Done: documentation is included here or linked below.Doc - No Need: no user-visible documentation is affected.Documentation files in this PR or paired hugegraph-doc PR:
docker/hgRangerIntegration/README.mdhugegraph-server/hugegraph-ranger-plugin/src/main/resources/ranger-servicedef-hugegraph.jsonhugegraph-server/hugegraph-ranger-plugin/src/main/resources/ranger-hugegraph-security.xmlVisual overview
Proposed integration architecture, not a claim of verified policy enforcement or audit completeness.
Conceptual illustrations; not test, benchmark, security, or release-acceptance evidence.