Managed properties are Dataverse's mechanism for declaring exactly what downstream consumers can modify after your managed solution is installed — and most ISVs configure them wrong. This expert-level lesson covers the full component taxonomy, XML-level configuration, solution layering interactions, and a practical boundary strategy for building platform-grade solutions.

Imagine you've spent six months building a sophisticated Dataverse solution for a healthcare client. You've carefully designed a data model with precisely controlled field behaviors, security roles calibrated to HIPAA requirements, forms engineered to enforce data quality at every interaction, and business rules that encode clinical logic that took weeks to validate with domain experts. You package everything up, deploy it to the client's production environment as a managed solution — and three weeks later you get a support ticket: the forms aren't working correctly because the client's internal IT team "improved" them by adding fields, removing required constraints, and rearranging sections. Your carefully validated clinical logic is now broken, and you're on the hook.
This is the exact problem that managed properties exist to solve. Managed properties are Dataverse's mechanism for ISVs, platform architects, and solution owners to declare, at the component level, exactly what downstream consumers are allowed to customize after your managed solution is installed. Done right, managed properties let you ship solutions that are simultaneously extensible where you want them to be and locked where they need to be. Done wrong — or not done at all — you get the healthcare scenario above.
By the end of this lesson, you'll understand how managed properties work at a structural level, know which component types support which locking settings, be able to configure them through both the UI and direct XML manipulation, understand how solution layering interacts with your locks, and be equipped to design an ISV-grade solution boundary strategy that survives real-world customer environments.
What you'll learn:
You need genuine working experience with:
Before diving into configuration, let's make sure we have a precise mental model of what managed properties are and what they're not.
Managed properties are metadata attributes stored on solution components that control whether those components can be modified after they arrive in a target environment as part of a managed solution. They do nothing in development environments — in an unmanaged context, every component is always fully editable. Managed properties only take effect when a component transitions into a managed state, meaning when it's exported as part of a managed solution and then imported into another environment.
Here's the crucial structural point: managed property settings are stored in the solution's customizations.xml file, attached to individual component definitions. When you import a managed solution, Dataverse reads these settings and registers them as constraints on those components for that environment. The constraints are enforced by the platform itself — they're not security-role based, they're not environment-variable based, they apply to everyone in the target environment including system administrators.
Key insight
System administrators cannot override managed property locks through any UI mechanism. The only way to modify a component that a managed property has locked is to update the managed solution from the source publisher and reimport it, or to uninstall the managed solution entirely (which deletes all managed components). This is exactly the control ISVs and enterprise architects need — but it's also a significant commitment you need to make deliberately.
This has a critical implication for your design process: managed properties are not something you configure "at the end." Once you ship a managed solution with certain components locked, you can't unlock them without shipping an update. Plan your solution boundary strategy before your first production deployment.
Not every solution component type supports the same set of managed property flags. Understanding the taxonomy is essential — applying the wrong lock strategy because you misunderstood which flags apply to which component type is one of the most common expert-level mistakes.
Tables have the richest set of managed property options, because tables are themselves containers for other components. The primary table-level managed properties are:
Allow customizations — This is the master switch. When set to false, it overrides all other table managed properties and makes the entire table component unmodifiable in the target environment. No new columns can be added to the table, no relationships can be modified, no forms or views on the table can be changed, nothing. Use this only for tables that are purely infrastructural and should never be touched by downstream parties.
Allow new forms — Controls whether consumers can create new forms on this table. Note the distinction: this controls creation of new forms, not modification of existing forms (that's controlled at the individual form level). This is useful when you want to permit consumers to build their own forms for their custom use cases while keeping your canonical forms locked.
Allow new views — Same pattern as forms: controls whether new views can be created on the table, not whether existing views can be edited.
Allow new charts — Controls chart creation on the table.
Allow new relationships — Controls whether consumers can add new relationships (lookups, one-to-many, many-to-many) to the table. This is a significant setting. If you lock this, consumers can't extend your table by creating relationships to their own custom tables — which may be exactly what you want for integrity, or exactly what you don't want for extensibility.
Allow security roles to be updated — Controls whether the security role configuration for this table can be modified. In practice, this rarely needs to be locked at the table level because security role definitions themselves have their own managed properties.
Individual columns support a single primary managed property flag:
Allow customizations — When set to false on a column, the column's definition becomes read-only in the target environment. Consumers cannot change the display name, the data type (not that they normally could), the required level, the maximum length, the description, or any other attribute of the column. The column exists and can hold data, but its metadata is frozen.
Warning
Locking column customizations does not prevent data from being written to that column by users who have appropriate security role privileges. Managed properties control metadata (schema changes), not data (record operations). If you want to prevent users from editing data in a field, you need field security profiles or form-level locking — covered in Column-Level Security and Record Sharing in Dataverse.
There are also some column-type-specific properties worth knowing. For option set (choice) columns, you can additionally lock whether new options can be added to the option set. This is particularly important for global choice columns shared across multiple tables — we'll cover this in the global choices section below.
Relationships have a single managed property: Allow customizations. When locked, the relationship definition cannot be modified — the cascade behaviors, the relationship type, the lookup column properties. This is important for ISVs whose business logic depends on specific cascade behaviors (for example, a solution that relies on parent-child cascade delete to maintain data integrity).
Forms have a single managed property: Allow customizations. When this is set to false, the form layout cannot be modified — no sections can be added or removed, no fields can be rearranged, no tabs can be added, no properties can be changed. The form is immutable in the target environment.
This is one of the highest-value managed property settings for ISVs. If your form encodes validated UX patterns, clinical workflows, compliance data entry sequences, or multi-step processes (via embedded Business Process Flows: Guiding Users Through Multi-Stage Processes in Power Apps), locking the form ensures that what you tested and validated is what runs in production.
Views also support a single Allow customizations property. Locked views cannot have their filter criteria, sort orders, columns, or column widths changed. Given how much business logic can be encoded in a view's filter criteria — particularly for system views used as lookup filters or quick find views — this is worth doing deliberately.
Security roles support Allow customizations. A locked security role cannot have its privilege levels modified by anyone in the target environment. This is a powerful setting that enterprise architects often overlook. If your solution ships a "Solution Auditor" role that grants read-only access to a specific set of tables, locking it ensures that the role stays read-only. Without this lock, a local admin can quietly escalate the role's privileges and undermine your security model.
Tip
Even if you lock the security roles you ship, consumers can always copy a role and modify the copy. Managed property locking prevents modification of the specific component instance you shipped — it can't prevent someone from duplicating it. Factor this into your security architecture rather than treating locked roles as a complete security boundary.
Global choice columns (formerly called global option sets) support two managed property flags:
Allow customizations — Locks the existing option values, their labels, their sort orders, and all metadata.
Allow adding new options — This is a nuanced setting that deserves careful thought. When you set Allow customizations to false but Allow adding new options to true, you get a middle ground: consumers can add new choices to the list but cannot modify or delete your existing choices. This is often the right posture for taxonomy-style fields where you define a core set of values that must exist for your logic to work, but you want to allow extensibility for customer-specific classifications.
Business rules support Allow customizations. A locked business rule cannot be deactivated, modified, or deleted by downstream consumers. This is important to understand: a locked business rule is permanently active from the consumer's perspective. If you ship a business rule that enforces a required field condition and lock it, users cannot work around it by disabling the rule.
Given how Dataverse business rules work at the form and server scope levels, locking a server-scoped business rule means that validation runs on every record write operation regardless of form. This can be very powerful or very frustrating depending on your intent.
These support Allow customizations. Locked dashboards and charts cannot be edited. For solutions that deliver operational dashboards as part of their value proposition, locking these ensures the analytics experience remains consistent.
The most accessible way to configure managed properties is through the Power Apps maker portal solution editor. The workflow is consistent across component types, so we'll walk through it in detail for a table and its components.
Accessing a table's managed properties:
The panel for a table will show toggles for: Allow customizations, Allow new forms, Allow new views, Allow new charts, and Allow new relationships. Each toggle is On (customizable) by default. Set them to Off to lock.
Accessing column managed properties:
Accessing form managed properties:
The pattern is identical for views, charts, business rules, and other component types that live under tables. For top-level components like security roles and global choices, navigate to them directly in the solution's object list and use the same managed properties command.
Note
Managed properties you configure in the UI are only persisted to the solution's customizations.xml at the time you save and export. If you make changes and don't export, the settings are stored in the environment's development metadata but won't be reflected in the export until you explicitly export. Always verify by examining the exported XML before considering a managed properties configuration "done."
For bulk operations, automated pipelines, or scenarios where you need fine-grained control that the UI doesn't expose well, working directly in the customizations.xml is the right approach.
When you export an unmanaged solution as a zip file and extract it, you'll find customizations.xml in the root. This is a large XML document that serializes all solution components. Managed property settings appear as child elements or attributes within component definitions.
Here's what a table definition looks like with managed properties configured:
<Entity>
<Name LocalizedName="ContosoClinicalVisit" OriginalName="contoso_clinicalvisit">
contoso_clinicalvisit
</Name>
<EntityInfo>
<entity Name="contoso_clinicalvisit">
<!-- ... other entity metadata ... -->
<IsCustomizable>1</IsCustomizable>
<CanCreateForms>1</CanCreateForms>
<CanCreateViews>1</CanCreateViews>
<CanCreateCharts>1</CanCreateCharts>
<CanCreateAttributes>1</CanCreateAttributes>
<CanBeRelatedEntityInRelationship>1</CanBeRelatedEntityInRelationship>
<CanBePrimaryEntityInRelationship>1</CanBePrimaryEntityInRelationship>
<CanBeInManyToMany>1</CanBeInManyToMany>
<CanEnableSyncToExternalSearchIndex>1</CanEnableSyncToExternalSearchIndex>
<IsActivity>0</IsActivity>
</entity>
</EntityInfo>
</Entity>
Each 1 represents "allowed/true" and 0 represents "locked/false." To lock the table against new forms and new relationships while keeping it otherwise customizable:
<IsCustomizable>1</IsCustomizable>
<CanCreateForms>0</CanCreateForms>
<CanCreateViews>1</CanCreateViews>
<CanCreateCharts>1</CanCreateCharts>
<CanCreateAttributes>0</CanCreateAttributes>
<CanBeRelatedEntityInRelationship>0</CanBeRelatedEntityInRelationship>
<CanBePrimaryEntityInRelationship>0</CanBePrimaryEntityInRelationship>
<CanBeInManyToMany>0</CanBeInManyToMany>
For a column:
<attribute PhysicalName="contoso_diagnosiscode">
<Type>string</Type>
<Name>contoso_diagnosiscode</Name>
<!-- ... other attribute metadata ... -->
<IsCustomizable>0</IsCustomizable>
</attribute>
For a form, the managed property is embedded in the form's FormXml:
<systemform>
<formid>{a4b2c1d3-...}</formid>
<IsCustomizable>0</IsCustomizable>
<type>2</type>
<!-- ... form definition ... -->
</systemform>
Warning
Directly editing customizations.xml is powerful but unforgiving. A malformed XML file will cause the solution import to fail entirely. Always validate your XML against the schema before importing, and always test in a sandbox environment before touching production. Maintain source control on your solution XML files — this is not optional for ISV-grade solutions.
For automated pipelines (Azure DevOps, GitHub Actions using the Power Platform Build Tools), you can use XSLT transforms or PowerShell scripts to bulk-apply managed property settings across a solution file as part of your build process. This is the right approach for large solutions with dozens of tables and hundreds of components — manually configuring managed properties through the UI at that scale is error-prone and time-consuming.
Here's a PowerShell snippet that demonstrates finding all form elements and setting their customizability to false:
[xml]$customizations = Get-Content ".\customizations.xml" -Encoding UTF8
$forms = $customizations.SelectNodes("//systemform")
foreach ($form in $forms) {
$isCustomizable = $form.SelectSingleNode("IsCustomizable")
if ($isCustomizable -ne $null) {
$isCustomizable.InnerText = "0"
} else {
$newNode = $customizations.CreateElement("IsCustomizable")
$newNode.InnerText = "0"
$form.AppendChild($newNode) | Out-Null
}
}
$customizations.Save(".\customizations.xml")
Write-Host "Locked $($forms.Count) forms"
This kind of script, run as a pre-export build step, ensures that every form in your solution has its customizability locked before the managed solution package is created — without requiring manual clicks in the UI for each component.
This is where the topic gets genuinely complex, and where many solutions fail in the field. You need to understand the solution layer model to understand the full implications of managed properties.
When a managed solution is installed in an environment, Dataverse stores it in a layer. If multiple managed solutions from different publishers touch the same components, they stack in layers ordered by their import sequence, with unmanaged customizations in the environment sitting in the topmost "active" layer.
Here's the critical rule: Managed property locks apply only to the layer below. This means:
This second point surprises most people. If Contoso Healthcare Solutions ships a managed solution with a locked form, and then a separate "Contoso Integration Adapter" managed solution from a different publisher imports into the same environment, the Integration Adapter can technically modify that form if it includes the form component in its own solution with updated definitions.
Key insight
Managed property locks protect against unmanaged modifications and lower-layer modifications. They do not protect against higher-layer managed solutions from other publishers overwriting components. If you're building a platform solution that others will extend with their own managed solutions, plan for this scenario explicitly. ISVs who want true immutability need contractual agreements with integration partners, not just technical locks.
The practical implication: if you're building a base solution that other ISVs will build on top of, you need to decide which components are part of your public API (extensible) and which are internal implementation details (locked). Document this boundary explicitly. Your managed properties configuration is your API contract.
Another layering subtlety: when a consumer environment has both your managed solution and an unmanaged customization layer active, the active layer wins for component properties that are not locked. If you've locked a column's definition but left the form unlocked, the form changes apply even though the column beneath it is frozen. Understanding this asymmetry helps you think about where locks are necessary versus where they're merely defensive.
Rather than just enumerating features, let's talk about how to actually design your managed property strategy for a real solution. This requires thinking about three distinct categories of components:
These are the foundation components that your solution logic depends on absolutely. If these change, your solution breaks. Lock them completely.
Examples:
For these, set IsCustomizable to 0 at both the table level (for table-level properties) and at the individual component level. Be ruthless here. If your plugin code references a specific column by schema name and assumes it has a specific data type, that column must be locked.
These are the surfaces your solution presents to end users. You want the UX to remain consistent and validated, but you don't need to prevent consumers from building additional custom forms for their own use cases.
The right managed property configuration for model-driven forms in this category:
IsCustomizable = 0 on each form component)CanCreateForms = 1 on the table)This gives consumers the ability to build custom forms and views on top of your data model without touching your canonical ones.
These are places where you expect and want consumers to extend your solution. Being explicit about these prevents you from accidentally locking things that need to stay open.
Examples:
Document your extension points explicitly in your solution documentation. A README or solution description that says "The contoso_category global choice column accepts new options but existing options cannot be modified" tells an integrating developer exactly what the contract is.
Tip
Create a solution boundary matrix — a simple spreadsheet or table that lists every major component in your solution alongside its managed property settings and the rationale for each decision. This document is invaluable when your solution grows, when you onboard new developers, and when customers ask why they can't modify something. Make it part of your solution's delivery artifacts.
Several advanced component types warrant special discussion because their managed property behavior is less obvious.
Power Apps Component Framework controls registered in a solution can have their component registration locked, but this doesn't lock the control code itself — the underlying JavaScript bundle is what implements the behavior. For true code protection, PCF controls need to be distributed as compiled, obfuscated bundles separate from the solution file. Managed properties on the control's solution registration prevents configuration changes to how the control is wired up in the environment, but not code-level inspection. For solutions that include PCF controls for model-driven apps, understand this distinction clearly.
Plugin assemblies included in a solution have a managed property: Allow customizations. When locked, the assembly registration cannot be modified in the target environment — the plugin steps, filters, and configurations are frozen. This is critical for ISVs because plugin configurations (which messages they fire on, their filter criteria, their execution order) directly affect business behavior. Lock these.
Warning
Locking a plugin assembly's customizability means you cannot make a hotfix to plugin behavior without shipping a full solution update. For solutions in highly regulated environments where emergency fixes might be needed, consider whether a configuration-driven approach (plugin behavior driven by configuration table data rather than hard-coded logic) gives you the operational flexibility you need.
Environment variables and connection references are specifically designed to be customizable — they're the mechanism by which consumers provide environment-specific values. Setting IsCustomizable = 0 on an environment variable would prevent the consumer from supplying the value your solution needs, which would break your solution immediately. Never lock these. If anything, verify in your testing that environment variables are always left with IsCustomizable = 1.
Shipping a managed solution with incorrect managed property settings is expensive to fix. Here's a validation process to run before every managed solution export.
Step 1: Export and inspect the XML
Export your unmanaged solution, extract the zip, and open customizations.xml in a code editor with XML support (VS Code with the XML extension works well). Search for IsCustomizable and audit every occurrence against your solution boundary matrix. Are there any 1 values where you expected 0? Any components missing an IsCustomizable element entirely (which defaults to 1)?
Step 2: Deploy to a dedicated validation environment
Import your managed solution into a clean environment — one that has none of your unmanaged components. Attempt to make modifications to locked components. If the lock is configured correctly, the platform should prevent changes and display an error like "You cannot edit this component because it is part of a managed solution."
Try these specific tests:
Step 3: Test your extension points
In the same validation environment, verify that your intentionally open extension points work. Can a consumer add a new column to a table you left extensible? Can they create a new form? Can they add new option set values? If these fail, you've over-locked.
Step 4: Test solution upgrade behavior
Import a second version of your managed solution (with a minor change) over the first. Verify that:
This last test is critical. One of the most common ISV support issues is solution upgrades that delete consumer customizations. Understanding how Dataverse merges managed and unmanaged layers during an upgrade protects your consumers' investment.
In this exercise, you'll build a minimal but realistic managed solution with a deliberate boundary strategy, deploy it to a sandbox environment, and validate the locks.
Scenario: You're building "Contoso Asset Tracker" — a managed solution for tracking physical assets in enterprise environments. The solution has a core contoso_asset table with fields like serial number, asset category, purchase date, and assigned location. You want:
Step 1: Create the solution components
In make.powerapps.com, create a new solution with publisher prefix contoso. Add a table contoso_asset with columns:
contoso_serialnumber (Text, required)contoso_assetcategory (Global Choice, connecting to a new global choice contoso_assetcategory)contoso_purchasedate (Date Only)contoso_assignedlocation (Text)Add options to the global choice: Hardware, Software, Furniture, Vehicles.
Create a main form with all four fields. Create a view "Active Assets" filtered to show only active records, sorted by serial number.
Step 2: Configure managed properties via UI
For the contoso_serialnumber column: Managed Properties → Allow customizations: Off.
For the contoso_assetcategory column: Managed Properties → Allow customizations: Off.
For the Asset form: Managed Properties → Allow customizations: Off.
For the Active Assets view: Managed Properties → Allow customizations: Off.
For the contoso_assetcategory global choice: Managed Properties → Allow customizations: Off, Allow adding new options: On.
For the contoso_asset table: Managed Properties → Allow customizations: On, Allow new forms: On, Allow new views: On, Allow new charts: On, Allow new relationships: On.
Step 3: Export as managed and validate the XML
Export the solution as managed. Extract the zip and open customizations.xml. Verify:
Search for contoso_serialnumber — find its IsCustomizable element and confirm it's 0.
Search for the form definition — confirm its IsCustomizable is 0.
Search for the table entity definition — confirm IsCustomizable is 1 and CanCreateForms is 1.
Step 4: Import to a sandbox and test
Import the managed solution to a sandbox environment. Attempt to:
Document which tests pass and which fail. If any test produces unexpected results, return to the source environment, inspect the XML, correct the managed property settings, re-export, and re-import.
Mistake 1: Locking components that consumers must configure
The most common ISV mistake. Developers lock things that seem like internal implementation details but that consumers must configure for their environment — things like email templates that reference specific sender addresses, security roles that reference specific teams, environment variables. Result: the solution imports but doesn't work, and the consumer can't fix it without the ISV's involvement.
Fix: Review every component that contains environment-specific data (addresses, identifiers, team references) and ensure those components or their configuration points are not locked.
Mistake 2: Forgetting that managed properties default to unlocked
If you don't explicitly set a managed property, it defaults to IsCustomizable = 1 — fully open. Developers often assume things are locked when they haven't explicitly set them. Large solutions can have hundreds of components, and manually checking each one through the UI is impractical.
Fix: Use XML inspection and automated scripts to audit your entire solution's managed property configuration as part of your build process, not as a manual post-build check.
Mistake 3: Setting table-level Allow customizations to false
Setting the master Allow customizations switch to false at the table level overrides all other table managed properties and locks everything. If you do this but then a consumer needs to use your table as a related table in their own relationship, they can't. You've broken their ability to extend the solution.
Fix: Use specific managed properties (CanCreateForms, CanCreateAttributes) rather than the master switch unless you truly need to lock the entire table. Reserve the master switch for genuinely internal tables.
Mistake 4: Locking security roles without locking related tables
You ship a locked "Read Only Analyst" security role, but you leave the core tables unlocked. A consumer can change the table's access level for their existing security roles, effectively granting themselves permissions to data that your locked role tried to restrict. Managed property locks on roles don't create a holistic security boundary.
Fix: Understand that security architecture requires both managed property locks AND proper security role and business unit design. Managed properties lock the schema; the actual data access model needs its own design layer.
Mistake 5: Not testing solution upgrades
You ship v1.0 with managed properties configured. You update your solution and ship v1.1. The upgrade process in Dataverse can behave unexpectedly when upgrading managed solutions, particularly around deleted components and layer merging.
Fix: Always test upgrades specifically. Import v1.0, make consumer customizations in the unmanaged layer, then import v1.1 and verify that consumer customizations survive where they should and that new locks from v1.1 are applied correctly.
Troubleshooting: "I can't make changes to a component in my development environment"
This happens when developers import a managed solution into their development environment and then try to build on top of it in the same environment. The managed solution's locks apply even in development environments.
Fix: If you're building on top of a managed base solution, create your extensions as a separate unmanaged solution. If you're the solution author who accidentally locked yourself out, you need to update the source solution (increase the version number, set the managed properties to open, export managed, import to dev). Always maintain a separate "clean source" environment that has your solution in unmanaged form.
Managed properties are the mechanism that transforms a Dataverse solution from a development artifact into a controlled platform product. They let you define explicit boundaries between what you own and control versus what your consumers can adapt for their needs. The most important principles from this lesson:
The next topics to explore from here are deep-dives into solution upgrade mechanics (how Dataverse handles component deletions and additions across versions), publisher strategies for multi-solution architectures (when to split a single large solution into multiple layered solutions), and the full lifecycle of a managed component when a solution is uninstalled. These topics build directly on what you've learned here about how the platform enforces managed property constraints throughout a solution's operational life.
For the data model foundations that underpin these components, review Designing a Dataverse Data Model: Relationships, Lookups, and Choice Columns, which covers how to structure the components you'll be locking. For form design considerations that inform what you should lock versus leave extensible, Designing Model-Driven Forms: Sections, Tabs, Subgrids, and Quick View Forms provides the context you need.