---
title: Creating AEM Service Users Using Sling Repo Initializer
description: We will cover how to create a Service User (SU) and grant privileges using Sling Repository Initializer (SRI) for AEM 6.5.4+ and AEM as a Cloud Service.
publish date: 2023-08-22
author: Jonathan Saurez
image: https://www-qa.oshyn.com/-/media/Oshyn/Insights/Blog/2003-08-Creating-AEM-Service-Users-Using-Sling-Repo-Initializer/blog_hero_aem-repo.jpg?rev=1c6b07ecbf294562b2f21bfbd9544fcd
url: http://www-qa.oshyn.com/blog/2023/08/aem-service-users-sling-repo-initializer
---
# Creating AEM Service Users Using Sling Repo Initializer

![AEM developer](https://www-qa.oshyn.com/-/media/Oshyn/Insights/Blog/2003-08-Creating-AEM-Service-Users-Using-Sling-Repo-Initializer/blog_hero_aem-repo.jpg?rev=1c6b07ecbf294562b2f21bfbd9544fcd&hash=912DF02E9E87C5A4E0D69D51577BC874)

In this article, we will cover how to create a Service User (SU) and grant privileges using Sling Repository Initializer (SRI).

AEM Version: AEM 6.5.4+ and AEM as a Cloud Service

## Concepts to Know

Sling Repository Initializer (SRI) factory allows you to run code before the SlingRepository service is registered, ensuring the ideal state and structure of the repository before its first usage/access.

It can create paths, users, groups, assign users to groups and provide privileges and restrictions. This option is recommended to create your users and groups from AEM 6.5.4+ and is compatible with AEM as a Cloud Service.

Service Users (SU) (aka System Users) are special JCR users that require no password to authenticate into the system. They expect to be assigned only the privileges required to perform a specific task, thus following the principle of least privilege. This option has been provided since AEM 6.0 for Back End services to get the corresponding permissions required to access the repository and AEM environment.

## Creating a Service User with Required Privileges.

There are two ways to create a SU:

1. From the CRX Explorer→ User Administration→ Create System User, enter the user name, then go to User Administration and assign the corresponding permissions to that new service user. This approach was the most popular for some time but there are a couple of drawbacks:
  1. It requires too much human interaction since administrators must create users at least once in every environment where the system is deployed.
  2. It is not compatible with Adobe as a Cloud Service.
2. Using Sling Repository Initializer factory, which allows you to run code before the SlingRepository service is registered, ensuring a certain state and structure of the repository (you can create paths, users, groups, assign users to groups, and provide privileges and restrictions) before using/accessing it.

If you used the AEM Project Archetype to create your project, by default, an OOTB RI file is generated with a basic initialization script. In our example (oshynDemo project), this file is named:


### Repo Init Config

```
org.apache.sling.jcr.repoinit.RepositoryInitializer~oshynDemo.cfg.json
```

and can be found at the root config directory at ui.config/src/main/content/jcr_root/apps/YOUR_SITE_PATH/osgiconfig/config/, in our case:


### Root Config Path

```
ui.config/src/main/content/jcr_root/apps/oshynDemo/osgiconfig/config/
```

as the Archetype deploys it by defect to all different RunModes. But you can place different RI files for the different RunModes in the system. This is the RI file auto-generated by the Archetype:


### OOTB Repository Initializer

```
{
    "scripts": [
        "create path (sling:OrderedFolder) /content/dam/oshynDemo",
        "create path (nt:unstructured) /content/dam/oshynDemo/jcr:content",
        "set properties on /content/dam/oshynDemo/jcr:content\n  set cq:conf{String} to /conf/oshynDemo\n  set jcr:title{String} to \"Oshyn Demo\"\nend"
    ]
}
```

Configuration names are suggested by Adobe to be created on .cfg.json file types but you can use .config files as well.

Unfortunately, .json files do not have good multiline support. However, a .config file does have it and configurations tend to be multiline at times.That's why we prefer to use a .config file and our Service User definition looks like this:


### org.apache.sling.jcr.repoinit.RepositoryInitializer-oshynDemo-service-users.config

```
scripts=["
    create service user oshynDemo-replication-service-user with forced path system/cq:services/oshyn-demo
    set principal ACL for oshynDemo-replication-service-user
    allow jcr:versionManagement,jcr:read,crx:replicate,rep:write,jcr:lockManagement on /content/oshynDemo
    allow jcr:versionManagement,jcr:read,crx:replicate,rep:write,jcr:lockManagement on /conf
    allow jcr:read on /apps
    end
"]
```

Please notice the differences between .cfg.json and .config notation. For example, in .config it is not required to wrap "scripts" definition into "{}" as has been done in .cfg.json files.

This is how it finally looks in the project structure.

![RepositoryInitializer factory example](https://www-qa.oshyn.com/-/media/Oshyn/Insights/Blog/2003-08-Creating-AEM-Service-Users-Using-Sling-Repo-Initializer/repositoryinitializer-factory-example.png?rev=f7b67c5ab87a495892e74db55b682b86?h=751&amp;w=1200)

## Important Details

- Notice the file name always starts with the OOTB class name (org.apache.sling.jcr.repoinit.RepositoryInitializer) and after that, the required custom name can be added (dash separated). Also, for separation between the OOTB class name and your custom file name suffix, Adobe uses a "tilde" symbol (~) , but you can also use a dash(-).
- Service Users MUST be created under system/cq:services to be compatible with AEMaaCS (AEMaaCS supports principal-based authorization by default only for all users below /home/users/system/cq:services). It is suggested to create a subfolder to group all possible Service Users required for the application (system/cq:services/oshyn-demo).
- CRITICAL: You can't have both files(.cfg.json and .config) in your project. You need to choose one way and use a single repo init factory file. (Do not deploy both files to your AEM server, as it may cause the repository to be in an inconsistent state next time the AEM instance starts. This gives a 503 error, leaving the site down and probably will require you to delete the repository and install a new AEM instance from scratch, losing any data not externally backed up).
- You should keep the initialization steps provided by the AEM Archetype. In such a case, you need to migrate the .cfg.json script to .config format. The following file shows the final result when completed:


### org.apache.sling.jcr.repoinit.RepositoryInitializer-oshynDemo-service-users.config

```
scripts=["
    create path (sling:OrderedFolder) /content/dam/oshynDemo
    create path (nt:unstructured) /content/dam/oshynDemo/jcr:content
    set properties on /content/dam/oshynDemo/jcr:content
        set cq:conf{String} to /conf/oshynDemo
        set jcr:title{String} to \"Oshyn Demo\"
    end

    create service user oshynDemo-replication-service-user with forced path system/cq:services/oshyn-demo
    set principal ACL for oshynDemo-replication-service-user
        allow jcr:versionManagement,jcr:read,crx:replicate,rep:write,jcr:lockManagement on /content/oshynDemo
        allow jcr:versionManagement,jcr:read,crx:replicate,rep:write,jcr:lockManagement on /conf
        allow jcr:read on /apps
    end
"]
```

At this point, we have a Service User readily available. However it cannot be used by any OSGi Component yet, it needs to be mapped to a Service Identifier first using a ServiceUserMapper Configuration Amendment (SUMCA) factory. We cover this topic in our blog: AEM User Mappings: Enforcing Cybersecurity Through the Principle of Least Privilege.

## Wrapping Up

Configuration files are the correct solution to define repository structure and systems behavior for situations like Service Users, general users, groups, permissions, repository structure, and configurations like the User Mappings. As these configurations are shipped within the code base and can be customized per environment, there's no need for manual processes. This approach removes the human error factor and allows your AEM environment to be set up for use from the first deployment iteration.
