XM Cloud tips & tricks: Extending CLI with handy productivity plugins and tools

Context and background

I presume most of us are familiar with Sitecore XM Cloud plugin that provides the cloud command that help you manage XM Cloud projects, environments and deployments from the Command Line Interface (CLI). CLI plugins provide us with powerful tools that enable us to automate management of Sitecore XM Cloud workloads by leveraging existing DevOps processes and tooling. In this blog post, I will share some of my tips and tricks on how you can quickly stand-up on of these plugins to automate, say, migration of content between two Sitecore XM Cloud instances.

Anatomy of a CLI plugin – Sitecore XM Cloud plugin example

A CLI plugin typically consists of a command which has one or more subcommands. Using an example of Sitecore XM Cloud plugin, you can check the cloud command is available as shown below:

I have assumed that you have already installed the required pre-requisites on your local developer environment. If this is not the case, help is available on how to do this setup, from the official Sitecore XM Cloud docs.

Subcommands

As you can see from above screenshot, we have the cloud subcommands for login, logout, project, environment, deployment and organization

I will not be focusing on what these mean for now. You can read more about them in the official docs pages. The point I am simply illustrating the anatomy of the CLI plugin, demonstrating what the command is and subcommands are. We will apply this to our own custom plugin next.

Tips & tricks 1 – Creating your own custom CLI Plugin – command and subcommands

I am going to share tips and tricks of creating a custom plugin to extend the base sitecore plugin with an new migrate command, which has only one subcommand to start the migration.

A typical use-case is imagine using this command to start content migration from Sitecore XM Cloud environment A into environment B. After we have created the plugin, we can run it with the dotnet sitecore --help command to display the plugin info as shown below.

Notice the migrate command is now listed alongside the out of the box subcommands that come with sitecore command. Very cool, we have now extended the sitecore command.

And we can now explore the available subcommands for our custom plugin using dotnet sitecore migrate --help command as shown below.

Tips & tricks 2 – Creating a Visual Studio Project for CLI Plugin

To extend the base Sitecore CLI plugin, we need to create a new class library project.

  1. In Visual Studio, select File > New > Project.
  2. In the Create a new project window, select C#Windows, and Library in the dropdown lists.
  3. In the resulting list of project templates, select Class Library (with the description, A project for creating a class library that targets .NET or .NET Standard), and then select Next.
  4. In the Configure your new project window, enter a name of your choice  for the Project name, and then select Next.
  5. In the Additional information window, select an appropriate Framework, and then select Create.

It is recommended we use the best practices such as have a clear project names to help clearly identify them and give a hint what the CLI plugin is all about. Below is a sample project skeleton, with all necessary classes needed for my CLI Plugin.

You will notice this project has the following structure. I will explain the main code classes below

  1. MigrateCommand.cs – this is the class code file that gives my plugin the migrate command
  2. StartMigrateCommand.cs – this is the class code file that adds my start subcommand to migrate command
  3. StartMigrateCommandArgs.cs – this is the code file that defines any command line arguments needed for the migration process. Below are the arguments supported
    • source-url: The URL of the source XM Cloud environment
    • destination-url: The URL of the target XM Cloud environment
    • root-item: The GUID of root item you want to migrate
    • include-children: Whether to include child items (default is true)
  4. PerformMigrateTask.cs – this is the code file that defines the tasks being accomplished by the subcommands
  5. RegisterExtension.cs – This is the main entry point code file, and implements the ISitecoreCliExtension

The rest of the code files are used for the business logic for this plugin. In my case, I have encapsulated my business logic for content migration from Sitecore XM Cloud environment A into environment B within the MigrationClient.cs code file. Consider this a black-box for now.

Which dependencies are needed for this project

We need to reference the Sitecore.DevEx.Client.Cli NuGet package from Sitecore, as shown below.

Verifying my project file (.csproj)

To ensure no errors with your CLI Plugin, you can verify your project file looks similar to the one shown below. Especially with Target Framework of netcoreapp3.1

Tips & tricks 3 – Configure NuGet package properties

We are going to deploy this project as a NuGet package. So follow the steps below to configure package properties

  1. Select your project in Solution Explorer, and then select Project > <project name> Properties, where <project name> is the name of your project.
  2. Expand the Package node, and then select General.
  3. Give your package a unique Package ID and fill out any other desired properties
  4. Below is my sample settings:

