Skip to content

Visibility Rules

Scoutify is secure-by-default. Since v1.12.0, visibility rules are used to control access to search results.

By default, guests cannot see search results, and authenticated users can only see results they are authorized to view via policies. Visibility rules allow you to define these permissions fluently on the model itself.

To customize visibility, implement the HasGlobalSearchVisibility contract and the globalSearchVisibility() method:

use Matheusmarnt\Scoutify\Authorization\VisibilityRule;
use Matheusmarnt\Scoutify\Contracts\HasGlobalSearchVisibility;
use Illuminate\Database\Eloquent\Model;
class Article extends Model implements HasGlobalSearchVisibility
{
public function globalSearchVisibility(): VisibilityRule
{
return VisibilityRule::make()
->visibleToGuests()
->orWhenAuthenticated()
->policy('view');
}
}
MethodArgumentEffect
visibleToGuests()Allow unauthenticated viewers.
orWhenAuthenticated()Chain clause for authenticated users.
policy(string $ability)ability nameRun Gate::check($ability, $record).
permission(string|array $perm)Spatie permission(s)$user->hasPermissionTo($perm).
role(string|array $role)Spatie role(s)$user->hasRole($role).
attribute(string $attr, mixed $val)column + expectedCompare model column (default true).
using(callable $fn)fn($rec, $user)Custom resolver logic.

Rules are combined using logical OR by default. You can change this behavior to require all rules to pass:

return VisibilityRule::make()
->role('admin')
->attribute('is_active', true)
->mode(VisibilityMode::All); // Logical AND

A Post model that is visible to guests if published, or to the author if it’s a draft:

public function globalSearchVisibility(): VisibilityRule
{
return VisibilityRule::make()
->visibleToGuests()
->attribute('status', 'published')
->orWhenAuthenticated()
->using(fn ($record, $user) => $user->id === $record->author_id);
}