Skip to main content

Policy Structure

Every policy has the same top-level shape in YAML:
- name: Human-readable label      # required, string
  type: app_config                # required: app_config | flow_config | dlp_config
  scope: global                   # required: global | group | device
  target: finance                 # required when scope is group or device
  locked: false                   # optional, default false
  description: "..."              # optional, ignored by the agent
  data:                           # required, type-specific (see below)
    ...

scope and target

ScopeTargetApplies to
globalomit (or null)All devices in the org
groupgroup name or group UUIDAll devices in that group
devicedevice UUIDThat specific device only
Group name resolution: the SDK looks up the group by name first, then by UUID. If the group does not exist, apply will fail with a 404.

locked

When locked: true, the device agent cannot override the policy locally — even if a device-level policy would normally take precedence. Use this for compliance-critical settings you never want overridden.

App Config (app_config)

Controls the Agent Charley application’s behavior on the endpoint.
data:
  suppress_frontend_ui: false           # Hide browser extension UI (coin, panel, badges)
  suppress_email_content_analysis: false # Skip email phishing analysis
  stealth_mode: false                   # Fully invisible mode — no tray icon, no dashboard
  flow_logs_enabled: true               # Stream activity logs for analytics
  telemetry_enabled: true               # Report threat telemetry to the Overview dashboard
  suppress_policy_locked: false         # Allow device to override locked policies (use carefully)
All fields are optional. Unset fields inherit from the broader scope.
FieldTypeDefaultDescription
suppress_frontend_uiboolfalseHides the browser extension’s visible elements
suppress_email_content_analysisboolfalseDisables email content phishing scanning
stealth_modeboolfalseNo tray icon, no local dashboard, completely silent
flow_logs_enabledbooltrueEnables the URL activity stream to the Charley API
telemetry_enabledbooltrueEnables threat event reporting for analytics
suppress_policy_lockedboolfalseIf true, device can override even locked policies

Flow Config (flow_config)

Controls which URL categories Agent Charley classifies and reports.
data:
  enabled: true
  categories:
    - SECURITY_BLOCK
    - BANKING
    - CRYPTO
    - ECOMMERCE
    - EMAIL
    - JOB_SITES
    - SOCIAL_MEDIA
    - PRODUCTIVITY
    - TRUSTED
FieldTypeDefaultDescription
enabledbooltrueEnable or disable flow tracking entirely
categorieslist[string]allURL categories to classify and report

Available Categories

ValueDescription
SECURITY_BLOCKKnown malicious, phishing, and threat domains
BANKINGOnline banking and financial services
CRYPTOCryptocurrency exchanges and wallets
ECOMMERCEShopping and retail sites
EMAILWebmail services (Gmail, Outlook, etc.)
JOB_SITESJob boards and recruiting platforms
SOCIAL_MEDIASocial networks
PRODUCTIVITYWork tools (docs, project management, collaboration)
TRUSTEDOrg-allowlisted domains

DLP Config (dlp_config)

Controls data loss prevention — scanning clipboard content and blocking or warning on sensitive data patterns.
data:
  enabled: true

  targets:
    apply_to_all_apps: true       # Scan paste events in all applications
    apps_allowlist:               # Alternative: only scan in these apps (by display name)
      - Chrome
      - Slack
      - Terminal

  detections:
    builtins:                     # Built-in pattern detectors
      - credit_card
      - ssn_us
      - email
      - phone
    custom_regex:                 # Custom regex patterns
      - name: account_number
        pattern: '\b[0-9]{8,17}\b'
      - name: api_key
        pattern: 'sk-[A-Za-z0-9]{32,}'

  actions:
    mode: warn                    # block | warn | allow
    clear_clipboard_on_block: true
    allow_once_override: false

  ui:
    notify_on_block: true
    notify_on_warn: true
    toast_cooldown_sec: 30        # Minimum seconds between toasts (0 = always show)

  slack_context:                  # Optional: Slack-aware DLP context
    enabled: true
    categories:                   # Only trigger in these Slack channel types
      - public_channel
      - external_shared
      - dm
      - group_dm
      - private_channel
      - context_unavailable

targets

Either apply_to_all_apps: true or provide apps_allowlist — not both. apps_allowlist entries are matched against the application’s display name on macOS (as reported by NSWorkspace).

detections.builtins

ValueDetects
credit_cardLuhn-valid 13–19 digit card numbers (Visa, MC, Amex, Discover)
ssn_usUS Social Security Numbers in XXX-XX-XXXX or XXXXXXXXX format
emailEmail addresses
phoneUS phone numbers in common formats

actions.mode

ValueBehavior
blockCancels the paste. Optionally clears the clipboard.
warnAllows the paste but shows a warning notification.
allowLogs the detection but takes no visible action.

slack_context

When slack_context.enabled is true, DLP triggers only when the user is pasting into a Slack window that matches the specified channel types. If slack_context is omitted or disabled, DLP applies regardless of the target application.

Python SDK Models

AppConfigData

from charley_policy import AppConfigData

AppConfigData(
    suppress_frontend_ui=False,
    suppress_email_content_analysis=False,
    stealth_mode=False,
    flow_logs_enabled=True,
    telemetry_enabled=True,
    suppress_policy_locked=False,
)

FlowConfigData

from charley_policy import FlowConfigData

FlowConfigData(
    enabled=True,
    categories=["SECURITY_BLOCK", "BANKING", "CRYPTO"],
)

DlpConfigData

from charley_policy import DlpConfigData, DlpTargets, DlpDetections, DlpActions, DlpUi, DlpRegex

DlpConfigData(
    enabled=True,
    targets=DlpTargets(apply_to_all_apps=True),
    detections=DlpDetections(
        builtins=["credit_card", "ssn_us"],
        custom_regex=[DlpRegex(name="account_number", pattern=r"\b[0-9]{8,17}\b")],
    ),
    actions=DlpActions(
        mode="block",
        clear_clipboard_on_block=True,
        allow_once_override=False,
    ),
    ui=DlpUi(
        notify_on_block=True,
        toast_cooldown_sec=0,
    ),
)