Tips & tricks 4 -Publishing your CLI Plugin to NuGet public feed

Now that we understand the high level anatomy of a CLI plugin and how to create its C#/.NET project, I will also share some tips on how to publish it to a public repository or feed. This is to make it available for the community to use the plugin.

Head over to Nuget.org and register for an account. You will need a Microsoft account to sign in or sign up. On successful login, select your user name at upper right, and then select API Keys as shown in step 1 and step 2 in screenshot below

Follow these steps once on the API Keys page

  1. Select Create, and provide a name for your key.
  2. Under Select Scopes, select Push.
  3. Under Select Packages > Glob Pattern, enter *.
  4. Select Create.
  5. Select Copy to copy the new key.

Important to note:

  • Always keep your API key a secret. The API key is like a password that allows anyone to manage packages on your behalf. Delete or regenerate your API key if it’s accidentally revealed.
  • Save your key in a secure location, because you can’t copy the key again later. If you return to the API key page, you need to regenerate the key to copy it. You can also remove the API key if you no longer want to push packages.

With our API-Key at hand, use the following command to publish your CLI Plugin. Notice we need to specify the name of our .nupkg file as well as API-Key when using the dotnet nuget push command.

When successful, you can view the list of your published packages using the ‘Manage Packages’ in step 3 on the previous screenshot. You should see the package listed such as shown below

For detailed guidance and further reference, follow the Microsoft Learn tutorial on NuGet packages.

Next steps

In this blog post, we have looked at tips and tricks on extending CLI for your XM Cloud instance. We looked at the CLI plugin architecture including how to create a sample .NET project for it. We also looked at how to package the CLI plugin and deploy to Nuget packages repository. I hope you find this useful and can adopt it for your own productivity use cases. Look out for a follow up blog post, where I will take a deep dive at some of the code I have used for my plugin. I intent to open up the black-box.

Stay tuned and please give us any feedback or comments.

How to plug your Content Hub data into your Observability platform and gain insights

Context

If you are already leveraging enterprise observability in your enterprise, this blog post is about how you can plug your Content Hub data to gain actionable insights. If you are not, then this blog post can help you start your journey towards embracing enterprise observability, plug your Content Hub data to gain insights.

In today’s complex IT landscape, enterprise observability goes beyond traditional monitoring by aggregating data from diverse sources to provide deep, actionable insights. Your Sitecore Content Hub platform is an upstream data source that you can plug in. You can push your Content Hub data such Assets, Projects, raw events and reporting logs—turning raw data into meaningful, proactive decision-making insights about your content supply chain. You can understand, for example, how your assets are being utilized, download footprints among more actionable insights.

Reference Architecture

I have shared a reference architecture at the top of this blog, which you can adopt for your use cases. Broadly you will need the following architectural components so you can push data from Content Hub into your observability platform and its visualization.

1. ETL Tooling

You will need tooling that will connect to your Content Hub instance to extract the data. Typically this tooling will provide capabilities to allow you to also transform and load the data to your target data lake. This process is known as Extract-Transform-and-Load(ETL).

Tooling such as Cribl and others are perfect for this. These tools and techniques perform an ETL (extraction, transformation, and loading) type functions on the raw data and shape it into a format suitable for analysis.

I will recommend working with Data Engineers with specialist skills in ETL to help with this process.

2. Data lake tooling

A data lake is commonly referred to as a data warehouse architecture, provides the capability to read and write data in a cloud object storage. This is the central repository where data from your various sources gets aggregated at scale.

Data will be extracted from Content Hub, transformed and loaded into a Snowflake database for example. This is where it all comes together. The data lake tooling will allow you to create a logical data model to help with analysis of your data. I will recommend working with Data Engineers with specialist skills in ETL and Data lake to help with this process.

3. Reporting UX tooling

You will need to turn your data into visuals. This architecture component is a user-friendly report-creation tool such as Microsoft Power BI

How to extract data from Content Hub

Content Hub provides a REST API for querying data held within your instance. All objects in Sitecore Content Hub are modeled as resources that represent the state of objects at the time of a request. Standard HTTP requests and responses are used to query and manipulate object states and standard HTTP headers are used to augment the request and response

All data is sent and received as JSON.

