-
Notifications
You must be signed in to change notification settings - Fork 15
Portal Privacy
Where: Tickets β Settings β Privacy Default: Hide them from the requester Affects: the self-service portal only. Nothing changes for analysts.
A ticket is not only your conversation with the person who raised it β and until this setting existed, the portal showed them all of it.
When an analyst forwards a ticket to a supplier, or copies in a colleague, that message is filed on the same ticket. So is the supplier's reply. That's exactly what you want internally: one ticket, one complete history, nothing scattered across mailboxes.
But the self-service portal was showing the requester that entire history. So correspondence about them was visible to them:
"Hi Dave β sending this one over, the customer's being difficult about the renewal. Pricing sheet attached."
β¦appearing in the customer's own portal, with the pricing sheet downloadable.
| Option | The message | Its attachments |
|---|---|---|
| Hide them from the requester (default) | Not shown at all | Not downloadable |
| Show the message, but not its attachments | Shown | Not downloadable |
| Show everything | Shown | Downloadable |
Show everything is exactly how FreeITSM behaved before this setting existed. If your team relies on the requester seeing forwards β some desks deliberately work "in the open" with their customers β choose it after updating.
Three things are decided elsewhere and are unaffected by whichever option you pick:
- Internal notes are never shown in the portal. They never were. That's what the Internal flag on a note is for, and it remains the right place for anything you don't want the customer reading.
- The requester's own messages are always shown. Anything they sent you, and any reply addressed to them.
- WhatsApp and web chat conversations are always shown in full. Those exchanges are between the requester and your desk by definition β there is no "forward" on those channels, so there is nothing to hide. (See How the rule works for why this needs stating explicitly.)
Here is the part worth understanding, because it explains the edge cases.
FreeITSM does not record that a message was a forward. A forward and an ordinary reply are stored identically β same table, same columns, same everything. Adding a "this was a forward" marker would only work for mail sent after the update, leaving every forward already in your system visible forever.
So instead of asking "was this a forward?", FreeITSM asks the question that actually matters:
Was this message to, or from, the person who raised the ticket?
If yes, it's their correspondence and they see it. If no, it's third-party and the setting decides.
That single question is better than a forward flag in three ways: it catches CCs to colleagues as well as forwards, it catches the supplier's reply coming back in, and it works on every ticket you already have with no migration.
Some messages can't be judged by that question, and every one of them is shown:
| Situation | Why it's shown |
|---|---|
| WhatsApp / web chat | Addressed by phone number or visitor id β the requester's email matches nothing, so an address check would hide their whole conversation from their own portal |
| A message with no recipient recorded | Nothing to compare against |
| A requester with no email address on file | Nothing to compare against |
This is deliberate, and it's the one place the design leans away from privacy on purpose:
Hiding an analyst's genuine reply is worse than showing a forward. A customer who can't see the answer concludes nobody helped them, opens a second ticket, and phones you. Ambiguity therefore resolves to visible, and the strict direction is something an admin chooses per option β never something FreeITSM guesses at.
Assume Sarah Chen (sarah.chen@northwind.co.uk) raised ticket ABC-123-45678 about a broken laptop, and your service desk mailbox is support@yourcompany.com.
An analyst replies to Sarah.
| From | support@yourcompany.com |
| To | sarah.chen@northwind.co.uk |
Sarah is a recipient β her correspondence β always visible, under all three options. Her attachments download normally.
The laptop is under warranty, so an analyst forwards the ticket to the vendor, attaching the diagnostic report.
| From | support@yourcompany.com |
| To | warranty@laptopvendor.com |
Sarah is neither sender nor recipient β third-party.
- Hide β Sarah sees nothing. Her thread jumps from the analyst's last reply to whatever comes next.
- Show without attachments β Sarah sees "we've raised this with the vendor" and the message body, but cannot download the diagnostic report.
- Show everything β Sarah sees the message and can download the report.
The vendor answers, and their reply lands on the same ticket.
| From | warranty@laptopvendor.com |
| To | support@yourcompany.com |
Still neither to nor from Sarah β third-party, and handled exactly like Example 2. This is the case a "was it a forward?" rule would have missed entirely β the reply isn't a forward, it's an ordinary inbound email.
An analyst replies to Sarah and CCs a network engineer.
| From | support@yourcompany.com |
| To | sarah.chen@northwind.co.uk |
| Cc | ravi@yourcompany.com |
Sarah is a recipient β visible. Being copied to someone else doesn't make it private from her β she's still being written to. The setting is about correspondence that isn't hers, not about who else is on it.
Sarah's ticket came in over WhatsApp, addressed by her phone number.
Always visible in full. Her email address doesn't appear anywhere on those messages, so a strict address check would have hidden her own conversation from her. Chat channels are exempt for exactly this reason.
Always visible. She wrote it.
The setting is enforced twice β once when building the conversation, and again when a file is actually requested.
That matters more than it sounds. Attachments are fetched by a numeric id in the URL, and those ids are sequential and easy to guess:
/api/self-service/get_attachment.php?id=39
Simply leaving the link out of the page would be decoration, not protection β anyone could type the URL. So the download endpoint applies the same rule independently and returns a plain 404 when it doesn't pass.
Two related guarantees, both verified:
- You can only ever reach attachments on your own tickets. The check walks attachment β message β ticket and requires you to be the person who raised it. A wrong id and someone else's id both return the same bare 404, so the portal never even confirms that another customer's file exists.
- The portal is never told who else was on an email. The sender and recipient fields are used to make the decision server-side and then removed from the response.
| If your desk⦠| Choose |
|---|---|
| Treats forwarding to suppliers as internal business (most desks) | Hide them |
| Wants customers to see that work is happening, without exposing what was sent | Show the message, not attachments |
| Works transparently with customers and relies on them seeing the full trail | Show everything |
If you're unsure, keep the default. It matches what most people assume is happening, and it's the only option where forwarding a ticket can't surprise you.
| File | Role |
|---|---|
includes/portal_visibility.php |
The rule, the policy reader, and the three constants. One place, so the listing and the download can't disagree |
api/self-service/get_ticket_detail.php |
Filters the conversation; strips the routing fields from the response |
api/self-service/get_attachment.php |
Enforces the same rule on download, independently |
tickets/settings/index.php |
The Privacy tab UI |
tickets/settings/manifest.php |
Declares the tab, its capability and its setting key |
includes/capabilities.php |
Cap::TICKETS_PRIVACY |
Stored as the portal_third_party_visibility system setting (hide / no_attachments / show). Absent means hide, so a fresh or upgrading install is protected before anyone finds the screen. No database change is needed for this feature.
- Self-Service Portal β the portal itself
- Tickets β forwarding, replies and internal notes
- Admin Access Control β the capability that controls who can change this
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
- MobileβFriendly
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)