Saturday, 25 November 2023

The SUGCON ANZ 2023 Experience

That's a wrap for SUGCON ANZ 2023 in sunny Brisbane!  I was fortunate enough to be able to make it, and as my first experience of Brisbane it was lovely to have been to spend some time before the event running along the banks of the Brisbane River on the Thursday morning after I landed, as well as experience some of the evening atmosphere on the Thursday evening going out to dinner with some of the crew.  What a great city!  It was also fantastic to see so many familiar faces, and meet a bunch of new ones as well. Everyone was super friendly and up for a chat - plus it helps that we all have (at least) one thing in common!

I thought it would be worth sharing a summary of events for those who couldn't make it - hope to meet some more of you next year!

Day 1 (Thursday)

Richard Hauer - as one of the organisers - kicked things off with a brief welcome, and was quickly followed by Gus Quiroga (Sitecore AVP) who invited us all to be "open to inspiration", providing a few examples of a few historical figures who proved that we “don’t have to re-invent, only to re-imagine”.


Vignesh Vishwanath
ran the first session "Migrating from Platform DXP to Composable DXP". He started by asking for a show of hands for which version(s) of Sitecore you're currently working on. For the 10.x series there was a fairly even split of the room, by the time we got to 9.2 there were only a couple of hands, but the big surprise was the few hands for 8.x, 7.x, and 6.x!! Obviously some happy (or scared) customers to still be running those ancient versions.  He assured everyone that XP wasn't going away, and that 10.4 would be released Q4 of 2024, and that obviously all the new composable stack was still very much compatible with the platform (XM/XP) products.
He then ran us through a couple of products which the Sitecore team are working on to assist the migration from platform XP ("the monolith") to composable: 

  1. xDB -> CDP (+ eventually Send) migration for Sitecore 9.0+
    If you have XP + CDP even though this uses Connect it would come at no additional cost.
    1million users (with a couple of custom facets) migrated in ~9hrs
    They're currently looking for pilot projects, if you'd like to be involved!

  2. XM on-prem content + users (10.1+) -> XM Cloud migration
    GUI based
    Select your content items and/or users and the tool handles the rest
    No size limits
Very exciting stuff! No doubt will be incredibly useful for many clients.


Next Greg Baxter ran a session on "Which Sitecore Personalisation Tool is Right for You?" where he took us all (in great detail, as he describe it: "a rabbit hole") through different ways to personalise depending on "where you are at, and where you want to go".  XP is still very robust and reliable, but if you haven't yet started on the journey then it's best to go with XM Cloud (to start with) and/or Personalize (for those who need more); the future is clearly the latter options.

The Dataweavers team, in their quick sponsored session, took us through how - now that there are so many Sitecore products to deal with at the same time - it's important to have good DevOps, PerfOps, and SecOps.  Naturally they wrapped with their plug: that they have the experience and tools to do this efficiently and effectively for any clients.

After lunch we needed to select from a couple of different tracks: developer or marketer. This first day I went full developer.


Vincent Lui
from CPA was up first with a session on "Abstracting Personalisation" where he described a bit about what CPA does and how it benefits its members. He went through a bunch of the tech that CPA uses to ensure that they collect as much data as they need to personalise for their users using a couple of different tools - CDP and EDP - and how these differ but complement each other.  Naturally given the PII being collected there are a great number of tools and processes that are in use to protect the data, as well as restrict how it's used.


Yevgen Spektor
then followed with a session on "Estimating the upgrade from monolith DXP to XM Cloud" which covered how XM Cloud / headless allows for better separation of concerns, faster builds and deploys, and takes load off Sitecore (ie no CD servers). Key considerations for the move include: serialization (eg. Sitecore content serialization) that most Sitecore modules no longer work, personalisation needs to be refactored, there are no longer custom Solr indexes, there will be little-to-no custom (.NET) code, you need to use Docker, and you'll probably use webhooks. The team structure will also be largely focused on the frontend devs, with little to no backend. Definitely some things to keep in mind there!

