Skip to content

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) and matchAny (OR) groups to build precise rules

Matcher Types

Matchers evaluate metadata from discovered shortcuts and executables.

TypeDescriptionExample
shortcutNameMatches the display name of the shortcut"Google Chrome"
targetPathMatches the executable file path"C:\Program Files\Google\Chrome\Application\chrome.exe"
argumentsMatches command-line arguments"--incognito"
publisherCertificateMatches the leaf code-signing certificate of the resolved executable. Match by thumbprint, Subject CN (publisher name), or Issuer CN."F0E1D2C3B4A5968778695A4B3C2D1E0FABCDEF12" or "Google LLC"
fileHashMatches the SHA-256 hash of the resolved executable"9F2A2F2B8E8A7C7F2E4AD941C90A7A1B0E4C1B9B4F3F7E6C2A0DBE4A9F1C0E2D"
versionMatches 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

TypeDescription
exactExact text match (case-insensitive)
regexRegular expression pattern matching
globShell-style wildcard matching for file paths (supports *, ?, and **). Easier to read and avoids regex escaping for typical path rules.

Recommendations

  • Always specify patternType explicitly ("glob", "regex", or "exact") to avoid ambiguity.
  • Use exact for 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 extensions array and avoid regex alternation for extensions. Matching is case-insensitive and patternType does not apply to the extensions form.
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 shortcutName and targetPath so 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.
  • glob
    • Intended for Windows file paths (for example, targetPath) and evaluated case-insensitively, consistent with typical Windows path behavior.

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 matchAll and matchAny groups 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 matchAll or matchAny, 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.exe
  • C:\\\\**\\\\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"

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 (exact is 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 targetPath and/or version for higher assurance; add fileHash for 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 fileHash matcher is present or when cache is invalidated.

version

  • Matches ProductVersion (fallback to FileVersion) from PE metadata.
  • Use exact to pin a single version.
  • Use regex to allow a version range (for example ^(1\\.(2|3)\\.[0-9]+)$).

Enterprise recommendations

  • Bind identity to location: targetPath + publisherCertificate.
  • Constrain updates: add a version regex (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