Skip to content

Security Best Practices

Advanced security and reliability guidance to harden your Launcher policy beyond the basic allowlist model. These practices add defense-in-depth and operational safety for enterprise deployments.

What You'll Learn

  • Use explicit deny rules; deny takes precedence over allow when both match
  • Require strong identity matchers (publisherCertificate, fileHash) for sensitive apps
  • Validate code-signing with revocation and RFC3161 timestamp semantics
  • Protect policy delivery integrity (signatures, hashes, atomic updates, telemetry)
  • Control printing via UI-level routing and device-level runtime configuration
  • Understand enterprise vs user policy authority: system-wide policy is authoritative

Explicit Deny with Higher Precedence Than Allow

Use explicit deny rules to neutralize broad allow rules (for example, allow “Program Files” but deny a risky sub-path). Deny should take precedence over allow when both match the same shortcut/resolved executable, and be evaluated before visibility and routing gating. See also: Merging & Precedence.

Example:

json
{
  "apps": [
    {
      "id": "allow-program-files",
      "enabled": true,
      "visibility": "visible",
      "matchAll": [
        { "type": "targetPath", "pattern": "C:\\\\Program Files\\\\**\\\\*.exe", "patternType": "glob" }
      ],
      "action": "allow"
    },
    {
      "id": "deny-vendor-updater",
      "enabled": true,
      "visibility": "hidden",
      "matchAll": [
        { "type": "targetPath", "pattern": "C:\\\\Program Files\\\\Vendor\\\\Tool\\\\updater\\\\*.exe", "patternType": "glob" }
      ],
      "action": "deny"
    }
  ]
}

Strong Identity Requirements for High-Risk Apps

For applications that handle sensitive content or may request elevation, prefer strong identity over path-only rules. Require identity matchers such as publisherCertificate and/or fileHash to be present and valid for a positive match. If supported by your policy version, you can express this with an identityRequirements list that must all validate in addition to the matchers. See: Matchers & Patterns and Reference/Schema.

Example:

json
{
  "apps": [
    {
      "id": "sensitive-editor",
      "enabled": true,
      "visibility": "visible",
      "matchAll": [
        { "type": "targetPath", "pattern": "C:\\\\**\\\\SensitiveEditor.exe", "patternType": "glob" },
        { "type": "publisherCertificate", "field": "subjectCN", "pattern": "Contoso Software LLC", "patternType": "exact" },
        { "type": "version", "pattern": "^(2\\\\.(5|6)\\\\.[0-9]+)$", "patternType": "regex" }
      ],
      "identityRequirements": ["publisherCertificate"]
    }
  ]
}

Publisher certificate field targeting

Guidance:

  • Use publisherCertificate to trust a vendor across versions.
  • Use fileHash for immutable pinning of a specific binary.
  • Use version ranges to exclude known-bad versions while still requiring strong identity.

Publisher Certificate Trust Validation (Windows)

Document and configure how publisherCertificate is validated:

  • Mechanism: Windows Authenticode verification (WinVerifyTrust) with a chain to trusted roots in Local Machine stores; require Code Signing EKU.
  • Timestamp: If an RFC3161 timestamp is present and valid, evaluate signature at signing time; otherwise evaluate at the current time.
  • Revocation: Support CRL/OCSP. Provide revocationMode ("online" | "offline" | "none") and revocationFallback (e.g., "fail-closed" or allow cache-only decisions when offline).
  • Pinning (optional): Restrict to allowedSigners (signer thumbprints) or allowedIssuers (enterprise intermediates).

Example configuration:

json
{
  "configuration": {
    "trust": {
      "revocationMode": "online",
      "revocationFallback": "fail-closed",
      "requireTimestamp": true,
      "allowedSigners": ["7DDB...F12A"],
      "allowedIssuers": ["33AA...BB01"]
    }
  }
}

Policy Integrity for Distributed Policies