Next Navneet Pisharodi's session "Exploring a Modern Vercel Frontend for XM Cloud? An Architectural Viewpoint." took us through hosting a headless app in Vercel.  Not only are they the creators of Next.JS (which you're very likely to be using to build your Sitecore head) they are easy to use with many efficiency gains like gitops (also allowing for immutable deployments and instant rollbacks) and many easy integrations (logging to SumoLogic being the example provided). Not to forget, Vercel is a partner of Sitecore meaning that (fingers crossed) any new developments on both sides will quickly be integrated into the other party's product(s). Licensing and costs were the final key consideration called out - pretty much always the case, but in this particular scenario if you're not familiar with headless hosting it can be something which may catch you out, or be difficult to estimate.

To end the day, Gus once again took the stage to award the Ultimate Experience award to Destination Gold Coast and their partner PING for their excellent use of Sitecore.


Day 2 (Friday)

Sanchia Stafford-Gaffney and Troy Outtram from Deloitte kicked off day 2 by reminding us that we in the room are the fortunate few, and there are many people globally struggling in many different ways.  Deloitte has started a Digital Career Compass to help those struggling to find jobs in digital, mentored and trained by people like us and potentially going on to be employed by companies such as Sitecore (as well as a bunch more they also listed).  Not only do these candidates come from a vast array of backgrounds bringing with them a wide variety of experience but they are generally super driven and excellent employees.

Following this we then split back into Devloper and Marketer streams once more, where I attended:


