From f4174aa30632dcbd8aac34536c3d0f178527852e Mon Sep 17 00:00:00 2001 From: Safija Hubljar Date: Wed, 7 Jan 2026 10:29:18 +0100 Subject: [PATCH 1/4] Data security model docs --- src/.vuepress/config.js | 3 +- .../modules/bootstrap/data-security-model.md | 182 ++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/en/developer-guide/applications/modules/bootstrap/data-security-model.md diff --git a/src/.vuepress/config.js b/src/.vuepress/config.js index 86fd5981..14691e7e 100644 --- a/src/.vuepress/config.js +++ b/src/.vuepress/config.js @@ -209,6 +209,7 @@ module.exports = config({ children: [ ['applications/modules/bootstrap/tags', 'Tags'], ['applications/modules/bootstrap/dynamic-attributes', 'Dynamic Attributes'], + ['applications/modules/bootstrap/data-security-model', 'Data Security Model'], { title: 'Data', collapsable: true, @@ -217,7 +218,7 @@ module.exports = config({ ['applications/modules/bootstrap/data/data-checks', 'Checks'], ['applications/modules/bootstrap/data/data-transformations', 'Transformations'] ] - } + }, ] }, ['preparing-content', 'Commerce Start'], diff --git a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md new file mode 100644 index 00000000..682fb298 --- /dev/null +++ b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md @@ -0,0 +1,182 @@ +--- +title: Data Security Model +tagline: Centralized and flexible control over portal permissions. +author: Safija Hubljar +--- + +## Introduction + +The Portal Data Security Model gives you a centralized and flexible way to manage portal permissions across all entities. It relies on a combination of shared default rules and optional overrides, so you can enforce consistent access control without duplicating rules or hardcoding logic. + +At the core, the model uses two main configuration tables: + +* **Permission Level Defaults** +* **Entity Auth Template** + +--- + +### Permission Level Defaults + +This table sets default access rules that apply to all entities. Think of it as the “baseline” for permissions. + +It’s mainly used in situations like: + +* When access depends on **Business Units** +* When access follows **My Log / My Access** patterns +* When you want the same rules applied across multiple entities + +| Display Name | Logical Name | Description | +| ------------------------ | --------------------------------------- | ------------------------------- | +| OData Filter | `talxis_odatafilter` | Custom OData filter. | +| FetchXML | `talxis_fetchxml` | FetchXML query expression. | +| Power Fx | `talxis_powerfx` | Power Fx formula expression. | +| Preferred Query Language | `talxis_preferredquerylanguagetypecode` | Preferred query language. | +| Permission Level | `talxis_permissionlevel` | Specifies the permission level. | + +--- + +### Entity Auth Template + +The Entity Auth Template is used for entities that: + +* Don’t use the Business Unit feature +* Require custom or entity-specific security rules +* Need to override default permission queries + +**Key features:** + +* Handles both default and override queries +* Lets you control permissions at a fine-grained level per entity +* Supports custom filtering logic when defaults are not enough + +| Display Name | Logical Name | Description | +| ------------------------- | ---------------------------------------- | ------------------------------------------------- | +| Entity Set Name | `talxis_entitysetname` | Name of the entity set. | +| Entity Logical Name | `talxis_entitylogicalname` | Logical name of the entity. | +| Entity Description | `talxis_entitydescription` | Explanation of the entity. | +| Allowed Permission Levels | `talxis_allowedpermissionlevelstypecode` | Which permission levels are allowed. | +| Owner Principal Id | `talxis_ownerprincipalid` | Unique ID of the record owner. | +| Modified By Principal Id | `talxis_modifiedbyprincipalid` | ID of the user who last modified the record. | +| Default Read | `talxis_default_read` | Default read permission. | +| Default Create | `talxis_default_create` | Default create behavior. | +| Default Write | `talxis_default_write` | Default write behavior. | +| Default Delete | `talxis_default_delete` | Default delete behavior. | +| Default Select | `talxis_default_select` | Attributes selected by default (comma-separated). | +| Override None OData | `talxis_override_none_odata` | No OData override applied. | +| Override None Power Fx | `talxis_override_none_powerfx` | No Power Fx override applied. | +| Override None FetchXML | `talxis_override_none_fetchxml` | No FetchXML override applied. | +| Override Basic OData | `talxis_override_basic_odata` | Basic OData override applied. | +| Override Basic Power Fx | `talxis_override_basic_powerfx` | Basic Power Fx override applied. | +| Override Basic FetchXML | `talxis_override_basic_fetchxml` | Basic FetchXML override applied. | +| Override Local OData | `talxis_override_local_odata` | Local OData override applied. | +| Override Local Power Fx | `talxis_override_local_powerfx` | Local Power Fx override applied. | +| Override Local FetchXML | `talxis_override_local_fetchxml` | Local FetchXML override applied. | +| Override Deep OData | `talxis_override_deep_odata` | Deep OData override applied. | +| Override Deep Power Fx | `talxis_override_deep_powerfx` | Deep Power Fx override applied. | +| Override Deep FetchXML | `talxis_override_deep_fetchxml` | Deep FetchXML override applied. | +| Override Global OData | `talxis_override_global_odata` | Global OData override applied. | +| Override Global Power Fx | `talxis_override_global_powerfx` | Global Power Fx override applied. | +| Override Global FetchXML | `talxis_override_global_fetchxml` | Global FetchXML override applied. | + +--- + +### Permission Level optionset (talxis_permissionleveltypecode) + +Supported types: + +| Label | Value | +|-----------------------------------|-------------------| +| None | 742070000 | +| Basic | 742070001 | +| Local | 742070002 | +| Deep | 742070003 | +| Global | 742070004 | + +### Preferred Query Language optionset (talxis_preferredquerylanguagetypecode) + +Supported types: + +| Label | Value | +|-----------------------------------|-------------------| +| Odata | 742070000 | +| FetchXML | 742070001 | + +### Best Practices and Considerations + +When setting up permission filters using FetchXML, OData, or Power Fx, keep these guidelines in mind: + +1. **Use explicit filters, avoid wildcards** + + * Don’t use `*` in EntitySetName or filters unless absolutely necessary. + * Wildcards bypass detailed permission controls and can create serious security risks. + +```xml + + + + +``` + +2. Filter Language and Scope + +- OData filters are usually sufficient for most scenarios and perform better than FetchXML for simple queries. + +- FetchXML filters are used when complex nested queries or aggregations are required, for example link-entity conditions. + +- Power Fx is primarily used when formulas need to compute values dynamically in the frontend. + +Example OData filter + +```text +contactid eq '{{ AuthorizationContextVariables.talxis_currentuser_contactid }}' +``` + +Equivalent FetchXML filter: + +```xml + + + + + + + +``` + +3. Unsupported Scenarios + +- Nested queries retrieved via $expand or link-entity do not enforce permissions on child entities, only the top-level entity respects the filter rules. + +- Some operators, such as `in` on link-entities, are not supported and should be avoided. + +- Converting complex FetchXML to OData is not always reliable, always manually verify results. + +4. Testing and Validation + +- Always manually validate filters after defining them. + +- Test filters with multiple users having different permission levels to ensure they enforce security correctly. + +- Use both OData and FetchXML overrides in a sandbox environment before deploying to production. + +Test example scenario: + +- User A: Should only see accounts they own + +- User B: Should see all accounts created after 2024-01-01 + +- Verify that OData and FetchXML overrides return expected records for each user. + +5. Recommended Override Usage + +- Use the override levels (None, Basic, Local, Deep, Global) to control the scope and priority of your filter rules: + + - **None** – No override, uses default permission queries + - **Basic** – Access to owned records only + - **Local** – Access to business unit records + - **Deep** – Access to business unit records and all child business unit records + - **Global** – Global access + +- Start with OData overrides for simplicity and performance. + +- Use FetchXML or Power Fx only when necessary for advanced scenarios. From c522a5fe973af9d6bd8bc98cb8c4f86049f8dbc1 Mon Sep 17 00:00:00 2001 From: Safija Hubljar Date: Wed, 7 Jan 2026 10:35:26 +0100 Subject: [PATCH 2/4] Fix --- .../modules/bootstrap/data-security-model.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md index 682fb298..00000f33 100644 --- a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md +++ b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md @@ -6,7 +6,7 @@ author: Safija Hubljar ## Introduction -The Portal Data Security Model gives you a centralized and flexible way to manage portal permissions across all entities. It relies on a combination of shared default rules and optional overrides, so you can enforce consistent access control without duplicating rules or hardcoding logic. +The Portal Data Security Model gives you a flexible way to manage portal permissions across all entities. It relies on a combination of shared default rules and optional overrides, so you can enforce consistent access control without duplicating rules or hardcoding logic. At the core, the model uses two main configuration tables: @@ -17,12 +17,11 @@ At the core, the model uses two main configuration tables: ### Permission Level Defaults -This table sets default access rules that apply to all entities. Think of it as the “baseline” for permissions. +This table sets default access rules that apply to all entities. It’s mainly used in situations like: * When access depends on **Business Units** -* When access follows **My Log / My Access** patterns * When you want the same rules applied across multiple entities | Display Name | Logical Name | Description | @@ -103,7 +102,7 @@ Supported types: ### Best Practices and Considerations -When setting up permission filters using FetchXML, OData, or Power Fx, keep these guidelines in mind: +When setting up filters using FetchXML, OData, or Power Fx, keep these guidelines in mind: 1. **Use explicit filters, avoid wildcards** @@ -123,7 +122,7 @@ When setting up permission filters using FetchXML, OData, or Power Fx, keep thes - FetchXML filters are used when complex nested queries or aggregations are required, for example link-entity conditions. -- Power Fx is primarily used when formulas need to compute values dynamically in the frontend. +- Power Fx is primarily used when formulas need to compute values dynamically. Example OData filter From 44c5c7c7e2898a269095cc682ae03612099ad615 Mon Sep 17 00:00:00 2001 From: Safija Hubljar Date: Fri, 9 Jan 2026 10:24:33 +0100 Subject: [PATCH 3/4] Fixes --- .../modules/bootstrap/data-security-model.md | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md index 00000f33..ae6e3172 100644 --- a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md +++ b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md @@ -19,10 +19,7 @@ At the core, the model uses two main configuration tables: This table sets default access rules that apply to all entities. -It’s mainly used in situations like: - -* When access depends on **Business Units** -* When you want the same rules applied across multiple entities +It’s mainly used in situations when you want the same rules applied across multiple entities | Display Name | Logical Name | Description | | ------------------------ | --------------------------------------- | ------------------------------- | @@ -38,9 +35,7 @@ It’s mainly used in situations like: The Entity Auth Template is used for entities that: -* Don’t use the Business Unit feature -* Require custom or entity-specific security rules -* Need to override default permission queries +* Require entity-specific security rules **Key features:** @@ -120,9 +115,9 @@ When setting up filters using FetchXML, OData, or Power Fx, keep these guideline - OData filters are usually sufficient for most scenarios and perform better than FetchXML for simple queries. -- FetchXML filters are used when complex nested queries or aggregations are required, for example link-entity conditions. +- FetchXML filters are used to query and filter data using the full set of FetchXML functionality -- Power Fx is primarily used when formulas need to compute values dynamically. +- Power Fx is primarily used as an additional filter for create, update, and delete requests. Example OData filter @@ -133,13 +128,7 @@ contactid eq '{{ AuthorizationContextVariables.talxis_currentuser_contactid }}' Equivalent FetchXML filter: ```xml - - - - - - ``` 3. Unsupported Scenarios @@ -170,12 +159,10 @@ Test example scenario: - Use the override levels (None, Basic, Local, Deep, Global) to control the scope and priority of your filter rules: - - **None** – No override, uses default permission queries + - **None** – Override for disallowed access - **Basic** – Access to owned records only - **Local** – Access to business unit records - **Deep** – Access to business unit records and all child business unit records - **Global** – Global access - Start with OData overrides for simplicity and performance. - -- Use FetchXML or Power Fx only when necessary for advanced scenarios. From 0f687858b501e68cde4e3a7f1ec87b3fcdd3525a Mon Sep 17 00:00:00 2001 From: Safija Hubljar Date: Mon, 12 Jan 2026 09:54:21 +0100 Subject: [PATCH 4/4] Fixes --- .../modules/bootstrap/data-security-model.md | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md index ae6e3172..2478b768 100644 --- a/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md +++ b/src/en/developer-guide/applications/modules/bootstrap/data-security-model.md @@ -17,7 +17,7 @@ At the core, the model uses two main configuration tables: ### Permission Level Defaults -This table sets default access rules that apply to all entities. +This table sets default access rules that apply to all entities. The `talxis_permissionleveldefaults` are provided by TALXIS and are based on Business Unit security. It’s mainly used in situations when you want the same rules applied across multiple entities @@ -95,6 +95,32 @@ Supported types: | Odata | 742070000 | | FetchXML | 742070001 | +### Preconfigured Authorization Context Variables (talxis_configuration_authcontextvariable) + +| Variable | Description | Use Case | +| ------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------| +| `childbusinessunits` | First level of child business units of the user’s business units | Used to filter subordinate business units of the current user. | +| `mybusinessunits` | Security Team of type business units, where user belongs to via child teams (security teams) | Retrieves business units the user has access to through security teams. | +| `mysecurityteamsarray` | All security teams the current user belongs to | Retrieves all security teams of the user. | + +### Preconfigured Permission Level Defaults (talxis_permissionleveldefaults) + +| Permission Level | OData Filter | FetchXML | Power Fx | Use Case | +|-----------------|-------------|----------|----------|----------| +| None | `createdon eq null` | `` | `false` | Default – no access to records | +| Basic | `talxis_accessprincipalid eq '{ { AuthorizationContextVariables.talxis_accessprincipalid } }'` | `` | `talxis_accessprincipalid = AuthorizationContextVariables.talxis_accessprincipalid` | Access to records owned by the current user | +| Local | `Microsoft.Dynamics.CRM.In(PropertyName='owningbusinessunit',PropertyValues='{ { AuthorizationContextVariables.mybusinessunits } }')` | `{ { AuthorizationContextVariables.mybusinessunits_fetchxml } }` | `owningbusinessunit in AuthorizationContextVariables.mybusinessunits` | Access to records within the user’s business units | +| Deep | `Microsoft.Dynamics.CRM.In(PropertyName='owningbusinessunit',PropertyValues='{ { AuthorizationContextVariables.mybusinessunits } }') or Microsoft.Dynamics.CRM.In(PropertyName='owningbusinessunit',PropertyValues='{ { AuthorizationContextVariables.childbusinessunits } }')` | `{ { AuthorizationContextVariables.mybusinessunits_fetchxml } }{ { AuthorizationContextVariables.childbusinessunits_fetchxml } }` | `owningbusinessunit in AuthorizationContextVariables.mybusinessunits || owningbusinessunit in AuthorizationContextVariables.childbusinessunits` | Access to records within the user’s business units and their child units | +| Global | `*` | `*` | `true` | Full access – for administrators and superusers | + +### Expected User Roles + +The following outlines which roles are expected to configure different parts of the security model based on required expertise: + +**Developers**:`talxis_permissionleveldefaults` and `talxis_entityauthtemplate` should be configured by developers, as they require knowledge of the querying languages. Any configuration allowed with `talxis_advancedmode=true` should also be handled by developers, due to the same level of technical expertise required. + +**Customer/Admins/Consultants**:`talxis_configuration_authruleset`,`talxis_configuration_authretrievefilter`, and `talxis_configuration_authwritecondition` can be managed by customer admins or consultants, mainly by working with `talxis_permissionleveltypecode`. + ### Best Practices and Considerations When setting up filters using FetchXML, OData, or Power Fx, keep these guidelines in mind: @@ -117,7 +143,7 @@ When setting up filters using FetchXML, OData, or Power Fx, keep these guideline - FetchXML filters are used to query and filter data using the full set of FetchXML functionality -- Power Fx is primarily used as an additional filter for create, update, and delete requests. +- Power Fx is used to filter create, update, and delete requests. Example OData filter @@ -159,10 +185,14 @@ Test example scenario: - Use the override levels (None, Basic, Local, Deep, Global) to control the scope and priority of your filter rules: - - **None** – Override for disallowed access + - **None** – No OData override applied - **Basic** – Access to owned records only - **Local** – Access to business unit records - **Deep** – Access to business unit records and all child business unit records - **Global** – Global access - Start with OData overrides for simplicity and performance. + +### Rules Caching + +Rules are cached for 15 minutes at the backend. If you need them refreshed in an emergency situation, a backend app service restart is required.