Skip to content

SOLR-13097: Make core-scoped authorization rules work in Solr standalone mode - #5016

Open
nick-boss-tech wants to merge 11 commits into
apache:mainfrom
nick-boss-tech:solr-13097-submit
Open

nick-boss-tech wants to merge 11 commits into
apache:mainfrom
nick-boss-tech:solr-13097-submit

Conversation

@nick-boss-tech

@nick-boss-tech nick-boss-tech commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

🤖 AI text below 🤖 (posted on behalf of Nick Shanin)

https://issues.apache.org/jira/browse/SOLR-13097

What happens today

In standalone (non-cloud) Solr, authorization rules in security.json that are scoped to a specific core do not take effect the way they do in cloud mode: the authorization check runs without the serving core's name as its context, so a rule written for one core does not match, and a user can be allowed on a core that a core-scoped rule was meant to deny them.

What this change does

HttpSolrCall now passes the serving core's name as the collection context for the authorization check in standalone mode, so core-scoped rules apply to the core actually serving the request. Cloud behavior is unchanged. The change is noted in the Solr 10.2 upgrade notes (major-changes-in-solr-10.adoc), and the rule-based authorization ref guide now states that in standalone mode the collection permission value can be the name of a core, and that for a distributed request only the core receiving the request is checked. The upgrade note sits in the Solr 10 upgrade notes because this change is intended for backport to branch_10x (10.2); if maintainers prefer it main-only, the note can move to the Solr 11 upgrade notes page instead.

Proof

  • CoreScopedAuthStandaloneTest: 5 of 5 pass with this change, verified at head f0e7395; tidy, the Error Prone compile and :solr:core:check -x test pass as well. Added in this round: a v2 request through V2HttpCall (/api/cores/<core>/select under the same core-scoped permission) and a wildcard permission alongside the scoped rules, pinning that a scoped rule governs its core on its own and the wildcard decides only for cores no scoped rule governs. Against base production code the v2 and wildcard cases fail for the reason this PR fixes (3 of 5 methods fail on base under the extended configuration). On base code, testScopedRuleDeniesOtherRolesOnTheCore also fails in the original configuration: it expects a RemoteSolrException denying a role scoped to another core, and no exception is thrown (4 failing test executions under randomization).
  • The shards behavior described in Limits was checked with a temporary probe test (not shipped), re-run at head 4c08aa5 on 2026-10-06 in three authentication configurations: both cores governed with blockUnknown at its default, both cores governed with blockUnknown=false, and the target core ungoverned with blockUnknown=false. The observed outcomes match the Limits text.

Limits

  • Standalone mode only. The authorization context is exactly the serving core's name, so rules scoped to anything other than that name do not match, and renaming or swapping a core moves which scoped rule applies to it. The v2 API path passes the same authorization context, so a v2 request served by a core in standalone mode is authorized against the core name as well; the test covers both the v1 /select path and a v2 /api/cores/<core>/select request. Requests with no serving core, such as /admin/cores?action=...&core=x, are unchanged by this PR: no core name is added for them, and they are authorized as admin requests, as before. Cloud mode is untouched by this change and is not exercised by the new test.

  • In standalone mode a request that fans out to other cores through the shards parameter is authorized here only against the serving core. Authorization in this plugin returns the decision of the first listed name that has a governing permission, so listing every shard core would not subject each one to its own check; the per-core check for a shard happens on the node that serves it. Such sub-requests send no user credentials under BasicAuth with default settings; under JWT authentication the caller's token is forwarded, so the receiving core authenticates and authorizes the actual user. With blockUnknown at its default (true), the receiving core rejects them at authentication. With blockUnknown=false, a target core that has a governing permission still denies the credential-free sub-request, at authorization. A target core with no governing permission at all, and no wildcard permission either, can return its documents to the caller in that configuration. That last case is the plugin's designed treatment of names with no configured permission, it behaves the same in cloud mode, and it is not a gap this PR opens.

Changelog: changelog/unreleased/SOLR-13097.yml

AI assistance

AI agents assisted with research, implementation, review, and drafting. Nick Shanin directed the work and takes responsibility for this contribution.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 3, 2026
…in test

String.formatted uses the default locale and is rejected by the
forbiddenApis check, which failed the core check step.
Comment thread solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
Comment thread solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-11.adoc Outdated
Comment thread changelog/unreleased/SOLR-13097.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The focused implementation, tests, and documentation consistently address the reported authorization gap.

Review effort: Balanced
Findings: None

What changed in this PR

Enables core-scoped authorization rules in standalone Solr by using the serving core name as authorization context.

Changes:

  • Authorizes standalone requests against the serving core.
  • Adds integration coverage for allowed, denied, and unauthenticated requests.
  • Documents the behavioral change in upgrade notes and changelog.
File Description
HttpSolrCall.java Supplies the standalone core name during authorization.
CoreScopedAuthStandaloneTest.java Tests core-scoped standalone authorization.
major-changes-in-solr-11.adoc Adds upgrade guidance.
SOLR-13097.yml Records the change.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@janhoy
janhoy requested a review from dsmiley October 6, 2026 22:00
…tandalone test

Adds a v2 /api/cores/<core>/select case through V2HttpCall and a case
pinning how a wildcard permission interacts with core-scoped rules: the
scoped rule governs its core on its own, and the wildcard decides only
for cores no scoped rule governs. Also states in the ref guide that for
a distributed request only the core receiving the request is checked.
@dsmiley
dsmiley removed their request for review October 7, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cat:security documentation Improvements or additions to documentation jetty-server tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants