Metadata-Version: 2.4
Name: spottersec
Version: 0.8.2
Summary: Kubernetes security scanner — attack paths, RBAC blast radius, interactive TUI
Author-email: SpotterSec <alexs@spottersec.com>
License: BUSL-1.1
Project-URL: Homepage, https://spottersec.com
Project-URL: Repository, https://github.com/spottersec/spotter
Project-URL: Bug Tracker, https://github.com/spottersec/spotter/issues
Keywords: kubernetes,security,k8s,rbac,scanner,devsecops,pentest,audit,attack-path
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML>=6.0
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Requires-Dist: argcomplete>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Dynamic: license-file

# SpotterSec

**Kubernetes security scanner that traces real attack paths — not just misconfigurations.**

SpotterSec analyzes workloads, RBAC permissions, network exposure, and service accounts to uncover exploitable chains such as:

```
Internet exposure → pod compromise → service account token theft → cluster-admin
```

Instead of only reporting misconfigurations, SpotterSec shows how an attacker could move through your cluster and provides the exact `kubectl patch` commands needed to fix each issue.

Built for security engineers, platform teams, and red teamers who want to understand what an attacker would actually do.

---

## Features

- Attack path analysis from internet exposure to cluster compromise
- RBAC blast radius scoring per service account
- Kubernetes manifest scanner for YAML, Helm, and live clusters
- Interactive attack graph — visualize the full kill chain
- Container escape surface analysis with ready-to-run PoC commands
- Secret enumeration with credential pattern matching and value scoring
- Interactive TUI for browsing findings and exploit chains
- Auto-patch suggestions with exact kubectl fixes
- CI/CD integration with SARIF output
- 52 Kubernetes security rules across pods, RBAC, networking, and secrets

---

## Demo

```bash
spottersec audit --interactive
```

```
23 CRITICAL · 65 HIGH · 137 MEDIUM · 84 LOW  (309 findings)

Risk Score  99/100  F  Critical Risk
⚡ Dangerous combinations detected:
  +10  hostPath + hostNetwork = node filesystem + network sniff
  +12  hostPID + SYS_PTRACE = dump memory of any process
  +20  Privileged pod + cluster-admin = instant full cluster

▶ ClusterRoleBinding/cluster-reconciler-flux-system
  💀 CRITICAL  cluster-admin binding → ServiceAccount/kustomize-controller

▶ Pod/monitoring/node-exporter
  💀 CRITICAL  hostPath mount on dangerous path: /
  💀 CRITICAL  hostPath mount on dangerous path: /proc
  🔴 HIGH      hostNetwork: true
```

---

## Install

```bash
pip install spottersec
```

Install from source:

```bash
git clone https://github.com/spottersec/spotter
cd spotter
pip install .
```

**Requirements:** Python 3.10+, `kubectl` in PATH (for live cluster scanning)

### Enable CLI Autocomplete (optional)

```bash
echo 'autoload -U compinit && compinit && autoload -U bashcompinit && bashcompinit && eval "$(register-python-argcomplete spottersec)"' >> ~/.zshrc
source ~/.zshrc
```

---

## Quick Start

```bash
# Scan a YAML file
spottersec scan pod.yaml

# Scan your live cluster
spottersec audit --interactive

# Trace attack paths
spottersec attack

# Generate an interactive attack graph
spottersec graph

# Check container escape vectors from a pod
spottersec escape

# Enumerate valuable secrets
spottersec loot
```

---

## Commands

| Command | Description |
|---------|-------------|
| `scan` | Scan YAML files or directories |
| `audit` | Scan live cluster via kubectl |
| `attack` | Attack path analysis |
| `blast-radius` | RBAC blast radius for pod or service account |
| `graph` | Generate interactive HTML attack graph |
| `escape` | Container escape surface — enumerate escape vectors per pod |
| `loot` | Enumerate valuable secrets — credentials, keys, tokens |
| `tui` | Interactive findings browser |
| `fix` | Review and apply patch fixes |
| `watch` | Re-scan on file change |
| `trend` | Compare two scans |
| `rules` | List all rules |

---

## Attack Graph

`spottersec graph` generates a self-contained HTML file showing the full cluster kill chain — entry points, workload compromise, RBAC pivots, and blast radius — rendered as an interactive force-directed graph.

```bash
spottersec graph                      # live cluster via kubectl
spottersec graph scan.json            # from saved scan JSON
spottersec graph -o report.html       # custom output path
spottersec graph --no-open            # don't auto-open browser
```