Protect policy delivery and updates:

  • Signed policy.json (preferred for file shares/offline): Use a detached CMS/PKCS#7 signature and pin acceptable signers by thumbprint. Maintain a last-known-good (LKG) policy and roll back on verification failure.
  • HTTPS safeguards: Validate expectedSha256 of downloaded content, track ETag for efficient updates, and perform atomic replace (download → verify → swap).
  • Telemetry: Log applied policyVersion, the effective schema MAJOR.MINOR.PATCH used for validation, signer subject and thumbprint, chain/revocation status, and reasons for rollback. See: Schema Versioning and Compatibility.

Examples:

json
{
  "policyVersion": 42,
  "policySignature": "MIIQ...base64-cms...",
  "signatureCertificateThumbprints": ["AA11...CC22"],
  "configuration": {
    "policySource": {
      "url": "https://policy.example.com/launcher/policy.json",
      "expectedSha256": "c598...e1b9",
      "etagTracking": true,
      "fallbackToLkgOnFailure": true
    }
  }
}

Printer Control

Launcher policy supports two complementary surfaces for printing:

  • UI-level flow: File routing controls whether a Print action is available for specific file types. If a routing rule does not define verbs.print, the Print action is not offered for files matched by that rule.
  • Device-level enforcement: Printer device access (for example, host printers, virtual printing, print-to-file) is enforced by the runtime using environment-specific configuration. Author portable settings under configuration.launch.runtime.devices or apps[].modifications.runtime.devices. For vendor-specific values, use runtime.extensions. Policy does not define a printer-specific schema. Consult your runtime’s documentation for appropriate values.

Recommendations

  • For IP protection, enforce device-level printer restrictions via the system-wide policy so user-level policy cannot re-enable printers.
  • Use file routing to control Print UI per file type; device-level settings control whether printers are available inside applications.

Related topics: File Types & Routing (print verb), Schema Reference, Device-level Settings (runtime configuration), Runtime Configuration, and Merging & Precedence (location and scope precedence).

Regulated Data (ITAR/CUI): Classification-Aware Enforcement and Watermarking