Authenticating and securing REST APIs

Access to the REST API is restricted to authenticated users. You can authenticate requests using these three options:

Tips and tricks: Query vs Scroll REST APIs

Querying API provides the most flexibility in terms of filtering data for specific entities using specific indexed metadata fields. This is a GET request type, and you access is such as shown below

GET http://<HOSTNAME>/api/entities/query/

For example, you can query all M.Asset entities by using the Definition.Name property as shown below

GET http://<hostname>/api/entities/query?query=Definition.Name=='M.Asset'

Due to deep paging restrictions, you can only retrieve up to 10,000 results. Any attempt to get more results results in an error message “Unable to execute search query. Status code:400” as shown below

Scroll API can be used to retrieve a large number of results (without the limitation seen in Querying API). Scroll only supports the GET method. The only difference with the Querying API is the paging arguments. This is also a GET request type, as shown below

GET http://<HOSTNAME>/api/entities/scroll/

This is the API I will recommend to be leveraged in scenarios when extracting all results from a single query from Content Hub into your Observability platform.

If you have concerns around data volumes and performance concerns for your Content Hub instance, reach out to your Sitecore Customer Technical Support for further guidance

Next steps

In this blog post, I have at a reference architecture that you can adopt to plug your Content Hub data into your Observability platform. I explained the various components of the architecture including some of the tooling you can leverage for your ETL and data warehousing and visualizations. I finished with strategies you can leverage to extract Content Hub data leveraging the Querying and Scroll APIs.

I hope my approach helps you address similar scenarios in your use-cases. Please let me know if you have any comments above and would like me to provide further or additional details.

Sitecore MVP 2025 announced

Julius Angwenyi Recognized as a Sitecore Most Valuable Professional

Honored for commitment to sharing expertise with the global Sitecore community

London, United Kingdom, January 30, 2025 – 360Agileweb.dev, today announced that Julius has been named a Sitecore Most Valuable Professional (MVP) Technology by Sitecore®, a global leader in digital experience software. Julius was one of only 241 MVPs worldwide selected this year.

The program recognizes professionals who actively share their knowledge and expertise with online and offline Sitecore communities to help them use Sitecore solutions and AI to create and deliver innovative digital experience solutions that drive business results.

MVPs represent and elite group in the Sitecore community of 16,000 certified developers and over 30,000 active community participants. MVPs are recognized for the quality, quantity, and impact of the contributions they made over the past year. A panel of Sitecore developers and executives honor the MVPs for the quality, quantity and impact of the contributions they made in 2024.  

“I am indeed honored to receive the MVP award and for the 4th time this year 2025. I would like to take this opportunity to congratulate my fellow MVPs on this achievement. I will also like to extend my sincere thanks to Sitecore community for recognizing my expertise and contributions. Cheers for the good work!”

“For nearly two decades, Sitecore has been honored to recognize the work of the experts who have distinguished themselves through continuous innovation and commitment to helping others build exceptional digital experiences,” said Roger Connolly, Chief Product Officer at Sitecore. “The MVPs are integral to the global Sitecore community and are looked to for their proven ability to build world-class solutions and dedication to sharing their knowledge.”

For more information, visit https://mvp.sitecore.com.

Content Hub DevOps: Resolving unable to delete entity because it’s being used in one or more policies errors

Context and background

Content Hub permissions and security model is underpinned by the user group policies model, whereby Content Hub users can perform actions based on their access rights. The official docs provides clear definition of the anatomy and architecture of the user group policies. For example, a user group policy consists of one or more rules, with each rule determining the conditions under which group members have permissions to do something.

While all the technical details of group policies are nicely abstracted away from our business users, there are use cases when you will need to in fact grapple with technical details of the policies. Such as when you can’t delete your taxonomies or entities, simply because you have used them in one or more rules in your policies.

In this blog post, I will outline this pain point and recommend a solution.

Unable to delete entity ‘…’ because it’s being used

Yes that is right. If you have used a taxonomy value or some other entity as part of your user group policy definition – then it makes sense you can not delete it. That is expected logic, we have a clear dependency within the system. In which case, we need to break or remove this dependency first.

Below is a sample screenshot of this error message. In this example, the highlighted taxonomy value can not be deleted yet, until the dependency has been removed.

User group policy serialization as JSON