The graph shows:
- Critical attack paths highlighted in red
- Node detail panel on click (findings, blast radius, severity)
- Sidebar filters by node type and attack path
- "Fix These First" panel — top 3 chokepoint nodes that break the most attack paths when fixed

---

## Container Escape Surface

`spottersec escape` analyzes every pod in the cluster and enumerates all escape vectors available from inside each container. For each vector it shows the MITRE technique, evidence, impact, and a ready-to-run PoC.

```bash
spottersec escape                          # all pods
spottersec escape [pod-name]                  # specific pod by name
spottersec escape pod/monitoring   # namespace/name
spottersec escape -n production            # scoped to namespace
spottersec escape --json                   # pipe to jq
```

**Vectors checked:**

| ID | Vector | Severity |
|----|--------|----------|
| ESC001 | `privileged: true` | 💀 CRITICAL |
| ESC002 | `hostPath /` mounted | 💀 CRITICAL |
| ESC004 | Container runtime socket mounted (docker.sock, containerd.sock) | 💀 CRITICAL |
| ESC007 | `SYS_ADMIN` capability (cgroup escape, CVE-2022-0492) | 💀 CRITICAL |
| ESC003 | Sensitive hostPath (`/etc`, `/var/lib/kubelet`, `/proc`…) | 🔴 HIGH |
| ESC005 | `hostPID: true` | 🔴 HIGH |
| ESC006 | `hostNetwork: true` (cloud metadata reachable) | 🔴 HIGH |
| ESC008 | `SYS_PTRACE` capability | 🔴 HIGH |
| ESC009 | `NET_ADMIN` capability | 🔴 HIGH |
| ESC010 | `DAC_READ_SEARCH` capability (Shocker attack) | 🔴 HIGH |
| ESC011 | SA token automounted | 🟡 MEDIUM |
| ESC012 | Running as root | 🟡 MEDIUM |
| ESC013 | Writable root filesystem | 🔵 LOW |

Dangerous combinations are surfaced separately — e.g. `hostPID + SYS_PTRACE = arbitrary code in any host process`.

---

## Secret Enumeration

`spottersec loot` reads all secrets in the cluster, base64-decodes values, and classifies them by credential type and attacker value. Use `--no-values` to redact actual values for safe reporting.

```bash
spottersec loot                        # all namespaces
spottersec loot -n production          # scoped
spottersec loot --min-value HIGH       # skip low-value noise
spottersec loot --no-values            # redact values
spottersec loot --json | jq '.[] | select(.value=="CRITICAL")'
```

**Credential categories detected:**

| Category | Value |
|----------|-------|
| AWS Access/Secret/Session keys | 💀 CRITICAL |
| GCP service account keys | 💀 CRITICAL |
| Azure client secrets | 💀 CRITICAL |
| Private keys (RSA/EC/DSA/OpenSSH) | 💀 CRITICAL |
| Kubeconfigs | 💀 CRITICAL |
| GitHub tokens | 🔴 HIGH |
| Stripe live keys | 🔴 HIGH |
| Database connection strings | 🔴 HIGH |
| JWT secrets | 🔴 HIGH |
| Slack tokens | 🔴 HIGH |
| OpenAI / Anthropic API keys | 🔴 HIGH |
| Container registry credentials | 🔴 HIGH |
| TLS certificates | 🟡 MEDIUM |
| Generic API keys | 🟡 MEDIUM |
| OAuth client secrets | 🟡 MEDIUM |
| Generic passwords | 🟡 MEDIUM |
| Generic tokens | 🔵 LOW |
| SSH public keys | 🔵 LOW |

Detection matches on both key name and decoded value content — catches credentials regardless of what the secret key is named.

---

## How SpotterSec Works

SpotterSec builds a graph model of your Kubernetes environment and analyzes how an attacker could move through it.

**Entry points**
- Ingress hosts
- LoadBalancer / NodePort services

**Workload compromise**
- `privileged` containers
- Dangerous Linux capabilities
- Host namespace access
- Container escape vectors

**Service account token abuse**
- RBAC permissions
- Secret access
- Pod creation privileges

**Privilege escalation**
- `cluster-admin` bindings
- RBAC self-grant
- Node escape vectors

These steps are combined to generate attack paths, a risk score, and an interactive graph.

---

## YAML Scanning

```bash
spottersec scan pod.yaml
spottersec scan ./k8s/ --explain --group
spottersec scan - --explain            # stdin
```

