Skip to content

Appendix B: Metadata Type Risk Classification Matrix

This matrix classifies Salesforce metadata types into four risk tiers, Tier 0 to Tier 3, that govern automated PR workflow behaviour as described in Section 6. It is the canonical matrix: Section 6 defines the tiers and links here rather than repeating the assignments. The tiers classify metadata deployed to the org. Secrets and credentials are governed in Section 7, and configuration stored as records rather than metadata follows the Configuration Data standard. The classification is based on the potential blast radius of an erroneous change - the breadth of impact, reversibility, and likelihood of cascading failures across dependent components or data.

How this matrix is used in the pipeline: The tables on this page are the human-readable matrix; metadata-risk-tiers.yml is its machine-readable form, read by the pipeline. Tier 0 metadata is blocked outright rather than reviewed: its paths are listed in .forceignore and .gitignore, a GitHub push ruleset rejects any push containing them, a required PR status check fails any PR whose diff includes them, and a static analysis rule reports any file of a Tier 0 type at severity 1 (see Tier 0 Enforcement). A required workflow labels every PR with its highest risk tier, from Tier 0 to Tier 3. From qa upwards, Tier 1 changes require the architect team's approval through CODEOWNERS; on every branch, auto-merge is disabled for them (see Tier 1 Enforcement); a linked ITSM record is optional. Tier 2 applies the standard quality gate chain. Tier 3 is eligible for expedited review policies in mature teams.

This matrix should be maintained as a versioned artifact in the centralised configuration repository and reviewed periodically as the organisation's risk posture and the Salesforce platform evolve. It is intentionally a starting point - organisations should adjust tier assignments to reflect their specific regulatory environment, data sensitivity, and operational history.

Machine-Readable Matrix

The pipeline reads the matrix from metadata-risk-tiers.yml. Its canonical copy lives in the config/ directory of the configuration repository (Appendix D), and each project repository keeps its copy in .github/, where the two workflows that read it look by default (Repository Structure). The Prohibited Metadata Check reads its tier0 list, and the Metadata Risk Tier workflow reads the tier1, tier2, and tier3 lists. A metadata file that matches no list is treated as Tier 2, and the workflow warns about it, so that every new metadata type is classified here before it becomes routine in the codebase.

Expand to show the risk matrix file
Metadata Risk Tiers
# metadata-risk-tiers.yml
# Machine-readable metadata risk matrix.
# The paths below are examples only. Include every metadata type on your
# organisation's own list for each tier, not just these.
# Patterns use fnmatch syntax, the same as the Tier 0 push ruleset.
# A metadata file that matches no pattern is treated as Tier 2 (standard
# risk), and the risk tier workflow warns about it so it can be classified.
# Patterns are checked in order: tier0, tier1, tier2, tier3.

tier0:
  - "**/flowDefinitions/**"
  - "**/*.flowDefinition-meta.xml"
  - "**/certs/**"
  - "**/*.crt"
  - "**/*.crt-meta.xml"
  # External Client App global OAuth settings: consumer key and secret
  - "**/extlClntAppGlobalOauthSets/**"
  - "**/*.ecaGlblOauth-meta.xml"
  # S-Controls: superseded by Visualforce pages
  - "**/scontrols/**"
  - "**/*.scf"
  - "**/*.scf-meta.xml"

tier1:
  - "**/sharingRules/**"
  - "**/territory2Models/**"
  - "**/namedCredentials/**"
  - "**/externalClientApps/**"
  - "**/extlClntAppOauthSettings/**"
  - "**/extlClntAppOauthPolicies/**"
  # Legacy: no new Connected Apps since Spring '26; existing ones remain
  - "**/connectedApps/**"
  - "**/authproviders/**"
  - "**/customPermissions/**"
  - "**/permissionsets/**"
  - "**/permissionsetgroups/**"
  - "**/profiles/**"
  - "**/mutingpermissionsets/**"
  # User access policies grant permission sets and groups automatically
  - "**/useraccesspolicies/**"
  # Experience Cloud: sharing sets give external users access to records,
  # and audiences decide who sees a site's pages and content
  - "**/sharingSets/**"
  - "**/audience/**"
  # Org settings: one settings file changes the behaviour of the whole org
  - "**/settings/**"
  - "**/objects/*__mdt/**"
  - "**/platformEventChannels/**"
  - "**/remoteSiteSettings/**"
  - "**/cspTrustedSites/**"
  - "**/corsWhitelistOrigins/**"
  # Destructive manifests usually sit at the repository root, so match
  # them both at the root and in subdirectories.
  - "destructiveChanges*.xml"
  - "**/destructiveChanges*.xml"

