Metadata-Version: 2.4
Name: smtp-gateway
Version: 1.0.1
Summary: SMTP gateway API with PII column scanning, CIDR allowlist, and optional ADLS audit
Author-email: Hemantha Krishna <saladi.krishna18@gmail.com>
License: Proprietary
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: flask>=2.3
Requires-Dist: gunicorn>=21.0
Requires-Dist: azure-identity>=1.14
Requires-Dist: azure-storage-file-datalake>=12.14
Provides-Extra: publish
Requires-Dist: build>=1.0; extra == "publish"
Requires-Dist: twine>=4.0; extra == "publish"

# SMTP Gateway (`smtp-gateway`)

Flask API that sends mail through an internal SMTP relay after checking caller IP (CIDR), bearer token, recipient domains, and PII column names in HTML bodies and CSV/HTML attachments. Optional audit to Azure ADLS and notification emails.

## Install

Git is **not** required. See [PUBLISHING.md](PUBLISHING.md).

### From PyPI (after you publish)

```bash
pip install "smtp-gateway==1.0.0"
```

### On VM without PyPI (copy wheel)

```bash
pip install /path/to/smtp_gateway-1.0.0-py3-none-any.whl
```

### From project folder (no git, no PyPI)

```bash
pip install .
```

### Local development

```bash
pip install -e .
```

## Required configuration

Copy `.env.example` to `.env` on the server and set at least:

| Variable | Purpose |
|----------|---------|
| `API_TOKEN` | Clients send `Authorization: Bearer <token>` |
| `FROM_EMAIL` | Gateway sender address |
| `SMTP_SERVER` | Internal SMTP host |
| `ALLOWED_DOMAINS` | Comma-separated recipient domains |

Startup fails if any required variable is missing.

### PII blocklist and caller CIDRs

The package ships **example** JSON under `smtp_gateway/data/`:

- `blocklist.json` — sample column names
- `allowed_cidrs.json` — empty list (blocks all IPs until you configure)

For production, point to your own files (recommended):

```bash
export BLOCKLIST_PATH=/etc/smtp-gateway/blocklist.json
export ALLOWED_CIDRS_PATH=/etc/smtp-gateway/allowed_cidrs.json
```

Format: JSON arrays. Blocklist entries are strings (one column name per entry). CIDRs are strings like `"10.0.0.0/24"`.

Without `ALLOWED_CIDRS_PATH`, bundled `allowed_cidrs.json` is used — empty `[]` means every caller gets **403 Forbidden IP**.

### Optional

| Variable | Purpose |
|----------|---------|
| `SECURITY_ALERT_EMAIL` / `SECURITY_ALERT_CC` | Email on blocked requests |
| `AUDIT_NOTIFICATION_EMAIL` / `AUDIT_NOTIFICATION_CC` | Audit copy per send/block |
| `ADLS_ACCOUNT_NAME`, `ADLS_CONTAINER_NAME`, `MANAGED_IDENTITY_CLIENT_ID` | ADLS audit (skipped if unset) |
| `GUNICORN_WORKERS`, `BIND` | Process count and listen address |

## Run

Production (HA — use behind a load balancer, 2+ VMs):

```bash
set -a && source .env && set +a
smtp-gateway
```

Equivalent:

```bash
gunicorn -w 4 -b 0.0.0.0:5000 'smtp_gateway.app:create_app()'
```

Local development (Flask dev server):

```bash
set -a && source .env && set +a
python -m smtp_gateway
```

Health check: `GET /health` → `{"status":"healthy"}`.

## API

`POST /send-mail` (multipart form):

| Field | Required | Notes |
|-------|----------|-------|
| `to` | yes | Recipient(s) |
| `subject` | yes | |
| `body` | yes | HTML (table headers scanned for PII) |
| `cc` | no | |
| `file` | no | `.csv`, `.html`, `.htm` only |

Headers:

- `Authorization: Bearer <API_TOKEN>`
- Caller IP must match `allowed_cidrs.json`

## Client checklist

- Call from an allowed CIDR
- Use allowed recipient domains
- Avoid blocklisted column names in HTML tables and CSV/HTML attachments

## Package layout

```
src/smtp_gateway/
  app.py              create_app()
  config.py           environment settings
  routes/             /health, /send-mail
  security/           CIDR, domains, auth
  pii/                extract, blocklist, matcher
  audit/              ADLS, email notifications
  data/               bundled example JSON
```

## What you supply vs what is bundled

| Bundled in package | You supply on the VM |
|--------------------|----------------------|
| PII matching code | Full `blocklist.json` via `BLOCKLIST_PATH` |
| Example blocklist | Real `allowed_cidrs.json` via `ALLOWED_CIDRS_PATH` |
| Flask routes, audit code | `.env` secrets and SMTP/ADLS access |
| `smtp-gateway` CLI | Load balancer, systemd, managed identity + RBAC |
