---
title: Configure Shell modules
slug: cms-11/dev-docs/configuring-shell-modules
docTags: 
createdAt: 2026-07-22T19:45:22.664Z
---

There are two different kinds of shell modules: protected and public. Protected ones are secured by default, while public ones are accessible to all users.

You can add modules to Optimizely Content Management System (CMS) by configuring the options for automatic discovery or by explicitly adding them by configuring the corresponding option through code or `appSettings.json` file.

Example of configuration from `appSettings.json`:

```json
"EPiServer": {
  "CmsUI": {
    "ProtectedModule": {
      "Items": [{
        "Name": "MySecureModule"
      }]
    }
  }
}
```

Example of configuration from code:

```csharp
services.Configure<ProtectedModuleOptions>(o => o.Items.Add(new ModuleDetails { Name = "MySecureApp" }));
```

Install public modules in the `modules` folder; install protected modules in the `modules\_protected` folder. Treat the web application as a "default" shell module but with path `.\` (the application root). To add settings for the "default" shell module, add a [module.config](https://world.optimizely.com/documentation/developer-guides/CMS/configuration/Configuring-moduleconfig/)  to the root of the application.

## Options configuration

You can configure a module through options like resource paths and assemblies. However, you should have a corresponding [module.config](docId\:RZVSXXKVRj26ep5OsAUB-) for a shell module.

### Module manifest

Each module can have a manifest file (`module.config`) in the module's root directory, where you can specify further module-specific settings.

### Security

A shell module can specify which security policy you should apply to requests for the module by assigning the attribute `authorizationPolicy` in `module.config` with the name of the policy to apply. If the module does not explicitly specify a policy, is by default no policy applied to public modules, while a policy named `episerver:defaultshellmodule` (requires the user to be in any of roles defined in `CmsPolicyOptions.DefaultShellModuleRoles` which by default is WebEditors, WebAdmins, CmsAdmins, and Administrators) is applied to protected modules.

Example of assigned policy `episerver:cmsedit` for the module through `module.config`:

```xml
<?xml version="1.0" encoding="utf-8" ?>
<module authorizationPolicy="episerver:cmsedit">
  <assemblies>
    <add assembly="MyModuleAssembly" />
  </assemblies>
</module>
```

### Discovery

`ProtectedModuleOptions` and `PublicModuleOptions` have a property `AutoDiscovery` that can be configured to specify how you should perform module discovery. By default, it is `PublicModuleOptions.AutoDiscovery` set to `AutoDiscovery.Modules` meaning it scans the `modules` folder for modules, which will then be automatically registered. The default for `ProtecedModuleOptions.AutoDiscovery` is set to `AutoDsicovery.Minimal` meaning all protected modules need to be explicitly registered. The CMS built-in modules like edit and admin mode are registered when `AddCms` is called.

## Version client resources

You can specify the relative path to client resources in the module folder using the optional `clientResourceRelativePath` attribute of the module node in the module manifest file, [module.config](docId\:dI64jrVOXLd4rWo8gsedO). The module client resource path is equal to the resource base path when `clientResourceRelativePath` attribute is not defined, or the value is an empty string. Otherwise, the system combines the module resource base path and the relative path specified in `clientResourceRelativePath` attribute. The resulting value is used as the module client resource path if it is a valid absolute path.

You can implement versioning to avoid client-side caching issues without individually changing all resource file references.

**Example module directory structure**

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/R5ndpQe2oNL_PWTo19jgq-20260722-194638.png "clientresourcerelativepath.png")

**Example module.config**

```xml
<?xml version="1.0" encoding="utf-8"?>
<module clientResourceRelativePath="1.5.0" >
  <!-- ... -->
  <clientResources>
    <add location="myScript" path="ClientResources/script.js" resourceType="Script" />
    <add location="myStyles" path="ClientResources/styles.css" resourceType="Style" />
  </clientResources>
 <!-- ... -->
</module>
```

- Resource base path: `~/modules/SampleModule/`
- Client resource path: `~/modules/SampleModule/1.5.0/`
