Metadata-Version: 2.4
Name: spottersec
Version: 0.8.0
Summary: Kubernetes security scanner — attack paths, RBAC blast radius, interactive TUI
Author-email: SpotterSec <hello@spottersec.com>
License: MIT
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: License :: OSI Approved :: MIT License
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
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 operators 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 TUI for browsing findings and exploit chains
- Auto-patch suggestions with exact kubectl fixes
- Secret detection using real credential patterns
- 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

Install from PyPI:

```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 a directory
spottersec scan ./k8s/ --explain

# Scan your live cluster interactively
spottersec audit --interactive

# Trace attack paths
spottersec attack

# Check service account blast radius
spottersec blast-radius my-pod
```

---

## Commands

| Command | Description |
|---------|-------------|
| `scan` | Scan YAML files |
| `audit` | Scan live cluster via kubectl |
| `attack` | Attack path analysis |
| `blast-radius` | RBAC blast radius for pod/service account |
| `tui` | Interactive findings browser |
| `fix` | Review and apply patch fixes |
| `watch` | Re-scan on file change |
| `trend` | Compare two scans |
| `rules` | List all rules |

---

## How SpotterSec Works

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

The analysis includes:

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

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

**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 and a risk score for each.

---

## 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/grafana
  ├─▶ SA/grafana
  ├─▶ kubectl get secrets
  └─▶ kubectl run pwn
```

---

## RBAC Blast Radius

```bash
spottersec blast-radius my-pod
spottersec blast-radius sa/flux-system/kustomize-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 by matching on value content — not just key names. Catches secrets regardless of what the env var or ConfigMap key is called.

| 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.