If you haven’t set up DevOps as part of your Content Hub development workflow, then we need to cover some basics around user group policies serialization. You can leverage Content Hub Import/Export feature to export all polices into a ZIP package, as detailed below:

  1. Using the Manage page, navigate to Import/Export.
  2. On the Import/Export page, in the Export section, select only the Policies check box and click Export. This will generate a ZIP package with all policies.
  3. Click View downloads at the right bottom of the screen.
  4. On the Downloads page, click the Download Order icon when the status of the package is ready for download. This will download the ZIP package with all policies.
  5. Unzip the downloaded package. This will have JSON files of all policies

A look at M.Builtin.Readers.json for example

Below is a snippet from the M.Builtin.Readers.json, which a serialized version of the M.Builtin.Readers user group (one of the out-of-the-box user groups)

Remember a group policy consists of one or more rules, with each rule having one or more conditions under which group members have permissions to do something.

I have highlighted one of the conditions within the first rule in this user group policy. This condition shows the dependency on one of the taxonomies, M.Final.LifeCycle.Status

On line 20, the reference (“href”) indicates which taxonomy child value is being used, which is M.Final.LifeCycle.Status.Approved

The full content of this file are available from my GitHub Gist for your reference.

How to safely delete or remove taxonomy references from user group policy JSON file

The serialized user group policy JSON file is a plain text file. So any a text editor of choice can be used to edit this file, and delete all references to the taxonomy with a dependency. And then save the changes in updated JSON file. That is it.

Due care has to be taken to ensure that the rest of the JSON file is not modified.

Once all references are deleted and verified, you can create a new ZIP package with the changed files, to be imported back into Content Hub.

It is recommended your certified Content Hub developers should make these changes (and validate them, say, using a text file comparison tool such as Beyond Compare). For example, you need to compare the original ZIP package with the newly created one to make sure that their structure is the same.

Finally, the newly created ZIP package can be imported using the Import/Export functionality as detailed in official docs.

DevOps: Automating removing taxonomy or entities references from user group policies

I have previously blogged about enabling DevOps as part of your Content Hub development workflow.

The current pain point becomes a bread-and-butter problem to solve assuming you already embraced Content Hub DevOps.

With some business logic implemented as part of your CI/CD pipelines, all references to taxonomy values or entities can be safely and reliably deleted from user group polices. This can be done with automation scripts and other tooling that comes with DevOps, truly bringing you ROI in your DevOps infrastructure.

Sample/suggested CI/CD pseudo code

  1. Define a CI/CD “user group policies clean-up” step to be invoked whenever we are deleting “entities” from your Content Hub instance.
  2. Using a Regex, scan and systematically delete such entities from your user group policies JSON files (depending on how you’ve setup your DevOps, all policies should be serialized to policies folder)
  3. Ensure your “user group policies clean-up” step runs ahead of any deletion of the entities (or taxonomy values). Remember you can’t delete an entity if it is being referenced in your user group policy.
  4. Work with your DevOps engineers to validate the steps and test any changes in non-production environment(s), before applying to production environment.

Remember to also look at my related blog post on DevOps automation for your Action Scripts.

Next steps

In this blog post, I have discussed a common pain point when you are Unable to delete entity because it’s being used in one or more policies. I explained why this is the case, and looked into technical details of user group policy architecture. I provided a solution, which can be automated with a robust DevOps culture adoption for Content Hub.

I hope my approach helps you address similar scenarios in your use-cases. Please let me know if you have any comments above and would like me to provide further or additional details.

My Sitecore contributions in 2024

It is that time of the year once again, and the Sitecore MVP 2025 applications are open.

Below is a summary of my contributions for 2024:

Content contributions

This year I mostly created content within Content Hub, Sitecore Experience Edge and Sitecore Personalize space. This is where I felt there were gaps based on industrial client work I have done this year. I believe I have produced content that meets expectations in terms of quality, quantity, and visibility and more importantly, adds value to our community. This has been through blog posts, code sharing via GitHub, YouTube content, Product Feedback via Gartner Peer Reviews among other social channels:

Gartner Peer Reviews:

Sitecore Hackathon 2024:

Code and architectural artifacts:

In person events

I’m a regular attendee and an active member of Sitecore User Group London. Include a chance to attend the in person event post Symposium hosted by Sitecore in their London Paddington office.