"From Frustration to Success: Marketers' Guide to Sitecore XM Cloud Do's and Don'ts" by Raman Gupta and Vikas Kumar was an excellent walk through their learnings from experiences implementing XM Cloud. Not only a great list of "dos" and "don'ts" (especially for those of us who haven't yet had the chance to work on a full XM Cloud implementation) but they also treated us to an excellent demo of XM Cloud and the component builder.  If you'd like to download a copy of their list you can fill out the form on their website to get a free copy.


Rajesh Sure
then took us through a bit of a deep dive into webhooks in his session "Unlocking Seamless Connections: Leveraging Sitecore Webhooks for Enhanced Integrations".  Not only did he cover the various types of webhooks and how they are used (a couple of key considerations are: timeouts, and the fact that there is no retry logic), but he also had a great demo of a webhook triggering a message to Slack and email, for which he walked us through the code. Super useful stuff!


Andy Cohen
from the Sitecore product team followed up with a peek under the hood of some Sitecore tech (XM Cloud in particular) in his session "Building for Resiliency" where he explained how Sitecore uses event-driven architectures, liveness checks (with tools such as Apache Kafka and Azure App Configuration) to ensure that Sitecore can handle all sorts of "outage" scenarios. Not only that but he suggested a few books around event-driven architecture and domain-driven design that I'll need to take a look at some time!

vNext up I went to the session "Exploring Atomic Design with Storybook in Next.js for Sitecore Headless" presented in part by an old teammate of mine Arif Uzzaman, as well as his client Nikunj Sanghadia. In this breakout they took us through how frontend developers barely (if at all) need to know Sitecore, and can utilise atomic design to ensure consistent design between components, as well as Storybook to preview and showcase their output.  Not only that but it's easy to produce components which look great and play well in Sitecore.  As someone who uses Storybook extensively (but not atomic design at this time) this was quite familiar, and there were some great (and funny) questions from others in the room going through a similar journey.


Alistair Deneys
from the Sitecore product team, in his session "Exploring the Experience Edge GraphQL Schema", walked us through the different GraphQL schemas for XM/XM Cloud and ContentHub / ContentHub One and various ways these could be used for different technical requirements. Not only that but he presented it all on his custom-built .NET MAUI interface consuming content from ContentHub One. Super cool!
The final sessions included Arul Pushpam Murugan who gave an inspiring talk "Empowering Women in Tech: A Journey of Growth with Sitecore" where she took us through some of the hurdles she herself had to overcome, as well as tips for other women in the industry.


Sandy Drew then took us through the technical side of Toyota's XM Cloud build in his session "Driving hybrid success with Toyota Used Vehicles" which sounded like a great implementation, utilising Next.JS SSG and Discover.

Final Thoughts

Whether Sitecore's indeed at an "inflection point" (as Gus put it at the start) it has clearly matured even over the last year or so. It's clear that even though there are still a vast number of clients and partners nursing old Sitecore instances (many of which are no doubt out of support), there are also a really healthy number of companies who have not only made the leap to composible (or hybrid) but have completed implementations and come out unscathed, and ready to share their story.  Sitecore is listening and learning from those first implementations, and the "new" SaaS products are continually improving. At this point, if you're considering Sitecore's new products, you're not an "early adopter" or "trailblazer" you're just in good company.

It's great to come to community events like this where it's not all vendor-painted roses and sunshine - "our product is the greatest and can do everything".  Here you'll find real stories and talk to real people who can reassure you of the reality - that even though not 100% of what you want/need to do will be a walk in the park, it's all achievable when we share our knowledge, experience, and love of developing with Sitecore.

Tuesday, 14 November 2023

SUGCON ANZ!

Just booked my tickets to SUGCON ANZ!  Looking forward to seeing some familiar faces, and hopefully meeting some new people as well.  Many (if not all) of us are all introverted techies, but remember we're all there for the same reason; if nothing else try to say hi to the person sitting next to you :)

There's a great agenda - it's certainly going to be tough choosing between some of those afternoon sessions.  Don't forget that on the first day registration opens at 9am, but the real fun doesn't start until after midday. That should hopefully mean some reasonable flight times (and hopefully prices).

Hope to see you there!

Sunday, 8 October 2023

Security & Permissions with headless Sitecore

Security is a big headline these days (and should always be in the forefront of anyone's mind) and when it comes to content permission and user authorization the Sitecore "monolith" has always provided these capabilities out-of-the-box; however with the giant shift to headless over the last couple of years (or more) and now the move to SaaS these have grown vastly more complicated than the simple out-of-the-box content-permission-setting capabilities we used to know and love.

The issue

So why is it that things are now more complicated?
With the move to headless and composable, we have more of a separation of concerns - in this case, separation of the authentication/authorization, the display (/render) of content, and the provision of content.  This is most evident (technically, at least) in the use of REST and GraphQL by the headless code to retrieve content from the CMS (or DXP if you want to be fancy) where renderings were previously automatically provided their content by Sitecore.

The Sitecore "monolith" provides all 3 of these capabilities: 

  • Auth* through old ASP.NET users/roles, Federated Authentication, or Sitecore Identity 
    • Authenticates and assigns roles to user for authorization
  • Display/render of content through .NET MVC controller/view renderings (let's not talk about webforms or XSLT)
    • Authorizes user by checking permissions set on content in Sitecore XM
  • Provision of content through (amongst other things) datasources provided and consumed by the renderings 

In the new headless/composable world, these would be:

  • Auth though a separate identity provider (IDP) such as Okta / Auth0 / OneLogin / MS Entra
    • Authenticates and assigns roles to user for authorization
  • Display/render of content through headless SDKs such as Next.js (using REST / GraphQL)
  • Provision of content from Sitecore XM / Content Hub / Content Hub One

Notice something missing in the second list? Hopefully you did, as it's highlighted in bold in the first list!
There is now a disconnect between the roles assigned to the user by the IDP, and any roles you create in Sitecore / the permissions set on content.

This disconnect has no doubt been encountered by anyone working in a headless environment which requires their users to log in, and I have seen a few examples of how various people have thought about / tackled a solution. The following sections outline my approach.

A solution

There are 2 gaps mentioned above, and in case you missed them these are:
  1. A disconnect between roles assigned to a user by the IDP and roles in Sitecore (ie roles assigned to content)
  2. No out-of-the-box capabilities by the headless SDK to determine whether users are authorized to view content

You might be thinking "but both the GraphQL and REST endpoints support authorisation!". This was my initial thought, and I spent quite a bit of time deep diving into whether this was a viable option (ie. calling the layout service / GraphQL using the authenticated user details from the headless code). Let me save you a lot of time and headache: short of a quick and dirty option (simple logged in / not logged in user content, for example by swapping which API key you use to call the layout service) this isn't going to be an option you can use for anything serious.

I have seen other solutions which propose mapping the permissions (ie. roles <=> content) in a separate system, however my preference was to keep this within Sitecore. Sitecore XM still offers a flexible and robust ability to assign which content should be accessible by which users/roles, and building this again / finding a separate solution just seems like extra effort for no reason. I also personally do not feel like using this existing functionality goes against the spirit of composable at all. This mindset was the foundation for the remainder of the approach below.

I'm not going to dive too deeply in to the first point in the list above - suffice it to say there will need to be a way to ensure your roles in Sitecore match the roles assigned by your IDP. There are at least a couple of options:

  1. Configure role serialization, dynamically generate a yml file containing the roles, and dotnet sitecore ser push it
  2. Create an API endpoint on your Sitecore CM which calls System.Web.Security.Roles.CreateRole()

The meat of the dev work required, as far as I'm concerned, lies in exposing the roles and consuming them as part of authorization in the headless code.

Exposing the permissions

After setting the content (item) permissions (an out-of-the-box Sitecore XM exercise), the first thing that needs to be done is exposing these permissions. Content is consumed by the headless code either via the layout service, or GraphQL, so these are the 2 scenarios that need to be covered.

GraphQL: 

The quick and dirty way is to patch out the standard field filter, and add the security fields into your schema.
Note: this is not going to work if you're using Edge (/XM Cloud).

If you want a version which is compatible with Edge / XM Cloud, you'll want to create your own "faux security" field (you might call it "permissions"), and copy the standard (__Security) field value to this custom (permissions) field in a item:saved event handler. See this stackexchange answer for an example of a similar event handler.

Layout service: 

See sample repo

The layout service filters out all the standard fields (including __Security) in the FieldFilter method of JssItemSerializer (or whichever item serializer your site is using) so we will need to patch that out and add our own filter.
We then want to serialize our security field in a more readable format, which we can do in a custom SecurityFieldSerializer.

After this is done we can see all the __Security fields in our layout service result!

Authorization in Next.js

When it comes to Next.js, authentication really comes down to next-auth which has a host of IDP plugins out of the box (or you can develop your own easily enough if you really need / want to).  Authorization, however, is a custom exercise.  Long story short: once the SDK has called the layout service, the headless code needs to parse the permissions and prevent the user from seeing the page, or hide the appropriate content on the page from the user. 

Again, there are 2 parts to this: security at a page level (not authorized to view the page) or at a component level (hide a component from the user by removing it from the layout).

These can both be accomplished largely by customising normal-mode.ts (at least in Sitecore 10.2) with a helper to parse un-formatted security fields.

Page level (lines 68-74) and component-level (lines 77-80):

In the former we simply check the page security field, and in the latter we loop through all placeholders and check the security field set on the datasource.  This does not necessarily cover 100% of your use cases (components without datasources for example) but the rest can certainly be implemented in a similar fashion.

Conclusion

Securing certain content - to be shown only for authorized users - has been a site requirement for almost as long as the web has been around.  The advent of headless and/or composable mandates a new way of thinking and new approach to securing your site content.

With the logic provided above you should be able to both cover the vast majority of your permissions cases, as well as have a solid foundation for custom use cases where permissions might be needed within each of your components.

If you've made it this far - firstly thanks for reading! - I hope you learned something new today, or maybe re-enforced something you already knew. I'd love to get your feedback either way, so please leave a comment below, whether it's in agreement or some constructive criticism!