**Pipe from kubectl:**

```bash
kubectl get pod mypod -o yaml | spottersec scan -
kubectl get deployments -A -o yaml | spottersec scan -
```

---

## Live Cluster Scanning

```bash
spottersec audit
spottersec audit -n production
spottersec audit --interactive
spottersec audit --explain
```

---

## Attack Path Analysis

```bash
spottersec attack
```

```
INTERNET-EXPOSED PATHS

Entry: Ingress/frontend
  ├─▶ SA/grafana
  ├─▶ kubectl get secrets
  └─▶ kubectl run pwn
```

---

## RBAC Blast Radius

```bash
spottersec blast-radius my-pod
spottersec blast-radius sa/ci-system/deployment-controller
```

Shows exact attacker steps using that service account token.

---

## Interactive TUI

```bash
spottersec tui
spottersec tui results.json
spottersec audit --interactive
```

| Key | Action |
|-----|--------|
| `↑↓` | Navigate |
| `Enter` | View details |
| `f` | Show fix |
| `e` | Show exploit chain |
| `b` | Back |
| `q` | Quit |

---

## Secret Pattern Detection

Detects real credentials in pod specs and ConfigMaps by matching on value content — not just key names.

| Pattern | Severity |
|---------|----------|
| AWS Access Key ID (`AKIA...`) | 💀 CRITICAL |
| GitHub Token (`ghp_`, `gho_`, `ghs_`) | 💀 CRITICAL |
| Stripe Secret Key (`sk_live_...`) | 💀 CRITICAL |
| Private Key headers (`-----BEGIN ... PRIVATE KEY-----`) | 💀 CRITICAL |
| Slack Bot Token (`xoxb-...`) | 🔴 HIGH |
| Database DSN with password (`postgres://user:pass@host`) | 🔴 HIGH |
| OpenAI / Anthropic API keys | 🔴 HIGH |
| Hashicorp Vault tokens (`hvs....`) | 🔴 HIGH |
| SendGrid, npm, PyPI tokens | 🔴 HIGH |
| + 15 more patterns | varies |

---

## Configuration

Create `.spottersec.yaml` in your repo:

```yaml
scan:
  fail_on: high
  severity: medium
  ignore:
    - NET001
  paths:
    - ./k8s/
    - ./helm/templates/
```

---

## CI/CD Integration

### GitHub Actions

```yaml
- uses: actions/checkout@v4
- uses: spottersec/spotter@v1
  with:
    path: ./k8s/
    fail-on: high
```

**With SARIF upload to GitHub Security tab:**

```yaml
name: K8s Security
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: SpotterSec scan
        uses: spottersec/spotter@v1
        with:
          path: ./k8s/
          output: sarif
          sarif-file: spottersec.sarif
          fail-on: high
      - name: Upload to GitHub Security
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: spottersec.sarif
```

### GitLab CI

```yaml
k8s-security:
  image: python:3.12-slim
  script:
    - pip install spottersec
    - spottersec scan ./k8s/ --fail-on high
```

---

## Rule Reference

52 rules across pods, RBAC, network, ingress, secrets, webhooks, and Helm.

### Container Security (SC)

| Rule | Severity | Description |
|------|----------|-------------|
| SC001 | 💀 CRITICAL | `privileged: true` |
| SC002 | 🔴 HIGH | `runAsUser: 0` — explicit root |
| SC003 | 🔴 HIGH | `runAsNonRoot: false` |
| SC004 | 🟡 MEDIUM | `runAsNonRoot` not set |
| SC005 | 🔴 HIGH | `allowPrivilegeEscalation: true` |
| SC006 | 🔵 LOW | `allowPrivilegeEscalation` not set |
| SC007 | 🔵 LOW | `readOnlyRootFilesystem` not set |
| SC008 | 🔵 LOW | No seccomp profile |

### Volumes (VOL)

| Rule | Severity | Description |
|------|----------|-------------|
| VOL001 | 💀 CRITICAL | `hostPath` on dangerous path (`/`, `/etc`, `/proc`, `/sys`, `/var/run`) |

### Namespace / Host (NS)

| Rule | Severity | Description |
|------|----------|-------------|
| NS001 | 🔴 HIGH | `hostPID: true` |
| NS002 | 🔴 HIGH | `hostNetwork: true` |
| NS003 | 🟡 MEDIUM | `hostIPC: true` |
| NS010 | 🔴 HIGH | Namespace missing Pod Security Admission enforce label |
| NS011 | 🔴 HIGH | Namespace PSA enforce level is `privileged` |