Engagement

I have continued online and offline conversations and driven Sitecore community engagement throughout 2024 in order to amplify the content I have created.

Next steps

For 2025, I look forward keeping up producing more valuable content in terms of quality, quantity, and visibility to our Sitecore community. I will be putting myself forward for public speaking events throughout the calendar year. I intent to continue identifying any gaps and filling them, providing product feedback, improvements, and references

Stay tuned and best of luck with those submitting the Sitecore MVP 2025 applications.

Content Hub tips & tricks: Extending MRM project permissions to improve your ways of working

Background and context

Content Hub’s Marketing Resource Management (MRM) module provides a robust project management tool within the context of creation and development digital assets as part of the wider DAM solution. For example, you can capture project summaries and briefs, model your assets creative development process using stages, tasks or even jobs. Basically, you can use this tool to map to your ways of working, sharing responsibilities as you will do in a typical project. Only that MRM provides three default roles of Managers, Contributors and Readers which does what they say on the tin. But does this meet your needs?

In this blog post, I will share tips and tricks on how you can go a step further and enhance the default project roles so that you can have a more fine-grained control of permissions to meet the needs of your team members in your projects.

What you get with default Managers, Contributors and Readers project roles

In brief, project roles work like user groups. In a similar way that user group membership determines what you can access and the actions you can take so do project roles. The role you are assigned determines what you can access and the actions you can take for specific project.

  • Managers have overall visibility of the project, can create projects, edit project information, and manage all defined stages, tasks or jobs within the project
  • Contributors can make contributions to the project, such as add assets and fragments to projects.
  • Readers have read only access to assets and fragments in the project

Clearly these three broad definitions above will not always map exactly to your business use cases. For example, you may need your Readers to do more, such as download or preview some assets.

Stay tuned for details on how to get a detailed view of granular permissions available for each of these roles and tips you can use to enhance or extend them.

Can I modify or extend the default permissions for the project roles?

The good news is that these default project roles are not system-owned. These are simply role templates that you can extend yourself so that the permissions closely meet your business needs.

Below is a sample comparison of the default Readers (left-hand-side) and Contributors (right-hand-side)

For example, a Contributor role allows all permissions to M.Asset within Readers role plus the following additional permissions:

  • Create
  • AddVersion
  • DownloadOriginal
  • DownloadPreview 
  • Order
  • CreateAnnotations, among others

Likewise, there are different permissions for M.File for both roles, as shown above.

For the detailed list of all the available permissions and what they mean please visit the official documentation page.

Tip 1: Getting full list of all role templates

You can access the full list of all role templates in your Content Hub instance by accessing the URL below (assuming you have super user access). BASE_URL is your Content Hub instance base URL.

BASE_URL/en-us/admin/entitymgmt/entity/1471

also

BASE_URL/en-us//admin/entitymgmt/entities/50

And below is a sample list:

And below is the Details page for the Contributor role template, which you get by clicking on View detail link above.

Tip 2: Viewing and editing role template using entity management page

Warning: You have to take caution when making changes to the role templates. Ensure you are only making changes after consulting with business owners and assessed and agreed on required permission changes to be made.

  1. Follow Tip 1 above to find and select a role template, say Contributor
  2. Click on the Pencil or edit button shown below
  3. This will open the edit page, shown below
  4. You can copy the text and keep note of it before making any changes. You can repeat this step for all the default project role templates, so you can compare what is different between them, to further help you assess what you need to fine tune for your use cases.
  5. Make the required updates, ensure you are using the valid list of permission shared above
  6. Click Save to apply your changes
  7. Repeat step for all your role templates that need the updates.

Tip 3: Exporting role templates into Excel

Role templates are entities in your Content Hub instance, as such you can export them into Excel.

A typical use case is to export any changes made in a lower environment (say DEV) and apply them into another environment (say QA), by leveraging Excel import into target environment.

  1. You need to create a new subpage to used for the export purposes. From Manage -> Pages. Then identify which section you will be creating the new page. Then select “Add subpage” option. Refer to detailed steps available on the docs for further guidance.
  2. On your newly created subpage, add a Search component and a Selection component as shown below
  3. Configure the Search component so we can search and display Role templates. You can use the Filters tab as shown below, and choose the M.RoleTemplate definition. You can refer to detailed steps available on the docs for further guidance.
  4. Ensure your Selection component is linked with the Search component.
  5. Then Enable export to Excel option on the Selection component as shown below
  6. This is it, your subpage is ready.
  7. On you subpage, select all the role templates that you need to export, and select Export to excel

