Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3273 +/- ##
============================================
+ Coverage 58.53% 58.57% +0.03%
- Complexity 2717 3091 +374
============================================
Files 779 779
Lines 69439 69470 +31
Branches 9577 9674 +97
============================================
+ Hits 40647 40689 +42
+ Misses 25101 25088 -13
- Partials 3691 3693 +2
*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
bitflicker64
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: The earlier findings (rate-limiter allow, init-store default password, reflection, DEFAULT-only role, Ranger CVE, CI coverage, login probe) are fixed at this head, but RangerAuthManager drops the graph-space overloads of AuthManager, so graph-space auth APIs break and skip the space-manager check in PD mode. Two smaller issues sit in the Docker integration stack.
| POSTGRES_PASSWORD: rangeradmin | ||
| POSTGRES_HOST_AUTH_METHOD: trust | ||
| ports: | ||
| - "5432:5432" |
There was a problem hiding this comment.
Minor: ranger-db runs with POSTGRES_HOST_AUTH_METHOD: trust and publishes 5432 on every host interface, so anyone who reaches the host can rewrite Ranger policies and grant themselves HugeGraph access. Drop the ports entry (Ranger reaches the database over the compose network) or bind it to 127.0.0.1.
There was a problem hiding this comment.
Addressed in recent commit
…- Address review comments: forward graph-space auth methods, restrict demo stack ports - RangerAuthManager: forward supportsGraphSpaceAuth() and every graph-space overload (deleteGroup, target/belong/access CRUD and listings) to the delegate. The AuthManager defaults reported no graph-space support in PD mode, skipping manager permission checks, dropping the graph space from target/belong/access calls and failing scoped group deletion. - RangerAuthManagerTest: fail when any AuthManager default is not overridden, and verify graph-space calls reach the delegate unchanged. - docker-compose: stop publishing ranger-db (trust auth) to the host and bind ranger-solr to 127.0.0.1. - README: note ranger-db is internal only and fix stale docker/ranger-integration paths in Steps 8, Teardown and Troubleshooting.
…- Cover "*" resource graph space in RolePerm wildcard match A resource whose graph space is literally "*" is matched by the exact-key lookup only; the wildcard fallback is skipped. Cover both outcomes so the !GENERAL_PATTERN.equals(space) guard is exercised on each branch.
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.