Skip to main content

Access control

Access control is your application's job. By default binding resolves any row — Polyslug does not own your tenant or publish state.

polyslugResolveQuery — the resolution gate​

Override polyslugResolveQuery() to inject those scopes. A model outside the scope then resolves to a 404 that is indistinguishable from a nonexistent one — no existence oracle — and the gate is enforced uniformly across bound routes, the polymorphic resolver, and /go short links:

use Illuminate\Database\Eloquent\Builder;

public function polyslugResolveQuery(Builder $query): Builder
{
return $query->where('tenant_id', currentTenant()->id)->where('published', true);
}

The default implementation is a no-op, so this is opt-in — but for a multi-tenant or draft-carrying model it is the required isolation contract, not an optimization. Every resolution path funnels through it, including polyslugResolveByKey(), which is what makes the /go short-link route gated too. Since 0.18.7 polyslug:sitemap reads each configured type through it as well, so a row the gate hides is never submitted.

polyslugIsRoutable — the output filter​

polyslugIsRoutable(?string $locale = null): bool is the companion for output. Return false to keep an unpublished model — or one specific locale — out of your hreflang sets and sitemaps:

public function polyslugIsRoutable(?string $locale = null): bool
{
return $this->status === 'published';
}

The two are complementary and you usually want both: polyslugResolveQuery() decides what a visitor may reach, polyslugIsRoutable() decides what you advertise. A draft filtered only from the sitemap is still reachable by anyone who guesses the URL. A draft blocked only at resolution stays out of the sitemap polyslug:sitemap writes, but a sitemap your own code builds still lists it unless polyslugIsRoutable() says no.

Do not rely on token opacity​

An identity encoder chooses how much the URL reveals, but no encoder is an authorization check. A leaked or shared URL still carries a valid token, so the gate above is what decides whether it resolves.

See also the multi-tenant SaaS and marketplace recipes, which wire both hooks end to end.