Appearance
Matchers and Patterns
Define which applications or files your policy targets by combining matcher types with clear, maintainable patterns. Matchers evaluate data discovered from Windows shortcuts (.lnk) and the resolved executable, not arbitrary files on disk.
What You'll Learn
- Choose the right matcher for the job (shortcut, path, arguments, or high-assurance identity)
- Use pattern types (exact, regex, glob) appropriately
- Author Windows path rules with simple, readable globs
- Use
matchAll(AND) andmatchAny(OR) groups to build precise rules
Matcher Types
Matchers evaluate metadata from discovered shortcuts and executables.
| Type | Description | Example |
|---|---|---|
shortcutName | Matches the display name of the shortcut | "Google Chrome" |
targetPath | Matches the executable file path | "C:\Program Files\Google\Chrome\Application\chrome.exe" |
arguments | Matches command-line arguments | "--incognito" |
publisherCertificate | Matches the leaf code-signing certificate of the resolved executable. Match by thumbprint, Subject CN (publisher name), or Issuer CN. | "F0E1D2C3B4A5968778695A4B3C2D1E0FABCDEF12" or "Google LLC" |
fileHash | Matches the SHA-256 hash of the resolved executable | "9F2A2F2B8E8A7C7F2E4AD941C90A7A1B0E4C1B9B4F3F7E6C2A0DBE4A9F1C0E2D" |
version | Matches the executable version (ProductVersion or FileVersion) | "123.0.6422.141" |
Notes
- The Launcher enumerates Windows shortcut files (.lnk) from Start Menu and Desktop and does not scan arbitrary paths.
- Executables must be represented by shortcuts in discovery scope to be matched and launched.
Security Rule — Path vs. Identity
Path-based matching (targetPath, glob) validates location, not integrity. It is vulnerable to "Rename Attacks" where a user with write access to the target folder renames a malicious binary to match your allowed pattern.
Requirement: For high-assurance environments (Zero Trust, CMMC), you must combine path matchers with publisherCertificate or fileHash.
Pattern Types
| Type | Description |
|---|---|
exact | Exact text match (case-insensitive) |
regex | Regular expression pattern matching |
glob | Shell-style wildcard matching for file paths (supports *, ?, and **). Easier to read and avoids regex escaping for typical path rules. |
Recommendations
- Always specify
patternTypeexplicitly ("glob", "regex", or "exact") to avoid ambiguity. - Use
exactfor certificate thumbprints and SHA-256 hashes; hex matching is case-insensitive.
File Type Extensions
- For fileTypes.match and handler-level match filters, author extensions using an
extensionsarray and avoid regex alternation for extensions. Matching is case-insensitive andpatternTypedoes not apply to theextensionsform.
json
{ "match": { "extensions": ["doc", "docx"] } }Single extension:
json
{ "match": { "extensions": ["pdf"] } }Prefer glob for Windows paths
Regex patterns in JSON require double escaping (for example: ".*\\myapp\.exe$"), which is cumbersome and error-prone. Use glob patterns instead (for example: "C:\\Program Files\\**\\myapp.exe") for simpler, more readable rules. Remember to escape backslashes in JSON strings.
Case Sensitivity
- exact
- Exact text match is case-insensitive across all matcher types. This includes publisher certificate thumbprints and SHA-256 hashes (hex is matched case-insensitively).
- regex
- Case-insensitive by default. This applies to Windows-targeted fields such as
shortcutNameandtargetPathso that "chrome.exe" and "Chrome.exe" both match. - For non-path fields (for example,
arguments,version, Subject/Issuer names), matching is also case-insensitive by default for consistency. If you need case-sensitive distinctions, author explicit character classes in your regex.
- Case-insensitive by default. This applies to Windows-targeted fields such as
- glob
- Intended for Windows file paths (for example,
targetPath) and evaluated case-insensitively, consistent with typical Windows path behavior.
- Intended for Windows file paths (for example,
Notes
- On Windows, file system paths are typically case-insensitive; the Launcher aligns with this behavior for path-oriented fields regardless of pattern type.
Boolean Logic Semantics
Application policies support flexible logic using matchAll (AND) and matchAny (OR).
- Logical AND (
matchAll): All items in the array must evaluate to true. - Logical OR (
matchAny): At least one item in the array must evaluate to true. - Nesting: You can nest
matchAllandmatchAnygroups arbitrarily to express complex logic (e.g., (A OR B) AND C). - Rule: You can only have one of each at each level. An object (whether the top-level policy or a nested group) can contain either
matchAllormatchAny, but not both.
No negate flag There is no native negate option. Use regex constructs (for example, negative lookahead) if exclusion is required, but prefer positive, readable matches. For strategies and examples, see: Limitations & Scope — Exclusions and negation.
Other ways to express OR
- Author multiple allow policies when alternatives span different fields. Any matching allow policy authorizes. If more than one allow policy matches, merges resolve by priority (descending) then id. See: Merging & Precedence
- Use regex alternation within a single field when appropriate.
Examples
AND (path + publisher) using matchAll:
json
{
"matchAll": [
{ "type": "targetPath", "pattern": "**\\\\myapp.exe", "patternType": "glob" },
{ "type": "publisherCertificate", "pattern": "5E0B1B36A6F3D1C2A6C9E4B1A46C9D18B1E3F2A469C7BA0E8F1A2B3C4D5E6F70", "patternType": "exact" }
]
}OR (simple list) using matchAny:
json
{
"matchAny": [
{ "type": "targetPath", "pattern": "**\\\\putty.exe", "patternType": "glob" },
{ "type": "targetPath", "pattern": "**\\\\psftp.exe", "patternType": "glob" },
{ "type": "targetPath", "pattern": "**\\\\pageant.exe", "patternType": "glob" },
{ "type": "targetPath", "pattern": "**\\\\puttygen.exe", "patternType": "glob" }
]
}Nested Logic ((A OR B) AND C):
json
{
"matchAll": [
{
"matchAny": [
{ "type": "shortcutName", "pattern": "Google Chrome", "patternType": "exact" },
{ "type": "shortcutName", "pattern": "Microsoft Edge", "patternType": "exact" }
]
},
{ "type": "publisherCertificate", "pattern": "F0E1D2C3...", "patternType": "exact" }
]
}OR (single field via regex alternation):
json
{
"matchAll": [
{ "type": "targetPath", "pattern": ".*\\\\(chrome|msedge)\\.exe$", "patternType": "regex" }
]
}NOT (exclude a specific argument via regex):
json
{
"matchAll": [
{ "type": "arguments", "pattern": "^(?!.*--private).*$", "patternType": "regex" }
]
}Glob patterns
*matches any sequence within a single path segment?matches a single character within a single path segment**matches across path separators (recursive)
Examples
C:\\\\Program Files\\\\*\\\\myapp.exeC:\\\\**\\\\Acrobat.exe**\\\\chrome.exe
JSON escaping note
- When writing patterns inside JSON strings, Windows backslashes must be escaped as
\\.- Regex example:
".*\\\\myapp\\\.exe$" - Glob example:
"C:\\\\**\\\\myapp.exe"
- Regex example:
Windows paths in JSON require double backslashes
When writing Windows paths inside JSON strings, every \ in the actual path must be written as \\ in JSON.
Examples
- Correct glob:
"C:\\\\Program Files\\\\**\\\\myapp.exe" - Correct regex:
".*\\\\myapp\\\.exe$" - Incorrect:
"C:\\Program Files\MyApp\myapp.exe"(mixed or unescaped backslashes) — this either fails to parse or matches the wrong path.
Because JSON and regex escaping both apply to Windows paths, complex regex patterns quickly become hard to read and easy to get wrong. For path-based matchAll rules (for example, targetPath), prefer:
patternType: "glob"for most Windows path rules, and- simple, stable patterns such as
"C:\\\\Program Files\\\\**\\\\myapp.exe".
High-assurance matchers
Use these to bind identity and integrity, especially for sensitive applications.
publisherCertificate
Accepted fields
- Thumbprint (SHA-256 64-hex or SHA-1 40-hex; paste without spaces; case-insensitive)
- Subject CN (publisher display name, for example "Microsoft Corporation")
- Issuer CN (for example "Microsoft Windows Production PCA 2011")
Pattern guidance
- Use
patternType: "exact"for thumbprints and CNs (exactis case-insensitive). - Use
patternType: "regex"to match the full Subject or Issuer distinguished name or to anchor on CN= specifically (for example:(^|,)\\s*CN=Microsoft Corporation(,|$)).
Trust behavior
- Unsigned executables do not match.
- For dual-signed binaries, matching is applied against the leaf signer used by Windows trust.
Best practices
- Prefer Subject CN for maintainability; thumbprints rotate on renewals.
- Combine with
targetPathand/orversionfor higher assurance; addfileHashfor immutability.
Field selection (explicit "field" property)
- You can now specify which certificate field to match with the optional field property on the publisherCertificate matcher:
- thumbprint — Leaf signer certificate thumbprint; requires patternType: "exact"; accepts 64-hex (SHA-256) or 40-hex (SHA-1).
- subjectCN — Leaf signer Subject Common Name (publisher display name); case-insensitive; prefer for maintainability.
- issuerCN — Issuer Common Name of the leaf signer’s issuing CA; use only when intentionally pinning to an issuer.
- subjectDN — Full Subject distinguished name; requires patternType: "regex". Anchor explicitly on CN= to avoid ambiguity.
- issuerDN — Full Issuer distinguished name; requires patternType: "regex". Anchor explicitly on CN= to avoid ambiguity.
Validation rules
- field: "thumbprint" → patternType must be "exact" and pattern must match ^(?:[A-Fa-f0-9]{64}|[A-Fa-f0-9]{40})$.
- field: "subjectDN" or "issuerDN" → patternType must be "regex".
- All certificate comparisons are case-insensitive.
Examples
Thumbprint pin: { "type": "publisherCertificate", "field": "thumbprint", "pattern": "5E0B1B36A6F3D1C2A6C9E4B1A46C9D18B1E3F2A469C7BA0E8F1A2B3C4D5E6F70", "patternType": "exact" }
Subject CN: { "type": "publisherCertificate", "field": "subjectCN", "pattern": "Microsoft Corporation", "patternType": "exact" }
Issuer CN: { "type": "publisherCertificate", "field": "issuerCN", "pattern": "Microsoft Windows Production PCA 2011", "patternType": "exact" }
Subject DN (regex anchored on CN): { "type": "publisherCertificate", "field": "subjectDN", "pattern": "(^|,)\s*CN=Microsoft Corporation(,|$)", "patternType": "regex" }
fileHash
- Matches the SHA-256 hash of the resolved executable.
- Strongest integrity guarantee; any update requires a policy update.
- Hashing is performed only when a
fileHashmatcher is present or when cache is invalidated.
version
- Matches ProductVersion (fallback to FileVersion) from PE metadata.
- Use
exactto pin a single version. - Use
regexto allow a version range (for example^(1\\.(2|3)\\.[0-9]+)$).
Enterprise recommendations
- Bind identity to location:
targetPath+publisherCertificate. - Constrain updates: add a
versionregex (for example, allow only 1.2.x–1.3.x). - Require immutability:
publisherCertificate+fileHash(operationally heavy).
Obtaining values
PowerShell snippets to extract values from an executable:
Publisher certificate thumbprint: (Get-AuthenticodeSignature 'C:\Path\To\app.exe').SignerCertificate.Thumbprint
SHA-256 file hash: (Get-FileHash -Algorithm SHA256 'C:\Path\To\app.exe').Hash
Version (ProductVersion): (Get-Item 'C:\Path\To\app.exe').VersionInfo.ProductVersion
Examples
Pin by publisher and version (glob path):
json
{
"matchAll": [
{ "type": "targetPath", "pattern": "**\\\\myapp.exe", "patternType": "glob" },
{ "type": "publisherCertificate", "pattern": "A1B2C3D4E5F60718273645546352413F0E1D2C3B", "patternType": "exact" },
{ "type": "version", "pattern": "^(1\\.(2|3)\\.[0-9]+)$", "patternType": "regex" }
]
}Allow all Program Files executables (glob path):
json
{
"matchAll": [
{ "type": "targetPath", "pattern": "C:\\\\Program Files\\\\**\\\\*.exe", "patternType": "glob" }
]
}Network destination matching
Use these patterns to match the destination of a network connection for proxy routing or egress policies. Host matching is case-insensitive; prefer glob for readability.
Supported match fields
- hosts: Array of HostPatternSpec objects (pattern + patternType). Case-insensitive. Prefer glob (e.g., "*.corp.local").
- cidrs: Array of IPv4/IPv6 CIDR strings (e.g., "10.0.0.0/8", "2001:db8::/32").
- ipRanges: Array of { from, to } with IPv4/IPv6 addresses.
- ports: Array of PortSpec strings (single "443" or range "8080-8090").
- protocol: "tcp" | "udp" | "icmp".
HostPatternSpec
json
{ "pattern": "*.corp.local", "patternType": "glob" }CIDR examples
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
- "2001:db8::/32"
IP range example
json
{ "from": "1.1.1.1", "to": "1.1.1.255" }PortSpec
- Single: "443"
- Range: "10000-10100"
- Valid ports are 0–65535; ranges must be start ≤ end.
Examples
Hosts via glob (proxy internet, deny otherwise)
json
{
"match": { "hosts": [ { "pattern": "*", "patternType": "glob" } ], "protocol": "tcp" }
}CIDR-based direct for RFC1918
json
{
"match": { "cidrs": ["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"] }
}IP range + port
json
{
"match": { "ipRanges": [ { "from": "203.0.113.0", "to": "203.0.113.255" } ], "ports": ["443"], "protocol": "tcp" }
}Guidance
- Prefer CIDR for known networks and host globs for domains; use regex only for complex host rules.
- Hosts are matched case-insensitively. CIDR/range matching applies equally to IPv4 and IPv6.
- Combine filters (e.g., host + port + protocol) to narrow matches.
Next steps
- Authorization and visibility: Authorization & Visibility
- Merging and precedence: Merging & Precedence
- File handling: File Handling