Next steps

In this blog post, we have looked at Content Hub’s Marketing Resource Management (MRM) module. We looked at the default project roles of Managers, Contributors and Readers and what they offer. I shared some tips and tricks on how you can extend the permissions for these roles to closely meet the needs of your project management use cases. I hope you find this useful for your similar use cases.

Stay tuned and please give us any feedback or comments.

Content Hub tips & tricks: How to securely share your DAM assets with external users by leveraging collections – part 2

Background

On the previous post, I looked at how to securely share your DAM assets externally by leveraging collections. Among other things, we covered four options you can use to secure the asset collections. One of the options involved defining a permissions policies on M.Asset (model for your assets) based on M.Collection (model for your asset collections). However, this option seems to come with some nuances and will not work by default. I will carry on the conversation to demonstrate how to make this option to work.

Why doesn’t the policy definition work?

In simple terms, the above policy states that we would like to allow all assets belonging to our collection named “External” to be downloadable. Simple. But it doesn’t work.

But why?

This is because the “Inherits security” setting for the CollectionToAsset relation is turned off by default. In other words, this means security related metadata (from the parents towards the children) can not be inherited while this setting is turned off.

M.Asset is a child of M.Collection (as shown below in the schema details for M.Asset definition). To access M.Asset schema page, click on Manage -> Schema -> then search for M.Asset

How do I turn on “Inherits security” for the CollectionToAsset relation?

Short answer is you can’t modify this by yourself. You will need support from Sitecore Technical Support to make this change for you. Please note CollectionToAsset is a system relation and is locked down to Super users as well.

You can raise Sitecore Support Cases using the Support portal and request the team to enable the “Inherits security” on CollectionToAsset on your environments. This should be actioned swiftly after which your policy definitions can start to work as expected.

Next steps

In this blog post, we have looked at how to make user group permissions policies on M.Asset based on M.Collection work. We looked at nuances that make this not to work by default and how to resolve and get it working. I hope you find this useful for your similar use cases.

Stay tuned and please give us any feedback or comments.

Content Hub tips & tricks: How to securely share your DAM assets with external users by leveraging collections – part 1

Background

One of the great values you get with your investments in Sitecore Content Hub platform is the collaboration capabilities with your external partners and users in your content supply chains. Siecore Content Hub provides out-of-the box the Asset Collections capability, which enables you to group your assets. Which seamlessly allows collaboration on that asset collection through comments, for example.

However, there is a catch.

When you create an asset collection and want a fine grained control on whether these assets should be downloadable, this doesn’t always seem to work as expected.

For example, you have a collection named “External” with only “Asset test 1” and “Asset test 2” included. And you need these two assets to be downloadable. However, when this collection is shared, there are scenarios when other additional assets will seem to appear within External collection, instead of just “Asset test 1” and “Asset test 2” as expected.

In this blog post, I will be sharing some top tips and tricks on how you can be in control of this process, ensuring you only share assets that need to be shared, securely.

How do I create an asset collection

The existing official docs provide step-by-step guidance on how to create asset collections. I will repeat the main steps below, for the sake of to keeping the flow in this blog post.

To create an asset collection:

  1. On the menu bar, click Collections.
  2. In the top-right corner of the Collections page, click + Collection.
  3. In the Collection dialog, populate the details of the collection you are creating
  4. Click Save.

How do I add assets to my asset collection

Again, the existing official docs provide robust step-by-step guide on how to add asset to a collection. Please note that it is best practice to add existing assets to your collection – which are at the correct stage of your content lifecycle. Avoid uploading new assets directly at this stage.

How do I share my asset collection

You can share the collection by following the following three main steps:

  1. On the collection details page, click Share link share link icon.
  2. In the Share link dialog, turn on the Create external link switch. This will then generate for you a link
  3. To share the link via email, use the Click Email email icon button, which should prompt for emailing details. You can alternatively use the Copy link button to copy the URL and share it as well

Tips and tricks on securing you asset collections

