Hardcoding values inside a plugin — a threshold number, a URL, a password — means recompiling and redeploying the assembly every time one of them changes. Dataverse avoids that by giving every registered plugin step two optional text boxes, filled in once at registration time, that your code reads back at startup: unsecure configuration and secure configuration.
- Both fields are set when you register (or later edit) a plugin step
- Both arrive as plain strings in the plugin's constructor, not the
Executemethod - Unsecure configuration is visible to anyone who can open the step's registration details
- Secure configuration is hidden from users without System Administrator or System Customizer privileges
A public bulletin board and a locked drawer
Unsecure configuration is like a notice pinned to a public bulletin board — anyone walking past the registration screen can read it, so nothing sensitive belongs there. Secure configuration is like a locked drawer that only staff with the right key can open — the value still exists and the plugin can still use it, but casual visitors to the office never see what's inside.
How the values reach your code
Both configuration strings are handed to the plugin class through its constructor, which the platform calls once when it creates an instance of your plugin — not once per record, and not inside Execute. That single read matters: it means configuration values are fixed at construction time for that instance, so a plugin isn't re-reading its settings on every run.
public class MyPlugin : IPlugin
{
private readonly string _unsecureConfig;
private readonly string _secureConfig;
public MyPlugin(string unsecureConfig, string secureConfig)
{
_unsecureConfig = unsecureConfig;
_secureConfig = secureConfig;
}
public void Execute(IServiceProvider serviceProvider)
{
// use _unsecureConfig / _secureConfig here
}
}
For a single value, a plain string is enough. When a plugin needs several settings at once — a URL, a timeout, a flag — developers commonly format the unsecure configuration string as a small block of XML and parse it in the constructor, rather than registering a dozen separate plugin steps just to pass a dozen separate values.
Choosing where a value goes
The rule of thumb is simple: if a value being visible to any admin-level user in the registration screen would be a problem, it belongs in secure configuration. If it's just a harmless constant that happens to be configurable, unsecure is fine and keeps things simple.
| Field | Visibility | Typical use | Example |
|---|---|---|---|
| Unsecure configuration | Anyone who can open the step registration | Non-sensitive constants and flags | A discount threshold, an "enabled" flag, a default region code |
| Secure configuration | Only System Administrator / System Customizer roles | Credentials and sensitive endpoints | An API key, a service account password, an internal service URL |
A couple of practical notes worth keeping in mind:
- Secure configuration isn't a substitute for a proper secrets vault in every environment, but for most plugin scenarios it's a meaningful and appropriate improvement over hardcoding or leaving credentials in plain sight.
- Both fields are optional — plenty of plugins need neither, and it's fine to leave them blank rather than invent a setting for its own sake.
- If a value changes later, editing the step's configuration doesn't require recompiling the plugin — only re-saving the registration.