Recommendations

  • Enable classification integration: configuration.dataClassification.enabled: true with approved providers (e.g., Microsoft Purview, Digital Guardian). Map provider labels to normalized enums (ITAR, CUI, CUI//SP-CTI, etc.) using configuration.dataClassification.mappings.
  • Default on unknown: For ITAR/CMMC environments set configuration.dataClassification.onUnknown: "deny". In non-regulated contexts, use inherit to avoid unintended blocks.
  • Fail-closed channels: For clipboard/dragDrop/screen*, set settings.<channel>.defaultAction: "deny" and allow narrowly via rules.
  • Author against enums: Prefer rules[].match.classifications.normalized over free-form patterns. Example deny: normalized ["CUI", "ITAR"].
  • Dynamic watermarking: Use templates with PII redaction filters (e.g., {User.UPN|hash(8)}) and style: "diagonalRepeating"; set blurBackground: true and mode: "foreground-only" for screenCapture.
  • Audit redaction: Hash or mask PII in audit (settings.audit.redaction) and include classification context (state/normalized/provider/confidence). Use env-backed salt.
  • ScreenShare parity: Mirror watermark and posture on screenShare when enabled; block screen sharing when audit pipeline is unhealthy (requireHealthyFor: ["screenShare"]).

Example configuration (global classification provider and mappings)

json
{
  "configuration": {
    "dataClassification": {
      "onClassificationFailure": "deny",
      "onUnknownClassification": "deny",
      "providers": [
        { "id": "corp-purview", "type": "purview", "confidenceThreshold": 0.8, "cacheTtlSeconds": 30 }
      ],
      "mappings": [
        { "providerId": "corp-purview", "externalLabelId": "11111111-2222-3333-4444-555555555555", "normalized": ["CUI", "CUI//SP-CTI"] },
        { "providerId": "corp-purview", "externalLabelId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "normalized": ["ITAR"] }
      ]
    }
  }
}

Example snippets

  • Clipboard deny for classified content
json
{
  "configuration": {
    "launch": { "runtime": { "dataMotion": {
      "settings": { "clipboard": { "enabled": true, "defaultAction": "deny" } },
      "rules": [ { "id": "clip-deny-cui-itar-out", "enabled": true, "priority": 1000, "channel": "clipboard", "direction": "out", "match": { "classifications": { "normalized": ["CUI", "ITAR"] } }, "action": { "type": "deny" } } ]
    } } }
  }
}
  • Watermark with hashed UPN
json
{
  "settings": { "screenCapture": { "enabled": true, "mode": "foreground-only", "watermark": { "text": "CUI//SP-CTI\nControlled by: {Organization}\n{User.UPN|hash(8)} @ {Timestamp.UTC}", "opacity": 0.3, "persistent": true, "style": "diagonalRepeating", "redactionDefaults": { "pii": "hash", "hashAlgorithm": "sha256", "salt": "env:PII_SALT" } } } }
}

For a complete, production-ready policy configuration, see: CMMC/ITAR Deployment Profile.

Network Control (Egress/Inbound) and Proxy Pinning

Harden VM networking by setting a restrictive baseline and routing egress deterministically via enterprise proxies.

Recommendations

  • Deny-by-default egress for sensitive workloads:
    • Set configuration.network.capabilities.egressDefaultAction: "deny".
    • Explicitly allow destinations via proxyRouting rules (host/CIDR/IP range + ports/protocol).
  • Define proxies only in the system-wide policy:
    • Use configuration.network.proxies (global-only). Do not define or expose secrets in policy; reference credentials via credentialsRef.
    • Enable TLS verification (tls.verify: true) and pin CA bundles via tls.caBundleRef when appropriate.
  • Bypass lists:
    • Restrict bypassHosts to known internal domains only. Prefer explicit RFC1918 CIDRs as direct rules rather than broad bypass.
  • Explicit internal ranges and metadata services:
    • Author direct rules for RFC1918/internal networks where required.
    • Explicitly deny cloud metadata IPs if the runtime permits access and they are not needed for the workload.
  • Per-app exceptions:
    • Use apps[].modifications.network.proxyRouting to add higher-priority direct allowances for specific CDNs or service ranges without weakening the global posture.
  • DNS governance:
    • Constrain DNS using capabilities.dnsAllowed, dnsServers, and dnsSearchSuffixes when the runtime supports it. Prefer enterprise DNS resolvers.
  • Auditable matches:
    • Prefer host globs and CIDRs for readability. Use regex only when necessary.

Selection and precedence

  • Scope precedence: Launch Profile > Policy (App) > Global.
  • Scope precedence: Launch Profile > Policy (App) > Global.
  • Proxy routing rules: additive across scopes; selection by rule priority (desc), then rule id alphabetical. deny short-circuits. See: Merging & Precedence (Networking).

Securing Configuration Templates

Use Configuration Templates to centralize constraints and validate user-provided values without weakening authorization.

  • Environment variable validation
    • Constrain values using validationPattern and patternType: "regex" (e.g., enforce trusted hostnames/protocols/ports for P4 settings).
    • Mark sensitive keys as required: true to prevent incomplete configurations.
  • Mount constraints
    • Allow user configurations to declare mounts, validated against template rules: allowedSourcePatterns, allowedDestinationPatterns, and allowedOptions. Prefer precise allowlists and deny-by-default posture.
  • Authorization unchanged
    • Templates do not bypass app authorization. Apps must still be discoverable and allowed by an application policy.
    • Hidden apps can still be referenced by routing when security gating passes; templates do not change this behavior.
  • Flag control
    • Do not allow users to set runtime settings via templates. Keep runtime/device-level settings in policy scopes (Launch Profile/User Configuration/Policy/Global precedence applies to mounts only; runtime remains policy-controlled).
  • Enterprise location
    • Define templates in the system-wide policy at %PROGRAMDATA%\Turbo\Launcher\policy.json.

Readability and Maintainability

  • Prefer matcher sets with matchAny over complex regex alternation to express OR across app variants (e.g., tool suites like PuTTY). This improves auditability and reduces regex errors.
  • Prefer centralized associations (fileTypes + fileAssociations) for a consistent UX and determinism; declare app support via apps[].capabilities.