tier2:
  - "**/classes/**"
  - "**/triggers/**"
  - "**/lwc/**"
  - "**/aura/**"
  - "**/pages/**"
  # Custom objects and their fields, validation rules, record types,
  # and custom setting definitions. Custom metadata types (__mdt) are
  # Tier 1 and matched above.
  - "**/objects/**"
  - "**/flows/**"
  - "**/workflows/**"
  - "**/labels/**"
  - "**/flexipages/**"
  - "**/layouts/**"
  - "**/queues/**"
  - "**/assignmentRules/**"
  - "**/duplicateRules/**"
  - "**/matchingRules/**"
  - "**/globalValueSets/**"
  # Agentforce and AI metadata
  - "**/aiAuthoringBundles/**"
  - "**/bots/**"
  - "**/botBlocks/**"
  - "**/botTemplates/**"
  - "**/genAiPlanners/**"
  - "**/genAiPlannerBundles/**"
  - "**/genAiPlugins/**"
  - "**/genAiFunctions/**"
  - "**/genAiPromptTemplates/**"
  - "**/genAiPromptTemplateActivations/**"
  - "**/aiApplications/**"
  - "**/aiApplicationConfigs/**"
  - "**/aiScoringModelDefinitions/**"
  - "**/aiUsecaseDefinitions/**"
  - "**/aiEvaluationDefinitions/**"

tier3:
  - "**/staticresources/**"
  - "**/translations/**"
  - "**/prompts/**"
  - "**/pathAssistants/**"
  - "**/email/**"
  - "**/reports/**"
  - "**/dashboards/**"
  - "**/documents/**"

Tier 0 - Prohibited Metadata

These metadata types are never stored in version control. They are managed directly in each org, and the pipeline blocks them at every layer described in Section 6.

Metadata Type API Name Rationale
Flow Definition FlowDefinition Salesforce manages the active Flow version server-side; committing FlowDefinition creates merge conflicts and provides no governance benefit.
Certificate Certificate Should be managed manually in each org
External Client App Global OAuth Settings ExtlClntAppGlobalOauthSettings Holds the app's OAuth consumer key and consumer secret, which must be protected; configured in each org, never committed. The rest of the app is Tier 1.
S-Control Scontrol Superseded by Visualforce pages, and an org that has never used s-controls cannot create one; an existing s-control is rebuilt as a Visualforce page or a Lightning web component, never committed (Scontrol)

Tier 0 Enforcement

The table above is the Tier 0 group, and each type in it is blocked at five layers. Its paths appear in three files and its type names in a fourth, the PMD ruleset, and all of them must agree. When a type is added to this table, update the files together:

  • .forceignore and .gitignore: the entries below. The Salesforce CLI then never retrieves or deploys the paths, and Git does not stage them by accident.
  • Risk matrix file: the tier0 list in metadata-risk-tiers.yml, which the required status check reads.
  • Push ruleset: the Tier 0 push ruleset in Appendix C rejects any push containing them.
  • Required status check: the Prohibited Metadata Check in Appendix A fails any PR that adds or modifies them, and so fails the Quality Gates check that every branch protection ruleset requires. It reads its paths from the risk matrix file rather than holding its own copy.
  • Static analysis rule: the PMD rule ProhibitedMetadataType in pmd-custom-rules-metadata.xml holds the same types in its metadataTypes property, each by its API name, which is the name of the root element of its file. The rule reports every metadata file of a listed type at severity 1. It reads what a file contains and not where it is, so it also reports a Tier 0 file saved under another name or in another folder. It reads XML only, so a certificate's .crt file and an s-control's .scf file are left to the path checks.

The same block goes in both .forceignore and .gitignore, which share the same pattern syntax:

# Tier 0 - prohibited metadata. Never commit, retrieve, or deploy.
# The entries below are examples only. Include every item on your
# organisation's own Tier 0 list, not just these.
# Keep in step with the tier0 list in metadata-risk-tiers.yml, the Tier 0
# push ruleset, and the ProhibitedMetadataType rule.

# FlowDefinition: Salesforce manages the active Flow version server-side
**/flowDefinitions/
**/*.flowDefinition-meta.xml

# Certificate: managed manually in each org
**/certs/
**/*.crt
**/*.crt-meta.xml

# ExtlClntAppGlobalOauthSettings: holds the OAuth consumer key and secret
**/extlClntAppGlobalOauthSets/
**/*.ecaGlblOauth-meta.xml

# Scontrol: superseded by Visualforce pages
**/scontrols/
**/*.scf
**/*.scf-meta.xml

