Account-restricted Objects: make a role grant required for VIEW, so duties can be separated within one B2B account

The problem

In a B2B portal, one customer is one Account, and that customer’s employees have different responsibilities. Some work with asset data, some with renewals, some only place orders in the webshop.

Liferay lets us control which applications an employee sees, through regular roles. It does not let us control which data they can read. Every user attached to the account can retrieve the complete contents of every account-restricted Object through the headless API, no matter which roles they hold. The separation we build at the application layer stops at the UI; the data behind it is open to everyone attached to the account.

This is not a cross-tenant issue — users never see other accounts’ data. It is separation of duties inside one customer organisation, and today it cannot be expressed at all.

Why it happens

accountEntryRestricted behaves as an additional grant, not as a narrowing filter. The permission check for VIEW returns true as soon as the user is attached to the entry’s account, and no role is consulted at that point. Because Liferay’s permission model is additive, nothing can subsequently take that grant away.

The consequence is that the condition is effectively is_attached_to_account, where what a B2B installation needs is is_attached_to_account AND has_role_with_view.

Proposed solution

Let account restriction act as a narrowing filter rather than a grant:

A user sees an entry when (a) a role they hold has been granted VIEW on the object, and (b) the entry belongs to an account they are attached to.

The role decides whether, the account decides which. The documentation already describes grants as being scoped this way; it simply never makes the grant required.

Changing the semantics globally would silently remove access on existing installations, so please consider an opt-in setting on the object definition — something like “Require explicit VIEW permission” next to the existing account restriction, defaulting to off. Unlike account restriction itself, this setting should remain changeable after publishing, so existing objects can adopt it.

Related

Security concern: Bypassing Account Restriction for individual ownership in Liferay Objects describes the same root cause on a different axis — separating by creator rather than by role within one account. Both would be solved by making the grant a required condition.

Why this matters beyond one installation

Any B2B portal where a customer is one account, and that customer has more than a handful of employees, runs into this as soon as the data is differentiated: invoices, contracts, asset inventories, service levels, support tickets. The only workaround available today is splitting one customer across several accounts, which breaks account master data, contacts, order history and user administration.