### RBAC

| Rule | Severity | Description |
|------|----------|-------------|
| RBAC001 | 💀 CRITICAL | `cluster-admin` binding |
| RBAC002 | 🔴 HIGH | Wildcard verbs on pod/workload resources |
| RBAC003 | 🔴 HIGH | Wildcard resources in RBAC rule |
| RBAC004 | 🔴 HIGH | Role grants Secrets read access |
| RBAC005 | 🔴 HIGH | Binding to built-in privileged role |
| RBAC006 | 💀 CRITICAL | ClusterRole with full wildcard |
| RBAC007 | 🔴 HIGH | Role can create/modify pods |
| RBAC008 | 💀 CRITICAL | Role can write RBAC — self-grant escalation |
| RBAC009 | 💀 CRITICAL | Role grants impersonation |

### Service Accounts (SA)

| Rule | Severity | Description |
|------|----------|-------------|
| SA001 | 🟡 MEDIUM | SA token auto-mounted |
| SA002 | 🟡 MEDIUM | Uses `default` ServiceAccount |

### Capabilities (CAP)

| Rule | Severity | Description |
|------|----------|-------------|
| CAP001_* | 💀/🔴 varies | Dangerous Linux capability added |
| CAP002 | 🟡 MEDIUM | `capabilities.drop: [ALL]` missing |

### Network (NET)

| Rule | Severity | Description |
|------|----------|-------------|
| NET001 | 🟡 MEDIUM | No NetworkPolicy |
| NET002 | 🟡 MEDIUM | NetworkPolicy catch-all ingress |
| NET003 | 🟡 MEDIUM | NetworkPolicy no egress restriction |

### Services (SVC)

| Rule | Severity | Description |
|------|----------|-------------|
| SVC001 | 🟡 MEDIUM | Service type LoadBalancer |
| SVC002 | 🔴 HIGH | `externalIPs` set — CVE-2020-8554 |
| SVC003 | 🔵 LOW | Service type NodePort |

### Ingress (ING)

| Rule | Severity | Description |
|------|----------|-------------|
| ING001 | 🟡 MEDIUM | Ingress host with no TLS |
| ING002 | 🟡 MEDIUM | Ingress wildcard/missing host |
| ING003 | 🔵 LOW | Ingress has no auth annotation |

### Webhooks (WHK)

| Rule | Severity | Description |
|------|----------|-------------|
| WHK001 | 🔴 HIGH | Webhook `failurePolicy: Ignore` |
| WHK002 | 🔵 LOW | Webhook high timeout |
| WHK003 | 🟡 MEDIUM | Webhook intercepts all resources |

### Environment / Secrets (ENV)

| Rule | Severity | Description |
|------|----------|-------------|
| ENV001 | 🔴 HIGH | Hardcoded credential in env var |
| ENV002 | 🔴 HIGH | Credential in ConfigMap |
| ENV003 | 💀 CRITICAL | Known secret pattern in env var |
| ENV004 | 💀 CRITICAL | Known secret pattern in ConfigMap |

### etcd (ETCD)

| Rule | Severity | Description |
|------|----------|-------------|
| ETCD001 | 💀 CRITICAL | etcd without TLS |
| ETCD002 | 💀 CRITICAL | etcd bound to `0.0.0.0` |
| ETCD003 | 🟡 MEDIUM | Secrets not encrypted at rest |

### Images / Resources (IMG, RES)

| Rule | Severity | Description |
|------|----------|-------------|
| IMG001 | 🔵 LOW | Mutable image tag |
| RES001 | 🔵 LOW | No resource limits |

### Helm (HLM)

| Rule | Severity | Description |
|------|----------|-------------|
| HLM001 | 🔴 HIGH | Hardcoded secret in Helm values |
| HLM002 | 🔴 HIGH | `auth.enabled: false` |

### Availability (PDB)

| Rule | Severity | Description |
|------|----------|-------------|
| PDB001 | 🟡 MEDIUM | Single replica |
| PDB002 | 🔵 LOW | No PodDisruptionBudget |

---

## Learn More

[spottersec.com](https://spottersec.com) — interactive Kubernetes attack path learning platform with 10 scenarios covering the most common K8s compromise chains.

---

## License

SpotterSec is licensed under the **Business Source License (BUSL 1.1)**.

Free for:
- Personal use
- Internal security scanning
- Research

Commercial redistribution or resale requires a license from SpotterSec.
