Skip to main content

Command-line client for ThreatCluster (`tc`)

Project description

threatcluster-cli

Command-line client for ThreatCluster. Installs the tc command.

pipx install threatcluster-cli

Getting started (3 steps)

1. Install

pipx install threatcluster-cli

2. Mint an agent key

Sign in at https://threatcluster.ioSettings → CLI → Mint key. Tick the scopes you want, click mint, copy the tc_agent_… value. Shown once — store it somewhere safe.

3. Log in

tc auth login

Paste the key when prompted. The CLI stores it in your OS keyring (Keychain on macOS, SecretService on Linux desktop, Credential Manager on Windows) and you're ready.

tc threats list --limit 5 | jq -r '.threats[].ai_title'

That's it.


Commands

Every command outputs JSON. Pipe through jq for reading. tc <command> --help for full options.

tc auth — credentials

tc auth login                    # paste a refresh credential
tc auth status                   # show what's loaded
tc auth status -v                # + storage backend, bearer jti, key id
tc auth logout                   # hard kill: revokes server-side AND clears local
tc auth logout --keep-remote     # local clear only (e.g. moving the key)

tc search — smart router (entities + threats)

tc search "Volt Typhoon"
tc search lockbit --only entities       # entity-only
tc search cisco --only threats --limit 20

tc threats — clusters and IOCs

tc threats list                                 # latest trending
tc threats list --query ransomware --limit 20   # filter by keyword
tc threats list --watch --interval 30           # live feed (NDJSON)
tc threats get <cluster-id>                     # one cluster
tc threats iocs <cluster-id>                    # IOCs for one cluster
tc threats iocs <id> --types ip,domain          # filter IOC types
tc threats stix <cluster-id>                    # STIX 2.1 export

tc iocs — bulk indicators

tc iocs feed                                    # plaintext, one per line (last 30d, confirmed)
tc iocs feed --type ip                          # filter by type
tc iocs feed --type hash --hours 24             # last 24h hashes only
tc iocs export --format csv                     # for spreadsheets / SIEM
tc iocs export --format json                    # structured
tc iocs export --type domain --format csv       # domains, CSV

tc entities — actors, malware, tools

tc entities search "lazarus" --type apt_group
tc entities get apt_group "Lazarus Group"
tc entities related apt_group "Lazarus Group"   # co-occurring entities
tc entities trending                            # top by recent mentions
tc entities trending --window 7d

tc vulns — CVEs

tc vulns list                                   # latest CVEs
tc vulns list --severity CRITICAL --limit 10
tc vulns list --watch --interval 120            # live CVE feed
tc vulns get CVE-2026-1234                      # one CVE detail

tc darkweb — ransomware, breaches, markets

tc darkweb ransomware victims                   # last 30 days
tc darkweb ransomware victims --group lockbit
tc darkweb ransomware victims --days 7 --limit 100
tc darkweb ransomware victims --watch           # live feed
tc darkweb breaches
tc darkweb breaches --watch
tc darkweb keyword-hits                         # business+/MSSP only

tc feeds — your custom intel feeds

tc feeds list
tc feeds get <feed-id>

tc cluster — analyst pivots

tc cluster open <cluster-id>                    # opens in browser
tc cluster open <id> --no-browser               # just print the URL

Stdin chaining (-)

Any command that takes an id accepts - to read ids from stdin. Compose freely:

# Top 5 trending clusters → IOCs for each
tc threats list --limit 5 \
  | jq -r '.threats[].cluster_id' \
  | tc threats iocs -

# CVE detail for everything new in 24h
tc vulns list --since 24h \
  | jq -r '.cves[].cve_id' \
  | tc vulns get -

# Open every LockBit-related cluster in the browser
tc threats list --query lockbit --limit 3 \
  | jq -r '.threats[].cluster_id' \
  | tc cluster open -

# STIX bundle for every "ransomware" cluster
tc threats list --query ransomware --limit 20 \
  | jq -r '.threats[].cluster_id' \
  | tc threats stix -

Use cases

SOC analyst — "what's worth my attention right now?"

# Trending ransomware clusters
tc threats list --query ransomware --limit 10 \
  | jq -r '.threats[] | "[\(.threat_score)] \(.ai_title)"'

# CVEs newly added to CISA KEV-style catalogs
tc vulns list --severity CRITICAL --limit 10 \
  | jq -r '.cves[] | "\(.cve_id) — \(.description[:120])"'

