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’ entities like blogs, products, categories and knowledge articles, or to ‘supporting’ entities 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 entities 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 entities 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 how 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 entities, 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 Email Parent Read
Email – Cases where contact is customer Email 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

Franco Musso

You may also like

2 Comments

  1. 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

    1. 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

Leave a reply

Your email address will not be published.

More in Power Pages