Tier 1 - High Risk Metadata

Metadata Type API Name Rationale
Sharing Rules SharingRules Controls record visibility; misconfiguration can expose sensitive data org-wide
Territory Management Territory2, Territory2Model Affects record access for large user populations
Named Credentials NamedCredential Governs authentication to external systems
External Client Apps ExternalClientApplication, ExtlClntAppOauthSettings, ExtlClntAppOauthConfigurablePolicies Controls OAuth flows and external system access. The app's global OAuth settings file is Tier 0
Connected Apps (legacy) ConnectedApp Existing Connected Apps keep working and stay Tier 1; new ones can no longer be created (Spring '26), so new integrations use External Client Apps
Auth Providers AuthProvider Governs SSO and identity federation
Custom Permissions CustomPermission Used in permission set and flow-based access control
Permission Sets PermissionSet Grants object, field, and system permissions
Permission Set Groups PermissionSetGroup Aggregates permission sets
Profiles Profile Broad access control surface
Muting Permission Sets MutingPermissionSet Removes permissions from permission set groups
User Access Policies UserAccessPolicy Grants or revokes permission sets, permission set groups, licences, public groups, and queues for every user it matches, by itself when users are created or updated
Sharing Sets SharingSet Gives Experience Cloud users access to records that are related to their account or contact
Audiences Audience Decides which Experience Cloud users see a site's pages and content
Org Settings Settings (every type, such as SecuritySettings, SharingSettings, and FlowSettings) One file changes the behaviour of the whole org: its security, its sharing model and OWD, how Flows deploy, and more
Custom Metadata Types CustomObject (__mdt) Often used for configuration-as-data patterns
Platform Events PlatformEventChannel Changes can break event-driven integrations
Remote Site Settings RemoteSiteSetting Controls which endpoints Apex callouts can reach; some orgs promote these to Tier 0 and manage them in each org
CSP Trusted Sites CspTrustedSite Controls which domains LWC components can load from
CORS Allowlist Origins CorsWhitelistOrigin CORS allowlist entries apply to REST API and Lightning Out requests.
Destructive Changes destructiveChanges.xml Any destructive change manifest

Profiles and permission sets get more scrutiny than their tier alone gives them: the permissions that block a change outright, and further metadata governance rules, are set out on the Permissions and Security page.

Tier 1 Enforcement

Tier 1 changes are governed at three points:

  • Risk matrix file: the tier1 list in metadata-risk-tiers.yml.
  • Required status check: the Metadata Risk Tier workflow labels the PR risk: tier-1 and disables auto-merge, so a Tier 1 change is always merged by hand. It also comments on each Tier 1 file in the diff, with the reason for the review, and asks the reviewer to resolve the conversation when the review of that file is done. The branch rulesets do not let the pull request merge while a conversation is open.
  • CODEOWNERS: the block below makes the architect team the code owner of every Tier 1 path. The rulesets of qa, staging, and main require code owner review (Appendix C), so from qa upwards no Tier 1 change merges without the architect team's approval. On int, one peer approves a Tier 1 change, as for any other change (Approvals).
# Tier 1 - high risk metadata. The architect team reviews every change.
# The entries below are examples only. Include every item on your
# organisation's own Tier 1 list, not just these.
# Keep in step with the tier1 list in metadata-risk-tiers.yml.
# Place this block at the end of CODEOWNERS, after the governance block:
# the last matching pattern takes precedence.

**/sharingRules/                          @<my-org>/architect-team
**/territory2Models/                      @<my-org>/architect-team
**/namedCredentials/                      @<my-org>/architect-team
**/externalClientApps/                    @<my-org>/architect-team
**/extlClntAppOauthSettings/              @<my-org>/architect-team
**/extlClntAppOauthPolicies/              @<my-org>/architect-team
**/connectedApps/                         @<my-org>/architect-team
**/authproviders/                         @<my-org>/architect-team
**/customPermissions/                     @<my-org>/architect-team
**/permissionsets/                        @<my-org>/architect-team
**/permissionsetgroups/                   @<my-org>/architect-team
**/profiles/                              @<my-org>/architect-team
**/mutingpermissionsets/                  @<my-org>/architect-team
**/useraccesspolicies/                    @<my-org>/architect-team
**/sharingSets/                           @<my-org>/architect-team
**/audience/                              @<my-org>/architect-team
**/settings/                              @<my-org>/architect-team
**/objects/*__mdt/                        @<my-org>/architect-team
**/platformEventChannels/                 @<my-org>/architect-team
**/remoteSiteSettings/                    @<my-org>/architect-team
**/cspTrustedSites/                       @<my-org>/architect-team
**/corsWhitelistOrigins/                  @<my-org>/architect-team
**/destructiveChanges*.xml                @<my-org>/architect-team

Tier 2 - Standard Risk Metadata

Metadata Type API Name Notes
Apex Classes ApexClass Standard gate chain; test coverage enforced
Lightning Web Components LightningComponentBundle Jest tests required; Code Analyzer gates apply
Aura Components AuraDefinitionBundle Code Analyzer ESLint gate applies
Visualforce Pages ApexPage Standard gate chain
Custom Objects CustomObject Review for downstream impact
Custom Fields CustomField Field type changes and deletions are higher risk
Validation Rules ValidationRule Can block record saves
Apex Triggers ApexTrigger Execute on DML operations; poorly tested triggers can cause data corruption
Flows (Active) Flow Active Flows execute in user and system contexts
Process Builder Flow (Process type) Legacy automation; same risk profile as Flows
Workflow Rules WorkflowRule Legacy automation that executes on record save
Agentforce Agent Bundle AiAuthoringBundle Top-level SFDX bundle packaging agent definitions, planners, and versioning artifacts (API v65.0+)
Agentforce Agent / Bot Bot, BotVersion Core agent definition; governs agent behaviour, topics, and data access scope
Agent Dialog Block BotBlock Reusable conversational dialogue blocks referenced by agents
Agent Template BotTemplate Reusable agent templates for rapid agent creation
AI Planner GenAiPlanner Controls agent reasoning strategy and action selection
AI Planner Bundle GenAiPlannerBundle Packages planner configuration for deployment with an agent
AI Plugin / Action GenAiPlugin Defines actions an agent can invoke; overpermissioned agents can exfiltrate data
AI Function GenAiFunction Custom callable functions exposed to AI agents
AI Prompt Template GenAiPromptTemplate, GenAiPromptTemplateActv Agent instructions and prompt configurations; manipulated templates can alter agent behaviour
AI Application AIApplication, AIApplicationConfig Einstein AI application definition and configuration (API v50.0+)
AI Scoring Model AIScoringModelDefinition Einstein Prediction Builder scoring model definition (API v58.0+)
AI Usecase Definition AIUsecaseDefinition Einstein AI use case configuration (API v56.0+)
AI Evaluation Definition AiEvaluationDefinition Agentforce testing and evaluation framework definitions (API v65.0+)
Custom Labels CustomLabel Deletion can break dependent code and LWC
Custom Settings CustomObject (definition) The setting values are configuration data, not metadata
Lightning Pages FlexiPage UI layout changes
Page Layouts Layout Affects field visibility
Record Types RecordType Affects picklist values and page layout assignments
Queues Queue Affects record assignment
Assignment Rules AssignmentRule Governs automated record assignment
Duplicate Rules DuplicateRule Controls duplicate detection
Matching Rules MatchingRule Underlies duplicate detection
Global Value Sets GlobalValueSet Deletions affect all dependent fields

Tier 3 - Low Risk Metadata

Metadata Type API Name Notes
Static Resources StaticResource File assets; changes are isolated
Translations Translations Localisation strings; no functional impact
In-App Guidance Prompt User guidance overlays
Path Assistant PathAssistant Sales path UI configuration
Email Templates EmailTemplate Content templates; minimal code risk
Reports Report Reporting configuration
Dashboards Dashboard Reporting visualisation
Documents Document Legacy documents

Static resources and JavaScript: Static resources are Tier 3, but the tier system governs only how a change is approved: a static resource does not need elevated review. It does not, however, mean that the contents go unchecked. Every JavaScript library in a static resource is scanned for known vulnerabilities in several ways, when a PR is submitted and at other times, including with RetireJS (see Dependency Scanning and Appendix E).

Depending on permissions given to users, Reports, Dashboards, Email Templates, and Documents may be pulled from Production to the pipeline branches regularly, which does raise the risk of merge conflicts.

Notes on Matrix Maintenance

Tier promotion: Individual metadata types may warrant promotion to a higher tier based on organisational context. A Custom Label read by Apex code controlling feature flags behaves more like Tier 1 than Tier 2.

New metadata types: Salesforce introduces new metadata types with each major release. New types should be assessed against the Tier 1 criteria and added to this matrix before they appear in the codebase.

Destructive changes override: Any PR containing destructiveChanges.xml or destructiveChangesPre.xml is treated as Tier 1 regardless of which metadata types are listed in the manifest.