Skip to content

UNOMI-1001: Restore 3.0 peer abilities in compatibility mode - #914

Merged
sergehuber merged 4 commits into
masterfrom
UNOMI-1001-compat-peer-abilities
Oct 9, 2026
Merged

sergehuber merged 4 commits into
masterfrom
UNOMI-1001-compat-peer-abilities

Conversation

@sergehuber

@sergehuber sergehuber commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Peer abilities in compatibility mode

  • In single-tenant compatibility mode, a valid X-Unomi-Peer key from an allowed IP again grants the Unomi 3.0 peer abilities on public endpoints only: set event id, choose body profile id, merge on login, update other profiles (segments/scores/consents/systemProperties). No administrator roles; private endpoints unchanged.
  • UNOMI-975 / UNOMI-978 trust gates stay in force for visitors without a valid peer.

Provider configuration fails closed

  • A provider key that is empty, shorter than 16 characters, or equal to the well-known example key disables the provider at startup unless allowExampleKey=true. Keys are compared in constant time.
  • abilities omitted grants all four (3.0 behaviour); an empty value grants none; a value that names no known ability (for example a misspelt one) disables the provider with an error.
  • A provider without ipAddresses is refused from every address, as in Unomi 3.0.1. The key alone is never enough.
  • X-Forwarded-For is used only when the direct address is in trustedProxies, and is read from the last entry backwards, skipping trusted proxies, so a client-supplied leading entry is ignored.
  • A present but rejected X-Unomi-Peer header is logged at WARN with its reason (unknown key, or IP not in the allowlist). Malformed ipAddresses / trustedProxies entries are reported at startup.

Profile merge protection

  • New setting org.apache.unomi.plugins.base.requireSecureTransport (UNOMI_REQUIRE_SECURE_TRANSPORT), false by default. When on, a tenant private key or administrator login may only merge profiles, record a merge identifier, update another profile or write systemProperties on a request received over HTTPS (HttpServletRequest.isSecure()), or from a proxy in org.apache.unomi.ip.trustedProxies that sends X-Forwarded-Proto: https. X-Unomi-Peer keys in compatibility mode are not affected.
  • REST and GraphQL clear any leftover subject at the start of each request, and the merge's background task restores the scheduler thread's subject when it finishes.

API

  • CompatPeerPrincipal (final; rejects unknown ability names; an empty set means no abilities).
  • InsecureTransportPrincipal, a marker for a request subject whose request was not encrypted.
  • SecurityService.hasCompatPeerAbility(String) and SecurityService.recordRequestTransport(...), both default methods so other implementations keep working.

Behaviour changes to note

  • The shipped provider1 uses the example key, so it is disabled unless the key is replaced or allowExampleKey=true is set.
  • A provider with an empty ipAddresses list no longer accepts its key from any address.

Test plan

  • mvn -pl api,services-common,rest,plugins/baseplugin,graphql/cxs-impl -am test
  • Local integration tests on Elasticsearch
  • Local integration tests on OpenSearch (402 tests, 0 failures)
  • CI unit tests
  • CI integration tests (Elasticsearch)
  • CI integration tests (OpenSearch)

https://issues.apache.org/jira/browse/UNOMI-1001

🤖 Generated with Claude Code

sergehuber and others added 4 commits October 9, 2026 15:19
A valid X-Unomi-Peer key from an allowed IP again grants setEventId,
chooseProfileId, mergeOnLogin and updateOtherProfiles on public endpoints
only, without administrator roles. Harden provider keys (length, example
key, constant-time compare) and honor X-Forwarded-For only behind trusted
proxies.
Add unit and IT coverage for non-compat peer no-op, ability subsets,
XFF behind trusted proxies, and peer-denied private endpoints. Document
operator guidance for ipAddresses and trustedProxies.
Deleting org.apache.unomi.thirdparty left later suite tests with no
providers, so login stopped being protected. Snapshot/restore instead,
and wait for persisted peer event ids.
Peer configuration no longer fails open: abilities that name no known
ability disable the provider, an empty abilities value grants none, and
a provider without an IP allowlist is refused from every address, as in
Unomi 3.0. X-Forwarded-For is read from the last entry backwards so a
client-supplied leading entry is ignored, and a rejected X-Unomi-Peer
header is logged with its reason.

Add requireSecureTransport (off by default): when on, a private key or
administrator login may only merge profiles or make other identity
claims over HTTPS, or behind a trusted proxy reporting it. Peer keys in
compatibility mode are not affected.

Clear any leftover subject at the start of REST and GraphQL requests,
restore the scheduler thread's subject after a merge task, and make
hasCompatPeerAbility a default method so other SecurityService
implementations keep working.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sergehuber
sergehuber merged commit facb23e into master Oct 9, 2026
7 checks passed
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.

1 participant