# What ransomware groups are most active this week?
tc entities trending --window 7d \
  | jq -r '.trending.ransomware_group[:10][] | "\(.value)  freq=\(.frequency)"'

Threat hunter — "is X in our intel?"

# Pivot from a malware family to clusters mentioning it
tc entities search "cobalt strike" --type malware \
  | jq -r '.entities[].entity_value'

# All IOCs from clusters mentioning a tool you're hunting
tc threats list --query "cobalt strike" --limit 50 \
  | jq -r '.threats[].cluster_id' \
  | tc threats iocs - \
  | jq -r '.iocs[]'

MSSP — "give me a feed for $CUSTOMER"

# Live ransomware victims into a Slack webhook
tc darkweb ransomware victims --watch --interval 60 \
  | while read line; do
      msg=$(echo "$line" | jq -r '"🔒 new victim: \(.group): \(.name)"')
      curl -s -X POST -d "{\"text\":\"$msg\"}" "$SLACK_WEBHOOK_URL"
    done

# Daily IOC blocklists (cron)
tc iocs feed --type ip     > /etc/blocklists/tc-ips.txt
tc iocs feed --type domain > /etc/blocklists/tc-domains.txt

Engineer — "feed our SIEM"

# Bulk IOC export for SIEM ingest
tc iocs export --format csv > tc-iocs.csv

# Filter to only the IOCs from clusters scoring 80+
tc threats list --limit 100 \
  | jq -r '.threats[] | select(.threat_score >= 80) | .cluster_id' \
  | tc threats iocs - > high-confidence-iocs.json

AI agent — "scoped, budgeted access"

Hand a sub-agent a narrower bearer than your own. The server enforces it — the child cannot escalate scopes or exceed the budget.

TC_SCOPES=threats:read,iocs:read \
TC_SESSION_ID="$(uuidgen)" \
TC_MAX_REQUESTS=50 \
  tc threats list --limit 5

Environment

Var Purpose
TC_API_URL Override API base (default https://api.threatcluster.io)
TC_REFRESH_TOKEN Refresh credential (overrides keyring + file). For CI only.
TC_SCOPES Comma-separated subset of refresh scopes for the bearer.
TC_SESSION_ID Session id for per-session request budgeting.
TC_MAX_REQUESTS Cap requests per session; subsequent ones get 429.
TC_PROPAGATE_AUTH Set to 1 to propagate auth env to subprocesses.
TC_DEBUG Set to 1 for verbose stderr (auth headers redacted).

Shell completion

tc --install-completion bash    # or zsh, fish
exec $SHELL                     # restart your shell
tc thr<TAB>                     # → tc threats

Security notes

  • Refresh credential is never sent on argv (--api-key flag is rejected).
  • Bearer JWTs (15 min ttl) are minted on demand, cached in memory only.
  • The CLI refuses plaintext http:// URLs unless the host is 127.0.0.1/localhost.
  • Auth env vars are scrubbed from subprocess environments unless TC_PROPAGATE_AUTH=1.
  • Credential file is mode 0600 + uid-checked; loose perms are refused.

See the docs for the full reference, and Agent keys & scopes for the security model in detail.

Release flow

See PUBLISHING.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

threatcluster_cli-0.1.1.tar.gz (19.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

threatcluster_cli-0.1.1-py3-none-any.whl (21.7 kB view details)

Uploaded Python 3

File details

Details for the file threatcluster_cli-0.1.1.tar.gz.

File metadata

  • Download URL: threatcluster_cli-0.1.1.tar.gz
  • Upload date:
  • Size: 19.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for threatcluster_cli-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9a9bef6cdbbf2c8574954d4fecb5e1c9c60faac5516e52070cfe5d5fb7296462
MD5 29cd63e21c2b3b95a3965ccb521e8425
BLAKE2b-256 92b51143254fe9ddc94dc465a09c3a2bcd23d4e25101288cc699b018af3418f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for threatcluster_cli-0.1.1.tar.gz:

Publisher: publish.yml on Jam0k/threatcluster-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file threatcluster_cli-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for threatcluster_cli-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 26bbe04ba48dfceb9bb803e9396285c52ecdee8b24929a6dedc9ec80c37d59cb
MD5 7110e3c4461f7217712b5f9ac2e96af2
BLAKE2b-256 97f984b14f5257749530de517197115e5b052bddb3faf0f843514a28dac21cf4

See more details on using hashes here.

Provenance

The following attestation bundles were made for threatcluster_cli-0.1.1-py3-none-any.whl:

Publisher: publish.yml on Jam0k/threatcluster-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page