Now that we have covered the basics on how to create an asset collection and share it, I will focus on top tips and tricks of ensuring we are sharing the collection using best practices and for the correct external collaborators.

Top tip 1 – Leverage user groups to manage external collaborators

User groups underpins the permissions model within Content Hub. Members of a user group are granted permissions and privileges according to the user group policies assigned to that group. By managing permissions and privileges using groups, you can streamline how they are assigned.

  • Read-only external collaborators – Define a separate user group for your external collaborators who need a read-only access. These are not expected to make any contributions, but may be to give them a status update of your assets.
  • Contributor external collaborators – Define a separate user group for your external collaborators who you would like to give you comments and feedback on shared assets.
  • Download external collaborators – Define a separate user group for your external collaborators who you would like download your shared assets. The use case is when you would like them them to use download the shared assets for allowed activities such are offline brands channels.
  • Add external collaborators to a user group – Always add external collaborators as users in your Content Hub instance, then assign them one of the above user groupings. Sitecore Content Hub allows users belonging to an external domains to be added using Users Manager (and they can sign in with their username and passwords) Depending on your security policies and governance, it is possible to also leverage Single sign on with External domains. If you need guidance, reach out to your Security and Identity team or Sitecore Technical support.

Top tip 2 – Leverage user group policies to lock down UX and pages

You need to make a decision which pages your external collaborators can view. For example, should they access your Asset details page, which will potentially give them access to additional meta data?

If you have followed Top tip 1 above, all you need to do is define user group policies for each relevant user groups.

Below is an example of how you can give access to allow viewing Asset details page(s) such as Asset details or Video asset details page as shown below.

Top tip 3 – Additional policies – downloadable assets based on a taxonomy value

You recall the scenario I described at the start of the blog. You have a collection named “External” with only “Asset test 1” and “Asset test 2” included. How will you go about ensuring only these two assets are downloadable?

  1. Define taxonomy, use this to tag and identify external assets:
    • This option requires you to define some form of Taxonomy, say, ExternalAsset which entities Yes or No. For all externally shareable assets, you will need to tag them with value of Yes. You can then leverage this Taxonomy within your User Group policies definitions to narrow down which assets can be downloadable. As an example, this policy below shows how I can narrow which asset is downloadable based on M.AssetType value of Video
  2. This clearly works. However, with this option you will need to ensure all assets are tagged accordingly before sharing them externally. This could add more work to your content workflows.

Top tip 4 – Additional policies – downloadable assets based on current asset collection

You could be asking, why can’t I apply the additional policy for downloadable assets based on the current asset collection? Good question.

If you try this approach, your User group policy will look like this instead.

This is perfectly fine. You could have thought this will work, right?

This option does not work. It seems you can not define a policy on M.Asset (model for your assets) based on M.Collection (model for your asset collections) by default.

While grappling with this issue, I reached out to Sitecore Technical support for guidance. Good news is we have a technical solution for this specific problem. Stay tuned on my next blog post when I will cover how you can make a group policy definition policy on M.Asset based on M.Collection such as in the screenshot above work.

Next steps

In this blog post, we have looked at Content Hub asset collections a great feature for collaboration capabilities with your external users during your digital assets lifecycle. We have looked at some of the top tips you can leverage to secure your collections when sharing them with your external collaborators. I hope you find this useful for your similar use cases.

On the follow up blog post, I will look into details how to resolve the specific problem identified above. Please give us any feedback or comments.

Content Hub DevOps: Managing your action script code lifecycle in CI/CD pipelines

Context and background

When working with automated CI/CD pipelines with you Sitecore Content Hub, you need to be aware of the development lifecycle for your Action Scripts. This is to ensure your source code repo for your scripts doesn’t get ‘bloated with orphaned‘ script code files. In this blog post, I will cover how to manage the development lifecycle of your Action Scripts to mitigate against this problem.

What happens when you serialize action scripts into source control

