# Symantec CloudSOC DLP CLI

A Python CLI for managing **DLP Profiles** and **Protect Policies** via the Symantec CloudSOC REST API.

---

## Requirements

- Python 3.8+
- A Symantec CloudSOC account with API access
- An API key downloaded from **Settings → API Keys** in the CloudSOC console

---

## Installation

```bash
cd symantec-dlp

# Create virtual environment
python3 -m venv .venv

# Activate it
source .venv/bin/activate        # macOS / Linux
.venv\Scripts\activate           # Windows

# Install dependencies
pip install -r requirements.txt
```

---

## Authentication Setup

### 1. Get your API key

Log in to the CloudSOC console → **Settings → API Keys** → Download your key file.  
It contains a `key_id` and `key_secret`.

### 2. Configure credentials

```bash
python cli.py auth configure
```

You will be prompted for:

| Field | Description |
|---|---|
| API Key ID | From your downloaded key file |
| API Key Secret | From your downloaded key file |
| Tenant name | Your CloudSOC tenant identifier |
| Region | `us` or `eu` |

Credentials are stored at `~/.config/symantec-dlp/credentials.json` with `chmod 600`.  
You can also pass values via environment variables to skip the prompts:

```bash
export SYMANTEC_KEY_ID=your_key_id
export SYMANTEC_KEY_SECRET=your_key_secret
export SYMANTEC_TENANT=your_tenant
export SYMANTEC_REGION=us
python cli.py auth configure
```

### 3. Check token status

```bash
python cli.py auth status           # show token validity
python cli.py auth status --refresh # force a new token
```

Tokens are cached at `~/.config/symantec-dlp/token_cache.json` and auto-refreshed after 14 minutes (the API TTL is 15 minutes).

---

## Commands

### Auth

```bash
python cli.py auth configure          # store credentials
python cli.py auth status             # show token validity
python cli.py auth status --refresh   # force token refresh
```

---

### DLP Profiles

#### List profiles

```bash
python cli.py profile list
python cli.py profile list --output json
```

#### Get a profile

```bash
python cli.py profile get <profile_id>
python cli.py profile get <profile_id> --output json
```

#### Create a profile — interactive (recommended for first use)

```bash
python cli.py profile create --interactive
```

The interactive builder walks you through:
- Profile name
- Rule type (keyword, data identifier, regex, EDM, IDM, etc.)
- Match targets (subject, body, attachments, envelope)
- Count type and threshold
- Severity (high, medium, low, info)

#### Create a profile — with flags

```bash
python cli.py profile create \
  --name "PCI Profile" \
  --policy "('''credit-card-rule''' ( data identifier count exists min 1 match on body | attachments ) severity high)"
```

#### Create a profile — from a JSON file

```bash
python cli.py profile create --json-file payload.json
```

Example `payload.json`:

```json
{
  "name": "My DLP Profile",
  "policy": "('''ssn-rule''' ( data identifier count exists min 1 match on body | attachments ) severity high)",
  "tenant": "your_tenant",
  "restConnectorId": 1,
  "createdBy": "sys admin",
  "createdOn": "2024-01-01T00:00:00+00:00",
  "modifiedBy": "sys admin",
  "modifiedOn": "2024-01-01T00:00:00+00:00"
}
```

#### List Data Identifiers (for use in policy rules)

```bash
python cli.py profile di-list
python cli.py profile di-list --output json
```

---

### Protect Policies

#### List policies

```bash
python cli.py policy list                  # first 50
python cli.py policy list --all            # auto-paginate all pages
python cli.py policy list --output json
```

#### Update a policy

```bash
# Via flags
python cli.py policy update "My Policy" \
  --policy-type accessenforcement \
  --applications "Dropbox"

# Via JSON file
python cli.py policy update "My Policy" --json-file update.json
```

Example `update.json`:

```json
{
  "policy_name": "My Policy",
  "policy_type": "accessenforcement",
  "applications": "Dropbox",
  "delineated_id_scope": {
    "instances": ["__ALL_EL__"]
  },
  "delineated_id_scope_whitelist": {
    "instances": []
  }
}
```

Supported `--policy-type` values: `accessenforcement`, `documentshare`, `filexfer`

#### Delete a policy

```bash
python cli.py policy delete "My Policy"       # prompts for confirmation
python cli.py policy delete "My Policy" --yes  # skip confirmation
```

> **Note:** The CloudSOC docs document GET (list) and PATCH (update) for the Policy API. The delete command follows REST convention — if your tenant returns HTTP 405, the endpoint may not be exposed.

---

## Policy Rule Grammar

Policy rules use a structured string format:

```
('''RULE_NAME''' ( [rule_type] [parameters] match on [components] ) severity [level])
```

### Rule types

| Rule Type | Description |
|---|---|
| `keyword` | Match keywords with delimiter/token options |
| `data identifier` | Match sensitive patterns (SSN, credit cards, etc.) |
| `regex` | Custom regular expressions |
| `edm` | Exact Data Matching against an index |
| `idm` | Indexed document matching |
| `data classifier` | Match classified content categories |
| `document name` | Filter by filename |
| `document size` | Size thresholds (e.g., > 1 MB) |
| `document type` | File type filtering (pdf, 7zip, etc.) |
| `personal email` | Personal email recipient detection |
| `recipient` | Match by IP, email, or URL |
| `profiled sender` | Sender group identification |
| `sender ip` | Sender IP or email patterns |
| `structured data identifier` | Structured data type matching |

### Match components

```
match on subject | body | attachments | envelope
```

### Count options

```
count exists min 1        # at least one match
count all min N           # N or more total matches
count unique min N        # N or more unique matches
```

### Severity levels

`high` · `medium` · `low` · `info`

### Example rules

```bash
# Credit card detection — high severity
('''cc-rule''' ( data identifier count exists min 1 match on body | attachments ) severity high)

# SSN with minimum 3 unique matches
('''ssn-rule''' ( data identifier count unique min 3 match on body | attachments ) severity medium)

# Keyword match on subject and body
('''confidential-kw''' ( keyword count exists min 1 match on subject | body ) severity low)
```

---

## Output Formats

All commands support `--output` / `-o`:

| Flag | Description |
|---|---|
| `--output table` | Human-readable rich table (default) |
| `--output json` | Raw JSON for scripting / piping |

```bash
python cli.py profile list --output json | jq '.[].name'
```

---

## File Structure

```
symantec-dlp/
├── cli.py              # Entry point and auth commands
├── auth.py             # Credential storage and token cache
├── client.py           # HTTP clients (DLP Profile API + Policy Admin API)
├── config.py           # Base URLs, file paths, region config
├── requirements.txt
└── commands/
    ├── profile.py      # profile list / get / create / di-list
    └── policy.py       # policy list / update / delete
```

## Credentials & Token Storage

| File | Contents | Permissions |
|---|---|---|
| `~/.config/symantec-dlp/credentials.json` | key_id, key_secret, tenant, region | 600 |
| `~/.config/symantec-dlp/token_cache.json` | JWT token + expiry timestamp | 600 |

---

## API Reference

| API | Base URL (US) | Base URL (EU) |
|---|---|---|
| DLP Profile API | `https://app.elastica.net` | `https://app.eu.elastica.net` |
| Policy Admin API | `https://api-vip.elastica.net` | `https://api.eu.elastica.net` |

Full documentation: [Symantec CloudSOC Cloud DLP APIs](https://techdocs.broadcom.com/us/en/symantec-security-software/information-security/symantec-cloudsoc/cloud/api-home/protect-api/cloud-dlp-apis.html)
