Appearance
Policy Schema Reference
Field-by-field reference for application policies, file types, file associations, file policies, and global configuration. See concept pages for behavior details.
What You'll Learn
- The structure of the policy.json file
- Field definitions for apps, file types, and routing
- Global configuration options for runtime and network
- Concepts: Policy Overview
- Authorization & Visibility: Authorization & Visibility
- Matchers & Patterns: Matchers & Patterns
- Modifications & Flags: Modifications & Flags
- Launch Profiles: Launch Profiles
- File Types & Routing: File Types & Routing
- Merging & Precedence: Merging & Precedence
Top-level structure
json
{
"$schema": "https://schemas.turbo.net/launcher-policy.schema.json",
"schemaVersion": 2,
"policyVersion": 1,
"configuration": { ... },
"apps": [ ... ],
"fileTypes": [ ... ],
"fileAssociations": [ ... ],
"files": [ ... ],
"configurationTemplates": [ ... ]
}One document shape serves both platforms. A policy authored for Windows decodes on macOS and vice versa; a key one platform does not apply is accepted and ignored there, never refused. Which reader applies which key is listed in Field ownership by platform.
Top-level fields
Every root key is optional. A missing configuration is an empty configuration; a missing apps is an empty list (and nothing is launchable — see Defaults and behaviors).
$schema(string) — Editor hint pointing at the JSON Schema. Accepted and ignored by every reader.- schemaVersion (integer,
1or2) — The policy-language version the document requires; absent means 1. Must be2when the document usesmatchNoneorcodeDirectoryHash. Every reader refuses a document declaring a version newer than it supports (2 today) and keeps its current policy. Distinct frompolicyVersion. See: Schema versioning and compatibility. - policyVersion (integer) — Optional monotonic deployment counter for rollout/rollback tracking; absent means 0. Not a schema version.
- policySignature (string) — Detached CMS/PKCS#7 signature in base64 for this policy. Proposed — not verified on either platform today.
- signatureCertificateThumbprints (string[]) — Allowed signer certificate thumbprints used to validate policySignature. Accepts 64‑hex (SHA‑256) or 40‑hex (SHA‑1). Proposed — not verified on either platform today.
- configuration templates (
configurationTemplates, array) — Windows-only. Enterprise-defined reusable constraints for environment variables and mounts used by per-user configurations. Accepted and ignored on macOS. See: Configuration Templates. - files (array) — Windows-only file operation rules. Accepted and ignored on macOS.
Schema versioning and compatibility
The policy JSON has two distinct version numbers, both integers on the document itself:
policyVersion (integer, optional)
- Monotonic deployment counter used for rollout, rollback, and telemetry. Absent means 0.
- Interpreted only by policy distribution/orchestration systems and audit tooling.
- Does not describe the shape of the policy or which fields are allowed.
schemaVersion (integer, optional,
1or2)- The policy-language version the document requires. Absent means 1 (a legacy document).
- Describes which constructs the document uses, so a reader can refuse what it cannot apply rather than misread it.
Do not overload policyVersion as a schema version. The $schema URL is an editor hint only; no reader derives a version from it, and the JSON Schema artifact has no version line of its own.
What schemaVersion gates
Most additions to the policy language are safe to ignore: a reader that does not know a key drops it and applies the rest. A field that restricts something is different, and an exclusion is the sharpest case: a client that drops matchNone reads "allow everything except X" as "allow everything, including X" — it authorizes exactly what the author excluded. Ignoring it does not degrade the policy, it inverts it.
Such constructs are gated by the integer schemaVersion:
- A policy using
matchNoneor acodeDirectoryHashmatcher must declare"schemaVersion": 2. - A document that carries either while declaring version 1 — or declaring no version at all — is refused, naming the offending rule. It is never accepted with the construct ignored.
- A document declaring a version newer than the reader supports (2 on the Windows client, the macOS daemon and the macOS launcher) is refused rather than partially applied, and the reader keeps its current policy.
schemaVersionalso picks the defaultpatternTypefor matchers that omit it: regex at version 1, glob at version 2 and above, on every reader. Always statepatternType.
Servers stamp the lowest version a document actually requires, so a policy that uses no version-2 construct still declares version 1 and older clients keep applying it unchanged. Only a policy that uses a gated construct moves to version 2 — and is then refused by any client that predates it.
The JSON Schema is exposed at a stable URL for editor validation: https://schemas.turbo.net/launcher-policy.schema.json.
Unknown keys and unknown values
Every reader — the Windows client, the macOS daemon and the macOS launcher — applies the same rules to a document it decodes:
- Unknown keys are accepted and ignored, at every level, including keys the other platform owns. The Windows client logs at Debug which accepted keys it does not apply. Nothing is refused at document level for a key.
- Unknown matcher
typeorpatternTypevalues decode to a matcher that never matches. The rule fails closed; the document is still applied. A matcher object with notype(for example a nested group) decodes the same way. - Unknown
actionorvisibilityvalues refuse the whole document. They are decision words, and a guessed default would be a decision the author did not make. schemaVersiongreater than 2 refuses the document; the reader keeps its current policy.- Optional fields that are absent take the documented defaults:
enabledtrue,priority500,actionallow,displayName=id, profileactionText=displayName, mountaccessreadWrite, mountid=destination.
Deprecation policy
To minimize breaking changes:
- Fields and enum values are first marked as deprecated in this documentation and release notes (
turboFlags,vmFlags, site anchorproxyRef, the hyphenatedpolicy-assigned). - Deprecated fields remain accepted by every reader; a client may log a warning.
- Removal of a deprecated field, or a behavior change that a reader cannot safely ignore, ships under a new
schemaVersionand is gated the waymatchNoneis.
Identity and uniqueness
apps[].id: Required. Unique within apps[]; stable identifier referenced by fileAssociations.verbs[].appRef. When two enabled app policies have the same priority, ties break by id (alphabetical).
apps[].profiles[].id: Required. Unique within its parent application; compared ordinal, case-insensitive. Stable identifier used for profile-level merges and tie-breaks; not globally unique across apps.
apps[].profiles[].displayName: Optional (defaults to
id). UI text; not used for identity.fileTypes[].id: Required. Unique within fileTypes[]; referenced by fileAssociations[].fileTypeRef.
fileAssociations[].id: Recommended. Unique within fileAssociations[]; stable rule identity and tie‑break key after priority (alphabetical). If missing, fallback to rule displayName.
files[].id: Recommended. Unique within files[]; stable rule identity and tie‑break key after priority (alphabetical). If missing, fallback to rule displayName.
Handler arrays (routing verbs open/edit/print/preview): Handlers are not named. If multiple handlers are eligible:
- First pick any handler with
default: true(within the selected rule). - Else pick from the rule with highest
priority. - If still tied across rules, use rule
idalphabetical (fallback to ruledisplayNamewhen id is missing). - Within a single rule and no explicit default: array order applies.
- First pick any handler with
appRef refers to apps[].id. If no enabled app policy with
action: "allow"matches the target executable, the routing handler is ignored.
Profile Naming Conventions
Use distinct labels for each profile-related concept to avoid confusion in policies and support tickets.
- Launch profiles (
apps[].profiles[]): Treat these as app variants. Useidvalues that describe the action (chrome-incognito,word-readonly) anddisplayNametext that reads well in the context menu (for example, "Run Chrome (Incognito)"). - User configurations (
user-profiles.json→profiles[]): Refer to these as configurations in UI text and documentation to distinguish them from launch profiles. Use stable, kebab-case ids that include the template purpose (user-project-alpha,user-p4-shared) and keepdisplayNameuser-friendly ("Project Alpha Configuration"). - Configuration templates (
configurationTemplates[].idandapps[].configurationTemplates): Name templates after the constraint set they enforce (p4-shared-environment,dlp-reviewed-mounts) and avoid reusing the sameid/displayNamestrings used by launch profiles or user configurations. - In customer-facing text, prefer “launch profile” for context menu variants, “user configuration” for per-user files, and “configuration template” for enterprise-governed constraints.
Application policy (apps[] items)
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Immutable unique identifier for the app policy; unique within apps[]; referenced by fileAssociations actions via appRef; used for tie-break at equal priority (ordinal, case-insensitive). Use stable, URL-safe ids (kebab-case recommended). |
| displayName | string | No (default id) | Human-readable label shown in UI and examples. |
| enabled | boolean | No (default true) | Whether this policy is active. |
| priority | integer | No (default 500) | Higher numbers take precedence in merges; ties break by id. |
| visibility | "visible" or "hidden" | No | Controls UI presence; hidden apps can still be used by routing. The deciding allow rule's value is the one applied. See: Authorization & Visibility. |
| visibilityConstraints | VisibilityConstraints | No | Scopes an allow or modify rule to specific selected sites. A deny applies at every site regardless. See: Sites. |
| targetPath | string | No | Direct executable path shorthand, evaluated only when neither matchAll nor matchAny is populated. Compared as a full path, case-insensitively, after $VAR / ${VAR} / %VAR% expansion. |
| matchAll | Matcher[] | No | Logical AND: all matchers must match. Contains matchers only (no nested groups). See: Matchers & Patterns. |
| matchAny | Matcher[] | No | Logical OR: at least one matcher must match. Contains matchers only. |
| matchNone | Matcher[] | No | Exclusions, evaluated first: the rule applies only if no item matches. Requires schemaVersion 2; a document carrying it under an older declared version is refused, not applied with the exclusion ignored. See: Matchers & Patterns. |
| action | "allow", "deny", or "modify" | No (default allow) | Authorization action. allow permits the launch; deny blocks it and takes precedence over allow when both match; modify enriches an allowed launch without granting it — its modifications and profiles are layered onto the deciding allow, but it can never authorize an app on its own or displace the allow by priority. The same three values are accepted on Windows and macOS; an unknown value refuses the document. See: Merging & Precedence. |
| identityRequirements | string[] | No | Proposed — not enforced on either platform today. Accepted and ignored. Pin identity with publisherCertificate / fileHash / version matchers instead. |
| authorization | Authorization | No | Proposed — not enforced on either platform today. ABAC requirements and approval gating. Accepted and ignored by every reader. |
| modifications | Modifications | No | Structured changes layered onto the launch. See: Modifications below. |
| profiles | Profile[] | No | Additional launch variants. See: Launch Profiles. |
| capabilities | AppCapability[] | No | Per-app declaration of supported file types and verbs. See below. |
| configurationTemplates | string[] | No | Windows-only. Template ids enabling user configurations for this app. See: Configuration Templates. |
| containerColor | string | No | Sandbox border color for this app's windows, RRGGBB or AARRGGBB hex. Applied on macOS (daemon and launcher); accepted and ignored on Windows, which uses runtime.visual.borderColor. |
| sandboxEnabled | boolean | No | Launch through the sandbox (xvm --sandbox). Applied by the macOS launcher; accepted and ignored elsewhere (Windows uses runtime.isolation.remoteSandbox). |
| launcher | LauncherPresentation | No | macOS-launcher-only presentation (title, subtitle, icon, instrumentation) for the items this rule matches. Accepted and ignored by the daemon and on Windows. |
| overlay | OverlayPolicy | No | Windows-only: { "processLevel": true } overlays the app at process level. Accepted and ignored on macOS. |
A rule may carry matchAll, matchAny, or the targetPath shorthand; matchAll and matchAny together on one rule is invalid (the JSON Schema rejects it; the Windows validator warns at version 1 and refuses at version 2, the macOS daemon refuses). Lists are flat — a matcher list contains matchers, not further groups. matchNone is separate from that choice: it may accompany any positive form, but it never supplies the positive side. A rule with no matchAll, matchAny, or targetPath matches nothing on every reader, with or without matchNone, and is refused under schemaVersion 2 as an authoring error. To express "everything except these", pair an explicit ** glob matcher with matchNone.
VisibilityConstraints
| Field | Type | Required | Description |
|---|---|---|---|
| siteRefs | string[] | No | Array of site IDs. App is visible only when the selected site matches one of these. |
Matcher
json
{ "type": "targetPath", "pattern": "C:\\\\**\\\\myapp.exe", "patternType": "glob" }| Field | Type | Required | Description |
|---|---|---|---|
| type | enum | Yes | One vocabulary on every reader: shortcutName, targetPath, arguments, publisherCertificate, fileHash, version, bundleId, teamId, codeDirectoryHash (the last requires schemaVersion 2). A type a platform cannot evaluate never matches there — arguments on macOS; bundleId, teamId, codeDirectoryHash on Windows. An unknown value makes the matcher never match; it does not refuse the document. See: Matchers & Patterns. |
| pattern | string | Yes | Pattern text. |
| patternType | enum | No (state it) | exact, regex, glob, semver. When omitted, every reader uses regex under schemaVersion 1 and glob under 2. semver is meaningful on version matchers only. An unknown value makes the matcher never match. See: Matchers & Patterns. |
| field | enum | No | For publisherCertificate matchers, which certificate field to match: thumbprint, subjectCN, issuerCN, subjectDN, issuerDN. When omitted the pattern is tried against the thumbprint, the Subject CN and the Issuer CN. |
Publisher certificate field targeting
field: "thumbprint"→patternshould be a 64‑hex (SHA‑256) or 40‑hex (SHA‑1) digest. Thumbprints, file hashes and code-directory hashes are always compared exactly and case-insensitively;patternTypeis ignored for them.field: "subjectDN"or"issuerDN"→ anypatternTypeworks on the RFC 4514 string; with regex, anchor onCN=to avoid ambiguity.- All comparisons are case-insensitive.
Authorization (apps[].authorization)
Proposed — not enforced on either platform today
authorization (ABAC requirements and approval gating), identityRequirements, identityAccess, configuration.identity, configuration.trust, configuration.policySource, configuration.security, configuration.dataClassification, and policySignature verification are documented as the intended model. No shipped reader — the Windows client, the macOS daemon, or the macOS launcher — evaluates them. They are accepted and ignored, so a launch they would have blocked is not blocked. Do not rely on them for enforcement.
Augments allow policies with attribute- and context-based constraints, evaluated after an allow policy matches and before launch. All specified requirements must pass; otherwise the launch is denied.
Structure
json
{
"authorization": {
"requirements": {
"userAttributes": [
{ "attribute": "usPersonStatus", "allowedValues": ["verified"] }
],
"contextConstraints": {
"allowedGeos": ["US"],
"requireCompliantHost": true
}
},
"approval": {
"mode": "required",
"workflowRef": "manager-approval-app-launch",
"reuse": {
"policy": "perUserPerApp",
"ttlSeconds": 86400
}
}
}
}Fields
- requirements.userAttributes[]:
attribute(string): key defined inconfiguration.identity.claimsMapping(e.g.,"usPersonStatus")allowedValues(string[]): one or more normalized values
requirements.contextConstraints.allowedGeos(string[]): ISO 3166-1 alpha-2 country codes (e.g., "US")requirements.contextConstraints.requireCompliantHost(boolean): requires compliant host perconfiguration.security.hostAttestation
Semantics
- Evaluated only when an enabled app policy with
action: "allow"matches (matchAll/matchAny). - Deny-on-fail: if any requirement fails (attributes mismatch or host non-compliant under enforce mode), the launch is denied.
- Complements identityRequirements; both may be present.
- When
authorization.approval.modeis set to"required", a successful approval workflow is also required beforeappLaunchis allowed. Approval workflows are defined globally underconfiguration.launch.runtime.approval. - See behavior and examples: Authorization & Visibility.
Authorization Approval (apps[].authorization.approval)
Optional approval gating evaluated after matchers and ABAC requirements. Use this when you want applications to appear in the Applications tab but require an approval workflow before launch or for specific in-app operations.
Fields
mode(string, optional):"none"|"required"|"conditional"."none"(default): no approval gate; behavior matches existing ABAC-only authorization."required": approval is required beforeappLaunchis allowed."conditional": implementation may request approval under certain runtime conditions (for example, elevated risk posture). Semantics are implementation-defined; use when coordinated with platform guidance.
workflowRef(string, optional): referencesconfiguration.launch.runtime.approval.workflows[].id. When set andmodeis not"none", this workflow is used to gateappLaunch. When omitted, the runtime may fall back toconfiguration.launch.runtime.approval.defaults.appLaunchWorkflowRef.reuse(object, optional): Controls when approvals can be reused instead of re-requested.policy(string, required whenreuseis present):"perLaunch"|"perSession"|"perUserPerApp".ttlSeconds(integer, optional): time-to-live in seconds for an approval within the chosen reuse boundary. When omitted, the runtime default applies.
operations(array, optional): optional per-operation approval rules for in-app actions.operations[].operationId(string, required): logical operation identifier (for example,"appOperation.crm.exportSensitiveData").operations[].workflowRef(string, required): workflow id to use for this operation. Referencesconfiguration.launch.runtime.approval.workflows[].id.operations[].reuse(object, optional): same shape asauthorization.approval.reuse.
Notes
- Use
mode: "required"onauthorization.approvalto make discovered applications visible but require approval before launch into the Secure Sandbox runtime. - Operation identifiers under
authorization.approval.operations[]provide a flexible contract for app-specific actions. Apps or external processors raise events with the configuredoperationIdvalues, and the policy engine uses the associated workflows to gate those actions.
Modifications
Changes layered onto a launch that an allow rule has permitted. One shape on both platforms: each key is applied by the platform that owns it and accepted-ignored by the other (see Field ownership by platform). The same keys are valid on a launch profile.
json
{
"arguments": { "prepend": "--safe-mode", "append": "--incognito" },
"runtime": { "isolation": { "remoteSandbox": true } },
"mounts": [
{ "id": "Desktop", "source": "@DESKTOP@", "destination": "@DESKTOP@", "access": "readWrite" }
],
"network": { "capabilities": { "egressDefaultAction": "deny" } },
"files": { "contexts": [ { "id": "documents", "root": "@DOCUMENTS@", "access": "readWrite" } ] },
"environment": { "P4PORT": "ssl:p4:1666" },
"ipc": { "machServices": { "virtualizePreferences": true } },
"childProcesses": { "inject": "auto", "onUninjectable": "audit" },
"agents": { "claudeCode": { "manageSettings": true, "permissionMode": "bypassPermissions" } }
}| Field | Type | Applied by | Description |
|---|---|---|---|
| arguments | Arguments | Windows | Command-line edits. replace overrides prepend/append. Scope precedence: Launch Profile > Policy > Global. |
| turboFlags | string[] | Windows | Deprecated. Raw Turbo flags. Use the structured keys instead. |
| runtime | Runtime | Windows (isolation, clipboard, visual); macOS daemon (files, ipc, childProcesses, agents, audit) | Structured runtime settings. Replaces raw flags. |
| mounts | StructuredMount[] | macOS daemon; Windows (--mount) | Host paths exposed inside the runtime. See StructuredMount. |
| network | NetworkOverrides | macOS daemon (per-connection); Windows (site-based proxy selection) | Capability and proxy-routing overrides. See: Networking. |
| files | FilesConfig | macOS daemon (enforced); macOS launcher (Files tab) | Storage contexts and per-path isolation. See FilesConfig. |
| environment | object (string → string) | macOS daemon | Environment variables set for the launched process. |
| ipc | IpcConfig | macOS daemon | Host IPC reachable from the process: automation.enabled, machServices.denied[], machServices.virtualizePreferences. |
| childProcesses | ChildProcessesConfig | macOS daemon | inject: off | auto | required; onUninjectable: audit | deny; scriptFallbackGate: decline | enforce. |
| agents | AgentsConfig | macOS daemon | Turbo-managed settings for coding agents in the session (claudeCode, codex). |
| identityAccess | IdentityAccessEntry[] | — | Proposed — not enforced on either platform today. |
Runtime
| Field | Type | Applied by | Description |
|---|---|---|---|
| isolation | Isolation | Windows | Session isolation settings (remoteSandbox → --sandbox). macOS uses apps[].sandboxEnabled. |
| clipboard | Clipboard | Windows | Clipboard size and direction settings. |
| visual | Visual | Windows | borderColor → --skin-border-color. macOS uses apps[].containerColor. |
| files | FilesConfig | macOS daemon, macOS launcher | Storage contexts and isolation (see below). |
| ipc, childProcesses, agents | as above | macOS daemon | Same shapes as under modifications; here they set the global default. |
| audit | Audit | macOS daemon | settings (level, redaction, integrity, failurePolicy, export, rotation). Windows process-launch audit lives under configuration.audit.processLaunches. |
| composition, devices, extensions, dataMotion, approval | — | — | Accepted on every reader; approval is proposed (not enforced). |
Clipboard
| Field | Type | Required | Description |
|---|---|---|---|
| mode | string | No | Clipboard direction. Values (case-insensitive): Bidirectional, InboundOnly, OutboundOnly, Isolated. Synthesized as --clipboard-mode. |
| size | number | No | Maximum clipboard size in bytes for both directions. Set to 0 for unlimited. Synthesized as --clipboard-size. |
| sizeInbound | number | No | Maximum inbound clipboard size in bytes (host to session). Overrides size for inbound. Synthesized as --clipboard-size-inbound. |
| sizeOutbound | number | No | Maximum outbound clipboard size in bytes (session to host). Overrides size for outbound. Synthesized as --clipboard-size-outbound. |
| imageMaxPixels | number | No | Maximum clipboard image size in pixels (width × height). Set to 0 for unlimited. Synthesized as --clipboard-image-max-pixels. |
Isolation
| Field | Type | Required | Description |
|---|---|---|---|
| remoteSandbox | boolean | No | Run in a remote sandbox. Synthesized as --sandbox. |
Visual
| Field | Type | Required | Description |
|---|---|---|---|
| borderColor | string | No | Border color for testing/authoring. Format: "#AARRGGBB" (alpha-ARGB) or named color. Example: "#80008200". Synthesized as --skin-border-color. |
Arguments
| Field | Type | Required | Description |
|---|---|---|---|
| prepend | string | No | Added before base args. |
| append | string | No | Added after base args. |
| replace | string | No | Replaces entire arg string. |
StructuredMount
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | No (default destination) | Identity key used for merge and tie-breaks. |
| source | string | Yes | Host path; supports well-known tokens (@DESKTOP@, …) and platform environment variables. |
| destination | string | Yes | Path inside the runtime. |
| access | "readOnly" | "readWrite" | No (default readWrite) | Mount access. |
| createIfMissing | boolean | No | Create the mount even when the source does not exist yet. |
| siteRefs | string[] | No | Sites this mount applies to; absent means every site. Windows-evaluated; the macOS daemon accepts and ignores it. |
FilesConfig (runtime.files, modifications.files, profiles[].files)
| Field | Type | Required | Description |
|---|---|---|---|
| defaultContextId | string | No | Context the Files tab opens by default; references contexts[].id. |
| contexts | StorageContext[] | No | Named, rooted filesystems inside the sandbox: id, displayName, scope (host | sandbox, default sandbox), root, access, classification[], importExport, containerRef. |
| isolation | IsolationManifest | No | Per-path virtualization: defaultMode (merge | writeCopy | full | inherit) and rules[] of { path, mode, readOnly, hidden, noSync, scratch, roaming, locked }. Enforced by the macOS daemon. |
Launch Profile
json
{
"id": "profile-id",
"displayName": "Chrome (Incognito)",
"actionText": "Run Chrome (Incognito)",
"arguments": { "append": "--incognito" },
"runtime": { "clipboard": { "size": 200 } },
"mounts": [ { "id": "DiagDump", "source": "%TEMP%\\MyApp\\Diag", "destination": "P:\\Diag", "access": "readWrite" } ],
"postLaunchAction": { "type": "OpenFolder", "path": "%LOCALAPPDATA%\\Turbo\\Containers\\sandboxes\\{ContainerId}\\logs" }
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Unique within this app (ordinal, case-insensitive); identity for profile conflict resolution. |
| displayName | string | No (default id) | Profile name. |
| actionText | string | No (default displayName) | UI text for the context menu action. |
| siteRefs | string[] | No | Sites the profile is offered at. Windows-evaluated; accepted and ignored on macOS. |
| arguments, turboFlags, runtime, mounts, network, files, environment, ipc, childProcesses, agents | as in Modifications | No | Profile-scope modifications, same shapes and same platform ownership as modifications. |
| postLaunchAction | PostLaunchAction | No | Windows-only action after launch (OpenFolder). Accepted and ignored on macOS. |
PostLaunchAction
| Field | Type | Required | Description |
|---|---|---|---|
| type | enum | Yes | "OpenFolder". |
| path | string | Yes | Path; supports {ContainerId} and Windows env vars (e.g., %LOCALAPPDATA%). |
AppCapability (apps[].capabilities[])
json
{
"fileTypeRef": "pdf",
"verbs": {
"open": { "arguments": "\"%1\"" },
"print": { "arguments": "/p \"%1\"" },
"extract": { "arguments": "/c tar -xf \"%1\" -C \"%~dpn1\"" }
}
}| Field | Type | Required | Description |
|---|---|---|---|
| fileTypeRef | string | Yes | References fileTypes[].id. |
| verbs | Dictionary<string, CapabilityVerbOptions> | No | Dictionary mapping verb names to invocation details. Supports standard verbs (open, edit, print) and custom verbs (e.g., extract). |
CapabilityVerbOptions
| Field | Type | Required | Description |
|---|---|---|---|
| arguments | string | No | Command string; supports variable substitution (%1, %~dp1, %~n1, %~dpn1). |
| vmFlags | string[] | No | Deprecated (Windows-only). Additional raw flags for this verb. Use runtime instead. |
| runtime | Runtime | No | Structured runtime settings for this verb. |
File Types (fileTypes[] items)
Central registry defining what a file “is” and how to match it.
json
{
"id": "pdf",
"displayName": "PDF",
"match": { "extensions": ["pdf"] },
"defaultPreviewProvider": "builtInPdf"
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Immutable unique id; kebab-case recommended. |
| displayName | string | Yes | Human-readable label. |
| match | FileMatch | Yes | Single match definition for the type. Case-insensitive extension match. |
| defaultPreviewProvider | enum | No | Default preview provider: builtInPdf, builtInImage, builtInText. |
FileMatch
| Field | Type | Required | Description |
|---|---|---|---|
| extensions | string[] | Yes | One or more extensions (no leading dot), matched case-insensitively. |
File Associations (fileAssociations[] items)
Central UX for file type actions, including preview, open, edit, print, and custom verbs.
json
{
"id": "pdf-routing",
"displayName": "PDF",
"enabled": true,
"priority": 250,
"fileTypeRef": "pdf",
"actions": [
{ "verb": "preview", "displayName": "Preview", "provider": "builtInPdf", "default": true },
{ "verb": "open", "displayName": "Open", "appRef": "example-app", "showInContextMenu": true }
]
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Stable rule identity; unique within fileAssociations[]; used for tie‑break after priority. |
| displayName | string | No | Human-readable label for diagnostics. |
| enabled | boolean | Yes | Whether the rule is active. |
| priority | number | Yes | Higher numbers first; ties break by rule id (alphabetical) or rule displayName when id is missing. |
| fileTypeRef | string | Yes | References fileTypes[].id. |
| actions | FileAssociationAction[] | Yes | Flat array of actions for this file type. |
FileAssociationAction
json
{ "verb": "open", "displayName": "Open", "appRef": "ms-word", "default": true, "showInContextMenu": true, "showInOpenWith": true }| Field | Type | Required | Description |
|---|---|---|---|
| verb | string | Yes | Verb name (e.g., preview, open, edit, print, extract). Must match a verb in the app's capabilities (or be preview for built-in preview). |
| displayName | string | Yes | Display name for menu labels. |
| appRef | string | No* | Id of an application policy (apps[].id) to launch. Required for non-preview actions. |
| provider | string | No* | Built-in preview provider (builtInPdf, builtInImage, builtInText). Required for preview verb only. |
| default | boolean | No | Marks as default action for double-click. |
| showInContextMenu | boolean | No | Show in main context menu (default: true). |
| showInOpenWith | boolean | No | Include in Open With submenu (default: true). |
| match | FileMatch | No | Narrows this action within the file type (e.g., split doc vs docx). |
*Either appRef or provider is required depending on the verb: use provider for preview verb, appRef for all other verbs.
Security gating
- An action references an app via
appRef. There must be an enabled app policy withaction: "allow"that matches the executable; otherwise the action is ignored. See: File Types & Routing.
Custom verbs
- Actions support any verb name defined in app capabilities (not limited to
open,edit,print). - Context menu actions are built dynamically from available actions at runtime.
File policies (files[] items)
Windows-only. The Windows Files tab evaluates these rules; the macOS daemon and launcher accept and ignore files[] (on macOS, movement in and out of a storage context is governed by the context's importExport).
Rule
json
{
"id": "deny-import-executables",
"displayName": "Block importing executables",
"enabled": true,
"priority": 1000,
"operation": "import",
"fileTypeRef": "executable",
"action": "deny"
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | No (recommended) | Stable identifier; unique within files[]; used for tie‑break after priority (alphabetical). If absent, fallback to displayName. |
| displayName | string | Yes | Human‑readable rule label; must be unique in files[]; used as tie‑break only when id is missing. |
| enabled | boolean | Yes | Whether the rule is active. |
| priority | number | Yes | Higher numbers first; ties break by rule id (alphabetical) or rule displayName when id is missing. |
| operation | enum | Yes | list, import, export, open, delete. Defaults: list Allow, import Allow, export Deny, open Allow, delete Allow. |
| fileTypeRef | string | Yes | References fileTypes[].id. |
| action | enum | Yes | "allow" or "deny". |
List operation
- Controls visibility in the Files tab (file browser) listing; this operation does not execute a verb.
- action: "allow" shows matching items; action: "deny" hides matching items from the listing.
- Conflicts resolve by rule priority (descending), then rule id alphabetical (fallback to displayName when id is missing), consistent with other file operations.
Configuration Templates (top-level)
Windows-only. Templates constrain per-user configurations, which exist only on the Windows client; macOS readers accept and ignore configurationTemplates and apps[].configurationTemplates.
Fields
- configurationTemplates: Template[]
Template
- id (string, required)
- description (string, optional)
- constraints (object, optional)
- environmentVariables: EnvVarConstraint[]
- key (string, required)
- required (boolean, optional)
- validationPattern (string, optional)
- patternType ("regex" | "exact", optional)
- mounts (object, optional)
- rules[] (array)
- description (string, optional)
- allowedSourcePatterns: PatternSpec[]
- allowedDestinationPatterns: PatternSpec[]
- allowedOptions: ("read-write"|"read-only")[]
- rules[] (array)
- environmentVariables: EnvVarConstraint[]
PatternSpec
- pattern (string)
- patternType ("glob" | "regex")
Notes
- Use glob for Windows path patterns; regex for value validation.
- Environment variables in patterns are resolved at validation time.
- Path-oriented matches are case-insensitive by default.
- Link apps to templates via apps[].configurationTemplates (string[]).
Global configuration
json
{
"configuration": {
"launch": {
"runtime": {
"isolation": { "remoteSandbox": true }
},
"mounts": [
{ "id": "Desktop", "source": "@DESKTOP@", "destination": "@DESKTOP@", "access": "readWrite" },
{ "id": "Documents", "source": "@DOCUMENTS@", "destination": "@DOCUMENTS@", "access": "readWrite" }
]
},
"network": {
"capabilities": {
"outboundAllowed": true,
"dnsAllowed": true,
"egressDefaultAction": "allow"
}
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
configuration.discovery | DiscoveryConfig | No | Application discovery providers executed at Launcher startup. |
configuration.policyUpdateIntervalMinutes | integer (1-60) | No | Windows-only. Minutes between the Sandbox Manager's policy update checks. Omit to leave clients on their built-in 5-minute cadence. Values outside 1-60 are rejected when the policy is published. See: Sandbox Manager policy sync. |
configuration.sites | SitesConfig | No | Definition of user-selectable sites (Windows client and macOS launcher; the daemon has no site concept). See: Sites. |
configuration.launch.runtime | Runtime | No | Global runtime settings applied to all launches (replaces raw flags). See: Modifications → Runtime for per-key platform ownership. |
configuration.launch.mounts | StructuredMount[] | No | Structured mounts applied globally. |
configuration.launch.flags | string[] | No | Deprecated, Windows-only. Raw Turbo flags applied to every launch. |
configuration.launch.startMenuIntegration.mode | "disabled" | "takeover" | No | Windows-only Start Menu integration. Default disabled. |
configuration.network | NetworkConfig | No | Global networking: capabilities (egress/inbound/DNS, protocols/ports, DNS servers/suffixes), proxies catalog, and proxy routing. See Network below for per-platform application. |
configuration.chat.enabled | boolean | No | Launcher AI chat surface (Windows client and macOS launcher). The server's workspace chat setting must also enable it. |
configuration.overlay.mode | "off" | "observe" | "nag" | "enforce" | No | Windows-only overlay posture. Default off. |
configuration.audit.processLaunches | object | No | Windows-only process-launch audit: enabled, includeCommandLine, retentionDays, maxStorageMb. The macOS daemon's audit settings live under configuration.launch.runtime.audit.settings; neither platform reads the other's key. |
configuration.trust.* | TrustConfig | No | Proposed — not enforced on either platform today. revocationMode, revocationFallback, requireTimestamp, allowedSigners, allowedIssuers. |
configuration.policySource.* | PolicySource | No | Proposed — not enforced on either platform today. url, expectedSha256, etagTracking, fallbackToLkgOnFailure. Policy delivery is described per platform in Deployment. |
configuration.identity, configuration.security, configuration.dataClassification | objects | No | Proposed — not enforced on either platform today. See the sections below. |
Sites (configuration.sites)
Structure
json
{
"configuration": {
"sites": {
"selectionMode": "auto",
"defaultSelectionStrategy": "lowestLatency",
"profiles": [
{
"id": "san-jose",
"displayName": "San Jose",
"anchor": { "type": "proxy", "proxyRef": "proxy-us" }
},
{
"id": "shanghai",
"displayName": "Shanghai",
"anchor": { "type": "proxy", "proxyRef": "proxy-cn" }
}
]
}
}
}Fields
defaultSiteId(string, optional): Site id to use when the selection mode cannot determine the active site. Must match an entry inprofiles[].id.selectionMode(enum, optional):"user"|"device"|"policyAssigned"|"auto". Controls how the active site is selected. The hyphenated"policy-assigned"is a legacy spelling that readers still accept.defaultSelectionStrategy(string, optional): Strategy used whenselectionMode: "auto". Current value:"lowestLatency".profiles[](array, required when Sites are used): List of site profiles available to select.profiles[].id(string, required): Stable identifier; referenced bysiteRefs.profiles[].displayName(string, required): UI label for the site.profiles[].anchor(object, optional): Anchor used by auto-selection.type(enum, required):"proxy".proxyRef(string, optional, deprecated): Single proxy reference. Referencesconfiguration.network.proxies[].id. Deprecated; useproxyRefsfor new configurations.proxyRefs(string[], optional): Multiple proxy references. Each entry referencesconfiguration.network.proxies[].id.
*Exactly one of proxyRef or proxyRefs must be specified when proxy anchor is present.
Semantics
- When
selectionModeis"auto", the client evaluates anchors on each profile and selects a site according todefaultSelectionStrategy. - With
defaultSelectionStrategy: "lowestLatency", the client performs a TCP connect test to the referenced proxy endpoints and selects the site with the lowest measured latency. Profiles without anchors (or with unreachable anchors) are ignored or treated as high latency. - If no active site can be determined, the Launcher behaves secure-by-default: policy entries are ineligible until a site is selected.
See also
- Sites — behavior, examples, and migration notes
- Networking — proxy catalog referenced by
anchor.proxyRef
Network (global) and overrides (app/profile)
Networking controls the runtime network posture and proxy routing. The shape is the same on both platforms; what each platform applies differs:
- macOS daemon — enforces
capabilitiesand evaluatesproxyRouting[].matchper connection, applyingproxy/direct/deny(withfailoverandproxyCandidates). It has no site concept and accepts-ignoressiteRefs. - Windows client — selects a proxy per site from
proxyRouting[].siteRefsandaction.proxyRef; it accepts-ignoresmatchandcapabilities, and treatsdirectanddenyas "no proxy" (denywith a warning, since Windows has no per-connection enforcement).
A rule may carry match (absent = every destination), siteRefs (absent = every site), or both.
Locations
- Global:
configuration.network(NetworkConfig) - Per-app:
apps[].modifications.network(NetworkOverrides) - Per-launch profile:
apps[].profiles[].network(NetworkOverrides)
Structure (global)
json
{
"configuration": {
"network": {
"capabilities": {
"outboundAllowed": true,
"inboundAllowed": false,
"dnsAllowed": true,
"protocols": ["tcp","udp"],
"ports": { "allow": ["80","443","10000-10100"], "deny": ["25"] },
"dnsServers": ["1.1.1.1","2606:4700:4700::1111"],
"dnsSearchSuffixes": ["corp.local"],
"egressDefaultAction": "deny"
},
"proxies": [
{
"id": "corp-proxy",
"type": "https",
"url": "https://proxy.corp.local:8443",
"tls": { "verify": true }
}
],
"proxyRouting": [
{
"id": "rfc1918-direct",
"enabled": true,
"priority": 900,
"match": { "cidrs": ["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"] },
"action": { "type": "direct" }
},
{
"id": "internet-via-proxy",
"enabled": true,
"priority": 800,
"match": { "hosts": [ { "pattern": "*", "patternType": "glob" } ], "protocol": "tcp" },
"action": { "type": "proxy", "proxyRef": "corp-proxy", "failover": "deny" }
},
{
"id": "site-us",
"siteRefs": ["san-jose"],
"action": { "type": "proxy", "proxyRef": "corp-proxy" }
}
]
}
}
}ProxyRoutingRule
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Rule identity; tie-break after priority. |
| enabled | boolean | No (default true) | |
| priority | integer | No (default 500) | Higher wins. |
| siteRefs | string[] | No | Sites the rule applies at; absent means every site. Windows-evaluated. |
| match | NetworkMatch | No | Destination selector (hosts, cidrs, ipRanges, ports, protocol); absent means every destination. macOS-evaluated. |
| action.type | "proxy" | "direct" | "deny" | Yes | Windows treats direct and deny as no proxy. |
| action.proxyRef | string | When type is proxy | References proxies[].id. |
| action.failover | "direct" | "deny" | No | macOS: applied when the proxy endpoint is unreachable; absent means the connection fails. |
| action.proxyCandidates | string[] | No | macOS: approved alternatives to proxyRef; health may choose only within this set. |
Proxy
| Field | Type | Required | Description |
|---|---|---|---|
| id, type, url | string | Yes | type: http, https, socks5. |
| credentialsRef, bypassHosts, connectTimeoutMs | — | No | Opaque credential reference; bypass patterns; connect timeout. |
| tls.verify, tls.caBundleRef, tls.skipVerify | — | No | TLS to the proxy. tls.skipVerify and tlsSkipVerify are the same setting. |
| useTls, tlsSkipVerify, resolveViaProxy | boolean | No | SOCKS5-over-TLS; skip verification; whether the proxy resolves hostnames (Windows emits --disable-proxy-resolve-via-proxy when false). |
Overrides (app/profile)
- apps[].modifications.network and apps[].profiles[].network support:
- capabilities (same shape as global)
- proxyRouting (rules only; proxies are defined globally and referenced via proxyRef)
Selection and precedence (summary)
- Scope precedence: Launch Profile > Policy > Global
- Proxy routing: Rules are additive across scopes; for a connection, choose the matching rule with highest priority (desc), then rule id alphabetical. Deny acts immediately.
- Capabilities:
- Booleans last-wins by scope (e.g., outboundAllowed).
- Arrays (protocols, dnsServers, dnsSearchSuffixes): last-wins replacement by scope.
- ports.allow/deny: within a scope, deny overrides allow; across scopes, last-wins replacement of the entire ports object.
See details:
- Networking
- Matchers & Patterns: Network destination matching
- Merging & Precedence: Networking precedence and routing selection
- Security Best Practices: Network hardening and proxy pinning
Security Posture (configuration.security)
Proposed — not enforced on either platform today
configuration.security, configuration.dataClassification, configuration.trust, configuration.policySource and configuration.identity are accepted and ignored by every shipped reader. The fields below describe the intended model.
Centralizes cryptographic requirements and host integrity validation for regulated environments.
json
{
"configuration": {
"security": {
"cryptography": {
"fipsMode": "enforced",
"keyManagement": {
"integrationMode": "externalKms",
"kmsProviderConfigRef": "platform-kms-aws-govcloud",
"customerManagedKeyRef": "key-id-12345"
}
},
"hostAttestation": {
"mode": "enforce",
"providerConfigRef": "platform-attestation-crowdstrike-zta",
"requirements": {
"requireManagedDevice": true,
"minimumComplianceScore": 75,
"requireActiveThreatProtection": true
},
"onFailure": "denyAccess"
}
}
}
}Cryptography (configuration.security.cryptography)
| Field | Type | Required | Description |
|---|---|---|---|
| fipsMode | enum | No | FIPS 140-2/140-3 enforcement: "disabled" | "enabled" | "enforced". Default: "disabled". |
| keyManagement.integrationMode | enum | No | Key management integration: "none" | "platform" | "externalKms". Default: "none". |
| keyManagement.kmsProviderConfigRef | string | No | Reference to external KMS provider configuration. Required when integrationMode is "externalKms". |
| keyManagement.customerManagedKeyRef | string | No | Reference to customer-managed encryption key in the KMS. |
FIPS Mode Semantics:
disabled: No FIPS requirement; system default cryptographic providers are used.enabled: Prefer FIPS-validated modules when available; warn if unavailable.enforced: Require FIPS-validated modules; fail operations if unavailable. Required for CMMC Level 2+ and ITAR.
Host Attestation (configuration.security.hostAttestation)
| Field | Type | Required | Description |
|---|---|---|---|
| mode | enum | No | Attestation enforcement: "disabled" | "audit" | "enforce". Default: "disabled". |
| providerConfigRef | string | No | Reference to attestation provider configuration (e.g., CrowdStrike ZTA, Microsoft Intune). |
| requirements.requireManagedDevice | boolean | No | Require device to be enterprise-managed. Default: false. |
| requirements.minimumComplianceScore | integer | No | Minimum device compliance score (0–100). Default: 0. |
| requirements.requireActiveThreatProtection | boolean | No | Require active endpoint protection. Default: false. |
| onFailure | enum | No | Behavior when attestation fails: "denyAccess" | "notify" | "auditOnly". Default: "auditOnly". |
Host Attestation Mode Semantics:
disabled: No host posture checking.audit: Evaluate posture and log results; do not enforce.enforce: Evaluate posture; applyonFailureaction when requirements are not met.
Host attestation integrates with ABAC via apps[].authorization.requirements.contextConstraints.requireCompliantHost. See: Authorization & Visibility.
Data Classification (configuration.dataClassification)
Integrates classification providers and maps external labels to normalized values for policy authoring and runtime DLP.
json
{
"configuration": {
"dataClassification": {
"onClassificationFailure": "deny",
"onUnknownClassification": "deny",
"providers": [
{
"id": "corp-purview",
"type": "purview",
"capabilities": ["document", "clipboard", "window"],
"confidenceThreshold": 0.8,
"cacheTtlSeconds": 30,
"connection": { /* provider-specific auth/endpoint details */ }
}
],
"mappings": [
{
"providerId": "corp-purview",
"externalLabelId": "11111111-2222-3333-4444-555555555555",
"normalized": ["CUI", "CUI//SP-CTI"]
}
],
"normalizedVocabulary": ["ITAR", "CUI", "CUI//SP-CTI", "CUI//SP-EXPT", "CUI//SP-PRVCY", "EAR", "EAR99"]
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
| onClassificationFailure | enum | No | Behavior when providers are unreachable: "deny" | "allow" | "auditOnly". Default: "deny". |
| onUnknownClassification | enum | No | Behavior when content has no classification: "deny" | "inherit" | "allow". Default: "inherit". |
| providers | Provider[] | Yes | Classification provider configurations. |
| providers[].id | string | Yes | Stable identifier; referenced by mappings[].providerId. |
| providers[].type | enum | Yes | Provider type: "purview" | "digitalGuardian" | "titus" | "custom". |
| providers[].capabilities | string[] | No | Supported classification targets: "document", "clipboard", "window". |
| providers[].confidenceThreshold | number | No | Minimum confidence (0.0–1.0) for classification to apply. Default: 0.8. |
| providers[].cacheTtlSeconds | integer | No | Cache duration for classification results. Default: 30. |
| providers[].connection | object | No | Provider-specific authentication and endpoint configuration. |
| mappings | Mapping[] | Yes | Maps provider labels to normalized vocabulary. |
| mappings[].providerId | string | Yes | References providers[].id. |
| mappings[].externalLabelId | string | Yes | Provider-specific label identifier (e.g., Purview label GUID). |
| mappings[].normalized | string[] | Yes | Normalized classification values from normalizedVocabulary. |
| normalizedVocabulary | string[] | No | Defines allowed normalized values. See: Normalized Classification Vocabulary. |
Normalized Classification Vocabulary
The normalizedVocabulary defines the set of classification labels that can be used in policy rules. Labels follow standard marking formats:
CUI (Controlled Unclassified Information)
Per NARA CUI Registry and 32 CFR Part 2002:
| Label | Description |
|---|---|
CUI | CUI Basic — default handling requirements |
CUI//SP-CTI | CUI Specified — Controlled Technical Information (DFARS 252.204-7012) |
CUI//SP-EXPT | CUI Specified — Export Controlled (EAR/ITAR related but CUI-marked) |
CUI//SP-PRVCY | CUI Specified — Privacy Act information |
CUI//SP-SBU | CUI Specified — Sensitive But Unclassified (legacy; prefer specific categories) |
Export Control
| Label | Description |
|---|---|
ITAR | International Traffic in Arms Regulations (22 CFR 120-130) |
EAR | Export Administration Regulations (15 CFR 730-774) |
EAR99 | EAR items not on Commerce Control List |
Format Rules
- Use double-slash (
//) to separate CUI from specified categories per NARA CUI Marking Handbook. - Use hyphen (
-) within category abbreviations (e.g.,SP-CTI). - Labels are case-sensitive in policy; use uppercase as shown.
- Multiple labels can apply to the same content; use arrays in
mappings[].normalized.
Extending the Vocabulary Organizations may extend normalizedVocabulary with custom labels for internal classification schemes. Custom labels should:
- Use a prefix to avoid collision (e.g.,
ACME-INTERNAL,ACME-RESTRICTED) - Be documented in organizational policy
- Map to provider labels via
mappings[]
Data Motion (runtime) — classification matcher
rules[].match.classifications
json
{
"classifications": {
"normalized": ["CUI", "CUI//SP-CTI", "ITAR"],
"provider": { "name": "corp-purview", "labels": ["1111…"], "match": "any" },
"state": "known" // known | unknown (optional)
}
}Semantics
- Use normalized enumerations for portable policies. Optionally constrain against provider labels.
- Values inside a group are OR; different matcher groups (e.g., mimeTypes AND classifications) are AND.
- If
configuration.dataClassification.enabled: false, this matcher is non-applicable and other matchers/defaultAction decide.
Screen capture/share watermark extensions
settings.screenCapture.watermark (mirrored in settings.screenShare.watermark)
- text (string): Template with variables and filters. Variables: Organization, User.UPN, User.DisplayName, Device.Hostname, Timestamp.UTC, Timestamp.Local, Classification.
- style (enum): center | topLeft | bottomRight | diagonalRepeating. If set, overrides legacy position.
- persistent (boolean): When true, applies consistently to captures/streams.
- variablesAllowlist (string[], optional): Restrict which variables may render.
- redactionDefaults (object, optional):
Example
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",
"variablesAllowlist": ["Organization","User.UPN","Timestamp.UTC"],
"redactionDefaults": { "pii": "hash", "hashAlgorithm": "sha256", "salt": "env:PII_SALT" }
}
}
}
}Audit redaction extensions
settings.audit
json
{
"settings": {
"audit": {
"logDecisions": true,
"sampleRate": 1.0,
"redaction": {
"pii": "hash", // mask | hash | drop | none
"variablesAllowlist": ["Classification"],
"hashAlgorithm": "sha256",
"salt": "env:PII_SALT"
}
}
}
}Audit event extension fields
- classification: { state, normalized[], provider: { name, labels[] }, confidence }
- watermarkTemplateUsed: boolean
- userIdentifiers: { upn: string | null } — value redacted per settings.audit.redaction
Audit (runtime) — failure policy and export extensions
The Audit settings under configuration.launch.runtime.audit.settings have been extended for CMMC alignment:
- failurePolicy.onFailure: continue | degrade | block (new value: block = fail closed when auditing cannot be guaranteed)
- failurePolicy.requireHealthyFor: string[]; supports token "all" to gate all sensitive operations
- export.mode: platform | siemForwarding | localOnly (added values)
- export.deliveryGuarantee: bestEffort | atLeastOnceConfirmed (new)
- export.complianceMetadata.retentionPolicyRef: string (new)
See semantics and examples: Audit Trails — integrity failure policy and export
Failure Semantics
Most rows in this matrix belong to the proposed sections above (classification, host attestation, approval, policy signature, trust); only the audit failurePolicy row is enforced today, by the macOS daemon. Multiple policy features include failure handling. This section clarifies the scope and interaction of each failure-related field.
Failure Mode Decision Matrix
| Failure Type | Field Path | Values | Scope | Default | CMMC Control |
|---|---|---|---|---|---|
| Classification provider unreachable | dataClassification.onClassificationFailure | deny | allow | auditOnly | Data motion classification checks | deny | SC-7, AC-4 |
| Content has no/unknown classification | dataClassification.onUnknownClassification | deny | inherit | allow | Data motion classification checks | inherit | AC-4 |
| Host attestation fails | security.hostAttestation.onFailure | denyAccess | notify | auditOnly | App launch (ABAC context) | auditOnly | AC-3, IA-3 |
| Audit pipeline unhealthy | audit.settings.failurePolicy.onFailure | block | degrade | continue | All audited operations | degrade | AU-5 |
| External processor unreachable | integrations.processors[].limits.offlinePolicy | deny | allow | skipProcessor | Data motion pipeline step | deny | SC-7 |
| Pipeline step fails | dataMotion.rules[].action.onProcessorFailure | deny | allow | skipStep | Data motion pipeline | deny | AC-4 |
| Policy signature verification fails | policySource.fallbackToLkgOnFailure | true | false | Policy load | true | CM-3 |
| Code signing revocation check fails | trust.revocationFallback | fail-closed | allow-cache-only | App launch (identity) | fail-closed | IA-5 |
Failure Handling Recommendations by Environment
CMMC Level 2 / ITAR:
json
{
"dataClassification": {
"onClassificationFailure": "deny",
"onUnknownClassification": "deny"
},
"security": {
"hostAttestation": { "mode": "enforce", "onFailure": "denyAccess" }
},
"audit": {
"settings": {
"failurePolicy": { "onFailure": "block", "requireHealthyFor": ["all"] }
}
},
"trust": {
"revocationMode": "online",
"revocationFallback": "fail-closed"
}
}Standard Enterprise:
json
{
"dataClassification": {
"onClassificationFailure": "auditOnly",
"onUnknownClassification": "inherit"
},
"security": {
"hostAttestation": { "mode": "audit", "onFailure": "auditOnly" }
},
"audit": {
"settings": {
"failurePolicy": { "onFailure": "degrade", "requireHealthyFor": ["screenShare"] }
}
},
"trust": {
"revocationMode": "online",
"revocationFallback": "allow-cache-only"
}
}Interaction Between Failure Modes
Classification + Data Motion: When
onClassificationFailure: "deny", data motion rules that match onclassificationswill deny if the provider cannot classify. WhenonUnknownClassification: "deny", unclassified content is denied regardless of other rule matches.Host Attestation + ABAC: When
hostAttestation.mode: "enforce"and a rule specifiesrequireCompliantHost: true, launch is denied if attestation fails andonFailure: "denyAccess".Audit + Operations: When
failurePolicy.onFailure: "block", operations listed inrequireHealthyForare blocked until the audit pipeline recovers. Use["all"]to block all sensitive operations.Processor + Pipeline: Per-processor
offlinePolicyapplies first. If the processor is reachable but returns an error,onProcessorFailureat the pipeline level applies.
Defaults and behaviors
- Field defaults:
enabledtrue,priority500,actionallow,displayName=id, profileactionText=displayName, mountaccessreadWrite,schemaVersion1,policyVersion0. An omittedpatternTypeis regex atschemaVersion1 and glob at 2. - Allowlist model: Only apps with at least one matching enabled app policy (
action: "allow") can launch. Hidden apps are excluded from Applications UI but can be used by routing. - Empty policy: a document with no
apps(or an empty list) authorizes nothing on every platform. What happens when no policy is delivered at all differs by platform — Windows falls back to an embedded allow-all default document, macOS to deny-all — and is described in Merging & Precedence → Policy sources and delivery. - Explicit deny precedence: If any matching enabled policy has
action: "deny", the app is not authorized and is not visible or eligible for routing. See: Merging & Precedence. - Merge rules: Scope precedence Launch Profile > Policy > Global. See: Merging & Precedence.
- Paths: Prefer glob for Windows paths; escape backslashes in JSON. See: Matchers & Patterns.
- Routing selection: Defaults resolve first by explicit
default: true, then by routing rule priority, then by routing rule id alphabetical. Open With includes handlers whereshowInOpenWith: true.
Field ownership by platform
One document, three readers. Applies means the reader evaluates or enforces the key; accepts means it decodes the key without error and ignores it. No key in this table is refused by any reader.
| Key | Windows client | macOS daemon | macOS launcher |
|---|---|---|---|
$schema, policyVersion | accepts | accepts | accepts (launcher reports $schema) |
schemaVersion | applies (ceiling 2) | applies (ceiling 2) | applies (ceiling 2) |
policySignature, signatureCertificateThumbprints | accepts | accepts | accepts |
configuration.launch.runtime.{isolation, clipboard, visual} | applies | accepts | applies (clipboard, isolation) |
configuration.launch.runtime.{files, ipc, childProcesses, agents, audit} | accepts | applies | applies (files, for the Files tab) |
configuration.launch.runtime.{composition, devices, extensions, dataMotion, approval} | accepts | accepts | accepts |
configuration.launch.flags, configuration.launch.startMenuIntegration | applies | accepts | accepts (flags: clipboard extraction only) |
configuration.launch.mounts | applies (--mount) | accepts | accepts |
configuration.network.capabilities, inspectionAuthority, readOnlyHttp | accepts (readOnlyHttp: sandbox service) | applies | accepts |
configuration.network.proxies | applies | applies | applies |
configuration.network.proxyRouting[].siteRefs | applies | accepts | applies |
configuration.network.proxyRouting[].match, action.failover, action.proxyCandidates | accepts | applies | accepts |
configuration.network.proxyRouting[].action.type direct / deny | accepts (treated as no proxy) | applies | accepts |
configuration.sites | applies | accepts | applies |
configuration.chat | applies | accepts | applies |
configuration.overlay, configuration.audit.processLaunches, configuration.policyUpdateIntervalMinutes | applies | accepts | accepts |
configuration.{discovery, identity, integrations, trust, policySource, security, dataClassification} | accepts | accepts | accepts |
apps[].{id, enabled, priority, action, matchAll, matchAny, matchNone, targetPath} | applies | applies | applies |
apps[].displayName | applies | accepts | applies |
apps[].visibility, apps[].visibilityConstraints | applies | accepts | applies |
apps[].capabilities, fileTypes, fileAssociations | applies | accepts | applies |
apps[].configurationTemplates, configurationTemplates, files[] | applies | accepts | accepts |
apps[].overlay | applies | accepts | accepts |
apps[].containerColor | accepts | applies | applies |
apps[].sandboxEnabled | accepts | accepts | applies |
apps[].launcher | accepts | accepts | applies |
apps[].modifications.arguments, turboFlags | applies | accepts | accepts (turboFlags: MCP overlay parse only) |
apps[].modifications.runtime | applies (isolation, clipboard, visual) | accepts | accepts |
apps[].modifications.mounts | applies (--mount) | applies | accepts |
apps[].modifications.{network, files, environment, ipc, childProcesses, agents} | accepts | applies | accepts (files: Files tab) |
apps[].modifications.identityAccess, apps[].identityRequirements, apps[].authorization | accepts | accepts | accepts |
apps[].profiles[].{id, displayName} | applies | applies | applies |
apps[].profiles[].actionText | applies | accepts | applies |
apps[].profiles[].{siteRefs, postLaunchAction, arguments, turboFlags} | applies | accepts | accepts (turboFlags: applies) |
apps[].profiles[].{network, mounts, files, environment, ipc, childProcesses, agents} | accepts (mounts: applies) | applies | accepts |
Matcher type evaluation follows the same idea: arguments never matches on macOS; bundleId, teamId and codeDirectoryHash never match on Windows. See Matchers & Patterns.
Using the JSON Schema
Add a $schema directive at the top of your policy.json to enable editor validation and IntelliSense.
Recommended (stable URL):
json
{
"$schema": "https://schemas.turbo.net/launcher-policy.schema.json"
}Alternatively (when editing inside this repo):
json
{
"$schema": "./schema.json"
}Validate with AJV:
bash
# Compile schema (optional)
npx ajv compile -s docs/src/policy/reference/schema.json
# Validate a policy file
npx ajv validate -s docs/src/policy/reference/schema.json -d path/to/policy.jsonVS Code
- With
$schemaset, VS Code provides IntelliSense and inline errors according to the schema.
User configurations JSON (per-user)
Windows-only. For the per-user configurations file at %LOCALAPPDATA%\\Turbo\\Launcher\\user-profiles.json, use the dedicated schema:
Header
json
{
"$schema": "https://schemas.turbo.net/launcher-user-configurations.schema.json",
"userProfilesVersion": 1,
"profiles": []
}Local (when editing inside this repo)
json
{
"$schema": "./user-configurations-schema.json",
"userProfilesVersion": 1,
"profiles": []
}Validate with AJV
bash
npx ajv validate \
-s docs/src/policy/reference/user-configurations-schema.json \
-d "%LOCALAPPDATA%/Turbo/Launcher/user-profiles.json"See also: User Configurations Schema Reference and User Configurations.