I have previously blogged on Content Hub DevOps, especially on leveraging Content Hub CLI to extract a baseline of your Content Hub components. For example ch-cli system export --type Scripts --wait --order-id command allows you to export Actions, Scripts and Triggers package. When you unzip or extract the files within this package, you will notice there is a scripts folder. This will have two types of files: .json files and .csx files (assuming your actions scripts are written in C#.NET)

Script .json file type

For each action script packaged from your Sitecore Content Hub instance, it will have two files. One of them is the script .json file.
Below is a sample action script json file:

This file contains all the relevant meta-data about the action script. In particular, you will notice that it is referencing a second file using the ScriptToActiveScriptContent relations property. Using our sample above, this json file is referencing this code file “ZOGG4GbbQpyGlTYM7r1GfA

Script .csx code file

The code file based on C#.NET, is similar to the sample shown below.

What happens when you modify the code in your scripts

Each time you make changes to your Action Script source code and successfully build it, Content Hub will generate a new code file version behind the scenes. This will be automatically linked to its corresponding script .json file.

To visualise this, you will notice that when you serialise your Action Script again from your Content Hub instance, a new code file will be generated.

If you now compare the previous code file with the new one, it will become obvious which changes Content Hub has made to the .json file. Below is a sample comparison.

What should you do with the ‘old’ code file

We have now established what is going on whenever the source code in your action script is changed and successfully rebuilt. Each time, a new file will be generated. The old file will remain in your source code repository, unused and effectively ‘orphaned’.

My recommendation is to design your DevOps process that will always clean-up or delete all files from your scripts folder in your source code, before pulling the latest serialised files from your Content Hub instance.

You can do this in an automated way leveraging the Content Hub CLI commands. Alternatively, you can do it old school way leveraging PowerShell commands to delete all files from scripts folder before serializing new ones again. Whichever mechanism you leverage, ensure old and used code files do not bloat your source code repo.

Next steps

In this blog post, I have discussed what happens when you make code changes to your action scripts. I explained why you will have ‘old’ or ‘orphaned’ code files within your script folder that will bloat your source code repo. I also covered steps you can take to mitigate this problem.

I hope my approach helps you address similar scenarios in your use-cases. Please let me know if you have any comments above and would like me to provide further or additional details.

Content Hub tips & tricks: Overriding Created by or Modify by ‘ScriptUser’ in your scripts

Background

If you currently leveraging Action scripts as part of your Content Hub solution, you probably noticed that any updates done to your entities are tagged as Created by or Modified by ‘Scriptuser’. You may as well not be aware that actually this is how the Content Hub platform works by design. At present, all scripts operate under the Scriptuser account

But how do I override the ‘Scriptuser’ account?

Frustratingly, there isn’t much documentation around this ‘Scriptuser’ on the official docs. You are not alone in this. That is why I have put together this blog post to help provide a solution to this problem.

It is not all doom and gloom. In fact, if you look around in Sitecore docs, the IMClient provides a capability to impersonate a user, using the the ImpersonateAsync method.

Below is a definition from Sitecore docs:

ImpersonateAsync(string)

Creates a new IMClient that acts on behalf of the user with the specified username. The current logger will be copied to the new client.

So we will need a function to get an impersonated MClient

Looks like we have a solution then. All we need to do now is define function within our Action Script, that will create an instance of an impersonated MClient. This impersonated client will in effect allow us to override the Scriptuser with the current user triggering our Action Script. Which is the solution to our current problem.

Good news, I have already defined such a function for you. I have named this function GetImpersonatedClientAsync, a shown below.

You should be familiar on how to load an entity property, by leveraging the PropertyLoadOption in your EntityLoadConfiguration, as shown above. That is how I am able to retrieve the Username property from the current user entity (currently authenticated user within Content Hub). This will be the user that has triggered our Action Script.

It is need as a parameter when calling the MClient.ImpersonateAsync as shown on line 35 above.

I have left the details of how triggering of an Action script happens, since I have covered this topic in my previous blog posts, such as this one.

However, I would like to call out that the UserId of the authenticated user is always available within the Action Script via accessing the Context object. Below is a snippet of how I have done this on line 10.

Saving changes with Impersonated MClient

We now need to use the impersonated MClient in all instances where we are saving changes in our Action Script. Below is a code snippet on how to achieve this. You can see on line 15, I am using the impersonated userClient. You can easily compare this with line 20, which is a fallback option that uses default MClient.

You can view the full source code of the above script from my public GitHub Gist.

Next steps

In this blog post, we have looked at a how to override the Scriptuser within an action script. I have walked you through a sample action script and also shared sample source code for your reference. I hope you find this useful for your similar use cases.

Stay tuned and leave please us any feedback or comments.