Per-Product Scoping
The default engine treats Department, Location, and Cost Centre as soft preferences via affinity scoring. The Allocation Rule field on each Software License (and the matching Default Allocation Rule on each catalog entry) lets you promote any of those three dimensions to a hard requirement on a per-license or per-product basis — without writing rules.
This page covers the built-in dropdown, how catalog defaults flow through to licenses, and the advanced custom-scope pattern for cases the built-in field cannot express.
The Built-In Allocation Rule
Every Software License record has an Allocation Rule field with these options:
| Option | What the Engine Enforces |
|---|---|
| Inherit from catalog | Use whatever the Software Catalog entry says (or fall back to the engine default if the catalog has no rule set) |
| Allocate by Department | Consumption's department must match — the license is excluded for any consumption in a different department |
| Allocate by Location | Consumption's location must match (within the license's location) |
| Allocate by Cost Centre | Consumption's cost centre must match |
| Allocate by Department + Location | Both must match |
| Allocate by Department + Cost Centre | Both must match |
| Allocate by Location + Cost Centre | Both must match |
| Allocate by Department + Location + Cost Centre | All three must match |
The Software Catalog entry has the same dropdown, labelled Default Allocation Rule, plus a "Use Default Rules" option that means "no per-product default — let each license set its own."
How Catalog and License Combine
The catalog's Default Allocation Rule is the starting point. Each license can override it. The engine reads:
| License setting | Catalog setting | Engine behaviour |
|---|---|---|
| Inherit from catalog | Use Default Rules | Engine defaults — Location requirement only (the legacy behaviour) |
| Inherit from catalog | Allocate by Department | All licenses for this product enforce Department |
| Allocate by Cost Centre | Allocate by Department | This license enforces Cost Centre; sibling licenses for the same product enforce Department |
| Allocate by Department + Location | (anything) | This license enforces both, regardless of catalog |
The catalog default is the "policy across all licenses for this product"; the per-license setting is the override for the few cases that need to differ.
Worked Example: Adobe Per-Department
The classic case. Adobe licenses purchased by Marketing must only cover Marketing users; licenses bought by Engineering must only cover Engineering users.
- Open each Adobe Software Catalog entry.
- Set Default Allocation Rule to Allocate by Department.
- Save. All existing Adobe licenses inherit this default; their Allocation Rule stays at "Inherit from catalog" but the engine now treats Department as a hard requirement for them.
- Recalculate.
A Marketing-owned Adobe license can no longer cover an Engineering machine, even if a Marketing-department asset is in deficit and Engineering has spare capacity. The constraint is enforced symmetrically.
Worked Example: One License That Bucks the Trend
Most Adobe licenses follow per-department policy, but one bulk-purchase enterprise license is allowed to cover any department.
- Adobe catalog entry: Default Allocation Rule = Allocate by Department (as above).
- The bulk-purchase license: open the License record, set Allocation Rule to … any value other than "Inherit from catalog" that suits. If you genuinely want this license unscoped, leave Allocation Rule as "Inherit from catalog" and the catalog default takes effect; if you want this license to ignore the per-department policy entirely, pick an option that explicitly states a different scope (e.g., Allocate by Location if it's location-bound) — anything except "Inherit from catalog" overrides the catalog default for this license alone.
If you need a license that explicitly has no scope (covers anywhere) while the catalog enforces something, set the catalog to "Use Default Rules" and rely on per-license configuration instead — keep the policy where it actually varies.
What "Allocate by ..." Means Mechanically
Selecting Allocate by Department activates a hidden Requirement rule the engine carries internally:
Requirement Consumption.DepartmentID within License.DepartmentID
The rule fires only for licenses whose Allocation Rule (or inherited catalog default) includes the Department bit. For all other licenses it stays dormant. The rule uses the existing within comparator, so a department hierarchy match counts (a license tagged "IT Division" covers consumptions in "IT Support" if IT Support is a child of IT Division in the department tree).
The same applies for Location (already enforced by default in the legacy behaviour) and Cost Centre.
Where the Field Lives
LicenseAllocationRule is a stored integer on the Asset record. The dropdown values map to a bitfield (1 = Department, 2 = Location, 4 = Cost Centre) so combinations work cleanly — but you don't normally see the integer; you pick a labelled option from the dropdown.
The catalog→license inheritance is implemented in the engine's data feeder via COALESCE(license.LicenseAllocationRule, catalog.LicenseAllocationRule, 0). NULL on either side falls through; an explicit "Inherit from catalog" choice on the license is also stored as NULL.
Advanced: Custom Scope Patterns
The dropdown covers the common policies. If you need scoping rules the dropdown cannot express — for example, "scope by a custom Project field," "scope only when the license has a non-empty Region tag," or "use a different combination of dimensions per license" — you can build it yourself using the same calculated-field pattern the engine itself uses internally.
Step 1: Add a Flag to the Catalog or License
Add a custom integer spec field to the relevant category (Software Catalog = 143, Software License = 10, or both). Set it to 1 for products or licenses that should be subject to your custom rule. See Configuration Guide: Custom Spec Fields.
Step 2: Surface the Flag in the Data Sources
Both feeder queries need to surface the flag, aliased exactly as your field name on both sides:
Calculate Software License Entitlements— join from license to its product (viaAsset.SoftwareCatalogEntry) and select the flag.Calculate Software License Consumptions— join fromst.ProductIDto the product and select the flag.
Use an outer join or ISNULL(..., 0) so the flag is always present on every row.
Step 3: Add the Scoping Rules
In Configure, add three rules following the sentinel pattern:
Set Consumption.MyScope = IIF(Consumption.MyFlag = 1, Consumption.MyDimension, -1)
Set License.MyScope = IIF(License.MyFlag = 1, License.MyDimension, -1)
Requirement Consumption.MyScope = License.MyScope
For a flagged product, both sides resolve to the real dimension and the requirement enforces it. For unflagged products, both sides collapse to -1 and the requirement is trivially satisfied.
Constraints on Custom Patterns
| Constraint | Detail |
|---|---|
| Use integer flags | Strings (e.g., IIF(Manufacturer = "Adobe", ...)) misbehave silently because the expression evaluator does not quote string literals reliably. Use integer comparisons. |
| Sentinel choice matters | Use -1 (or another value that cannot legitimately occur in the column), not 0 — some records genuinely have DepartmentID = 0. |
| Column must exist on every row | Data source queries must always return the flag. Use outer joins or ISNULL — a missing column throws. |
Comparator is = only |
Custom synthetic columns work with equality. The within comparator is wired only for the three real hierarchy fields (DepartmentID, LocationID, CostCentreID). The built-in Allocation Rule uses these real columns and so supports within; a custom MyScope field cannot. |
If a custom hierarchy-aware scope is required, expand the source data instead: emit one row per ancestor at query time so equality matching can pick up the parent.
Why Not Just Add a Per-Product Requirement Syntax in the Rules File
The rules block is global to the calculation, not parameterised per product. There is no Requirement ... WHERE Product = 'Adobe' syntax. The Allocation Rule field expresses per-product and per-license variation through the data, which keeps the rule evaluator simple and predictable.
Related Reading
- Software Licenses: Creating a License Record — where the per-license dropdown lives
- Software Catalog: Per-Product Configuration — where the catalog default lives
- Common Recipes — including a worked Adobe-per-department example
- Concepts: Affinity vs Requirements
- Default Rules