Note – this post-is a follow-up / alternative perspective to my previous post, Portal security: table permissions and web roles – the theory
I originally learned about table permissions and web roles by studying the config that comes as part of the Customer Self-Service starter portal, so I thought that might be the best way to introduce the concepts to you…
The customer self-service portal allows customers to raise, manage and track cases and activities. As a customer, there are certain aspects of security we take for granted when using self-service portals / case management systems:
- Access is secured
- The privacy of customers is protected, not allowing them to see each others details or update one another’s cases
- Customers have the means to provide feedback and respond to queries in order to progress their cases
This is all very doable but requires some config to set up.
Let’s take a look at the table permissions that enable this common scenario…
Access Types
Self
We’ll start with the least common of access types: Self
In addition to managing cases and activities, portals often allow self-service changes to contact information and communication preferences. Here’s how that table permission looks:
Field | Value | What this does / means | |||
Table name | Contact | ||||
Access Type | Self | No need to specify a relationship – the logged in portal user (contact’s) own record | |||
Privileges | Read | Write | Append
Append To |
Let the logged in portal user update their own contact record and to select themselves in lookup fields – but don’t allow them to create new contacts (unless other tale permissions allow them to), or delete their record |
Note – this table permission doesn’t magically allow the contact to see the account they belong to… not even to see the Company Name lookup field. That’ll be covered later, and will be based on the relationship the contact has with that account.
Global
This tends to apply to either ‘public-facing’ tables like blogs, products, categories and knowledge articles, or to ‘supporting’ tables such as units, currencies, languages etc. In each of these examples, there is no concept of ‘ownership’ by a particular contact or account (no relationship between these records and the visitor is required in order to see or interact with them).
Instead, as the name suggests, each record is global – it makes sense to be visible and accessible to any portal visitor.
You can still choose to restrict these tables to logged in users (the Authenticated Users web role) or to have them visible and selectable to the whole world (the Anonymous Users web role)
Examples of tables from the Customer Self-Service portal with permissions set at Global access type:
- Product
- Knowledge Article
- Category
Contact
Next, let’s see what the contact has access to because of a direct relationship they have with that record (e.g. their contact record is selected in a lookup field).
These will have an Access Type of Contact
We’re now in the realm of security trimmed access. Answering the question ‘Do you know who I am?’ or maybe that’s better phrased as “If your name’s not down, you’re not coming in“. Here’s what I get access to on the Customer Self-Service portal by virtue of being me (and being selected as a contact on these records):
Name (abbreviated for ease!) | Table | Access Type | Privileges | |||
Cases where contact is customer | Incident (case) | Contact | Read | Write | Create
Append Append To |
|
Contact of the Contact | Contact | Contact | Read | Append | ||
Primary Contact of the Account | Account | Contact | Read | Append | ||
Activity Pointer where contact is customer | Activity Pointer | Contact | Read | |||
Account of the Contact | Account | Contact | Read | Append |
Even though these are for various different tables, they’re all secured based on their relationship to the contact.
Account
These fall into the category of… you know my employer / I have a business relationship with this record
Name (abbreviated for ease!) | Table | Access Type | Privileges | |||
Cases where account of the contact is customer | Incident (case) | Account | Read | Write | Create
Append Append To |
|
Activity Pointer where account of the contact is customer | Activity Pointer | Account | Read |
So far we’ve seen how to restrict access to records that the portal user’s contact record is directly related to, or that are related to that contact’s account.
Next we’ll see how to provide access on the basis of “I should be allowed to see this child record because it ‘belongs to’ to a record that’s in my name (or my company’s name)”
Parent
Full disclosure: This really confused me to begin with… Parent access type applies to *Child* records. Please bear with me as I labour the point to try and make sense of this for you…
Maybe a better way of trying to understand this concept is that the key to unlocking access to this record is not via a direct relationship but through a Parent record that does have a relationship with the contact or their account. Me or my company don’t have a direct relationship with this lower level record (note, activity, etc.) but we do have a direct relationship with its parent.
To clarify, we’re talking about records that belong to (‘sit under’) security trimmed records – notes, activities, portal comments, etc. These might be vital in understanding the progress of the case but don’t have a direct relationship to the contact or their account that we can use to support them.
Example
Take a note regarding a case for example – there’s no way of specifying that the note is also regarding a particular contact or account. That record is 2 ‘hops’ away from contact or account (Note > Case > Contact). Sometimes what we need will be even further away, like notes or portal comments regarding activities that are related to a customer’s case (Note > Activity > Case > Contact)
Here are some out-of-the-box examples to help illustrate the point:
Name (abbreviated for ease!) | Table | Access Type | Privileges | |||
Customer Service – Case Notes where contact is customer | Annotation (Note) | Parent | Read | Write | Create
Delete Append |
|
Customer Service – Case Notes where account of the contact is customer | Annotation (Note) | Parent | Read | Write | Create
Delete Append |
|
Customer Service – Activity Pointer on Case where contact is customer | Activity Pointer | Parent | Read | |||
Customer Service – Activity Pointer on Case where account of the contact is customer | Activity Pointer | Parent | Read | |||
Email – Cases where account of the contact is customer | Parent | Read | ||||
Email – Cases where contact is customer | Parent | Read | ||||
Portal Comment – Attachments where account of the contact is customer | Annotation (Note) | Parent | Read | Write | Create
Append Append To |
|
Portal Comment – Attachments where contact is customer | Annotation (Note) | Parent | Read | Write | Create
Append Append To |
|
Customer Service – Portal Comment where account of the contact is customer | Portal Comment | Parent | Read | Write | Create
Delete Append Append To |
|
Customer Service – Portal Comment where contact is customer | Portal Comment | Parent | Read | Write | Create
Delete Append Append To |
Quick note re. activities – what is activity pointer?
The generic ‘activity pointer’ table covers all activity types. You can use this to set basic read permissions for all activity types and then create separate table permissions for specific activity types like emails and portal comments as required
Potential gotcha: Lookup fields
Tip – don’t forget lookup fields… You could for example, do everything to securely share the account table but still experience error messages on your forms and lists if you forgot to consider the Primary Contact lookup. That requires at least Read permissions on the Contact table for the field to display. To actually select a contact in the lookup, you would need the following:
- A table permission with the Append privilege on the Contact table
- A table permission with the Append To privilege on the Account table
Further reading
For a deep dive into the topic of securing portal content, see Nick Doelman’s epic deep-dive course over at 365.training
How to configure in power pages that portal users (contacts) can see other contacts cases within the same company (account) ? – not only own cases but all company cases created by other co-workers as well
My Open Cases
My Open Organisation’s Cases
Hi Mariusz
The short answer for how to create My Organisation’s Cases (assuming the account is selected as the customer on the case) is create a table permission with these settings:
Table: Case (incident)
Access Type: Account access
Relationship: incident_customer_accounts
The main difference between the two permissions in your example would be the Access Type:
Access Type = Contact the logged in user has a relationship with the record e.g. they’re selected in the Contact or Customer lookup field). This would work for My Cases in your example (‘open’ isn’t relevant to permissions)
Access Type = Account means the logged in user’s account has a relationship with the record e.g. is selected in the Account or Customer lookup
With either of these access types, you’ll need to select which relationship to use e.g. for account, are the records related to the case via the account lookup or the customer lookup
If the account doesn’t have a relationship to the case then it gets a little more complicated… I’d create a table permission called Contacts at My Account with these settings:
Table: Contact (contact)
Access type: Account access
Relationship: contact_customer_accounts
And then create a child permission under that called Cases for Contacts at my Account with these settings:
Table: Case (incident)
Relationship: incident_customer_contacts