---
title: "Privacy and authorization — Events for Laravel | Roundly"
description: "Who sees an event, what each surface hides, the EventPolicy abilities, the venue rules and the visitor-IP note for near-me search."
url: https://roundly-consulting.com/open-source/docs/events-for-laravel/privacy
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Events for Laravel](https://roundly-consulting.com/open-source/docs/events-for-laravel.md)

# Privacy and authorization

One rule (Support\\EventVisibility) feeds both Event::scopeVisibleTo($viewer) — and with it Events::visibleTo() and Events::browse() — and EventPolicy::view, so a list and a detail page never disagree:

| Who | Draft | Public | Unlisted | Private |
| --- | --- | --- | --- | --- |
| Managers | ✓ | ✓ | ✓ | ✓ |
| Invitees (pending, accepted) | — | ✓ | ✓ | ✓ |
| Attendees (active RSVP) | — | ✓ | ✓ | ✓ |
| Anyone with the uuid link | — | ✓ | ✓ | — |
| Lists, search, feeds, slug lookups | — | ✓ | managers, invitees, attendees | managers, invitees, attendees |

Unlisted events are link-only: found by uuid, never by slug for strangers, never listed.

## What each surface hides

| Surface | Rule |
| --- | --- |
| browse(), the API index, search | Visible and listed and announced. |
| Route-model binding, Events::find() | By uuid only, never the sequential id or the slug; no visibility rule — authorize view. |
| The API | A hidden event is a 404, exactly like a missing one, on every endpoint. |
| The join link (online\_url) | Encrypted at rest; only managers and going attendees (viewOnlineUrl) — API, calendar files, notices; never in feeds or JSON-LD unless expose\_online\_url. |
| Guest list | guest\_list: hidden (managers), attendees (going attendees), public (viewers). Interested people, the check-in record and the status / checked\_in / tier filters are managers-only. |
| Counts | Managers, or viewers when show\_counts — the event’s counts and seats\_left and each ticket type’s seats\_left; sort=popularity ranks hidden counts as zero. Whether an event is full is public; the numbers are not. |
| Check-in codes | Encrypted, hash-indexed, never in managers’ lists, domain events, logs or about; the QR is never cached. |
| Calendar files | Events::ics() skips events the viewer may not see; a single event’s ics($viewer) throws the uniform EventNotFoundException; drafts are never exported. |
| JSON-LD and URL templates | Public, announced events only (unlisted with seo.json\_ld.unlisted), never private; unlisted and private events never get a {slug} URL. |
| Notices | Recipients filtered by visibility when sent and again when delivered; no other attendee’s data. |
| Public filters | ?organizer= (feed) and filter\[organizer\] (index) never look the organizer row up — no existence oracle for your users’ keys. |
| API writes | Never without a signed-in Eloquent user (401), whatever events.routes.auth\_middleware holds. |

## The policy

Policies\\EventPolicy and Policies\\VenuePolicy are registered unless events.authorization.register\_policy is off. Events::for($event)->by($user) checks the policy before every call — the writes and the reads that reveal people; without by() the call is trusted code:

| Ability | Who |
| --- | --- |
| `viewAny` | Anyone, guests included. |
| `view` | The visibility rule above. |
| `create` | Authenticated, plus events.authorization.abilities.create when set. |
| `update, delete, restore, publish, unpublish, postpone, reschedule, cancel, complete, transition, moveOnline, manageTiers, invite, manageAttendees, checkIn, viewWaitlist` | Managers. |
| `manageHosts, transfer` | The organizer’s approved users, or an admin. |
| `rsvp` | view + the phase and window rules + the private-event invitation rule. |
| `viewAttendees` | Managers; going attendees with guest\_list = attendees; viewers with public. |
| `viewInterested` | Managers. |
| `viewCounts` | Managers, or viewers with show\_counts. |
| `viewOnlineUrl` | Managers and going attendees. |

An undefined ability denies — with events.admin undefined, nobody is an admin. Swap the policy with events.authorization.policy, extending the package’s class. With registration off and no policy of yours, by() still never silently allows: the configured class is asked directly.

## Venues

Anyone views a venue, and any organizer may hold an event at any venue. Creating needs an authenticated user, plus abilities.venues when set. An owned venue is managed by its owner’s approved users and admins and created only by someone the owner allows, so nobody plants a venue into another team’s list. A shared venue sits under other organizers’ events, so only admins and holders of abilities.shared\_venues create, edit, geocode or delete one.

## Visitor IPs

Geolocation::locateRequest($request), the usual near-me starting point, sends the visitor’s IP address to geolocation-for-laravel’s IP providers. Mention it in your privacy notice, or ask for the location instead.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/events-for-laravel.md)
