Translate any security/IaC tool's output file into human language — offline, no cluster, one grammar across tools
Project description
whyq
The artifact translator. You already ran the scanner — whyq explains the file it left behind, offline, one grammar across every tool.
whyq explain <file> reads a security/IaC tool's output file — trivy.json and falco.json today, plan JSON next — and returns six things for every finding:
| 何が (what) | なぜ (why) | 危険度 (severity) | まず確認 (check) | 修正 (fix) | 参考 (refs) |
|---|
$ trivy image --format json -o scan.json app:latest
$ whyq explain scan.json
■ openssl: possible denial of service in X.509 name checks [HIGH] (CVE-2024-6119)
何が: libssl3 — vulnerability
なぜ: A known vulnerability affects libssl3 3.0.2-0ubuntu1.15. A fixed version
(3.0.2-0ubuntu1.18) is available, so this is actionable now.
確認: Confirm libssl3 is actually reachable in your runtime path, and check
whether the installed version is really in use.
修正: remedify <scan.json> (OS-package remediation is remedify's job)
参考: https://avd.aquasec.com/nvd/cve-2024-6119
Where whyq sits: detect → understand → fix
whyq is the understanding layer of a three-part story about contextualizing detection:
detect ──────────► understand ──────────► fix
(tfdrift, trivy, (whyq) (remedify)
falco, sysdig…) what/why/severity distro-aware
/check/fix/refs remediation commands
- tfdrift-falco and other scanners detect.
- whyq turns their raw output into something a human can act on.
- remedify owns the last mile — the exact, OS-specific fix command.
whyq deliberately does not re-implement OS-package remediation. When a finding is an OS-package vulnerability, its 修正 field hands off to remedify. whyq stays the cross-tool understanding layer; remedify owns vuln→fix. The --format json output is shaped so remedify (and CI) can consume it directly.
Why not k8sgpt / HolmesGPT?
The space isn't empty, but the wedge is real and narrow:
- k8sgpt reads a live Kubernetes cluster. It can't read a file you already have.
- HolmesGPT connects to your alert sources and investigates autonomously — a heavy agent.
- whyq reads the artifact already sitting on your disk. No cluster, no connection, no SaaS — and one grammar across tools (trivy → falco → plan JSON → …), not a single domain.
"Light / local / no-SaaS / brew" is not the flag here — k8sgpt already owns that. whyq's flag is one thing: artifact translator, cross-tool.
Quick start
# zero-install (stdlib only, no dependencies)
git clone https://github.com/higakikeita/whyq && cd whyq
python3 whyq.py explain examples/trivy.json
# machine-readable (remedify-ready / CI)
python3 whyq.py explain scan.json --format json
python3 whyq.py explain scan.json --min-severity HIGH
LLM: BYO-key, and honest about it
Turning a finding into good prose (なぜ / まず確認) benefits from an LLM — so whyq will not claim "no SaaS" unconditionally. Instead:
- Default is offline. With no flag, whyq uses deterministic templates. Nothing leaves your machine.
- Opt in explicitly with your own key/model — data goes only where you point it:
whyq explain scan.json --llm anthropic # uses $ANTHROPIC_API_KEY
whyq explain scan.json --llm ollama:llama3.2 # fully local, no key
The deterministic half — parse, severity, fix command, references — never touches the LLM and is regression-tested. Only the prose is model-generated. That keeps the audit trail intact ("the deterministic tool computes, the AI explains").
Supported inputs
| Tool | Status |
|---|---|
| Trivy JSON (vulnerabilities · misconfigurations · secrets) | ✅ |
| Falco JSON / JSONL (runtime events; MITRE ATT&CK tags → refs) | ✅ |
| Terraform plan JSON | planned |
A scan finding and a runtime event — two different tools, two different domains — land in the same normalized shape and flow through the same six-field output. That is the cross-tool wedge, not a slogan:
whyq explain trivy.json # vulnerabilities & misconfig
whyq explain falco.json # runtime events (JSONL, as Falco writes it)
Adding a format is a parser plus a detector — the normalized finding and every output path stay the same.
Development
python3 -m unittest discover tests -v
The deterministic core is pinned by regression tests; the LLM layer is mocked. See tests/.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whyq-0.1.0.tar.gz.
File metadata
- Download URL: whyq-0.1.0.tar.gz
- Upload date:
- Size: 13.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68c57f1d1b62e4a0255dc7671c497c40a3c6ece856ff64ed12641eb8389d865b
|
|
| MD5 |
8df7c653b64374e7d47908d8cfd81477
|
|
| BLAKE2b-256 |
28c088bf435176d832091d4fc26cbb0ea7bc06da246dad75af34a30ba063e1a2
|
Provenance
The following attestation bundles were made for whyq-0.1.0.tar.gz:
Publisher:
release.yml on higakikeita/whyq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whyq-0.1.0.tar.gz -
Subject digest:
68c57f1d1b62e4a0255dc7671c497c40a3c6ece856ff64ed12641eb8389d865b - Sigstore transparency entry: 2211925188
- Sigstore integration time:
-
Permalink:
higakikeita/whyq@8568868e2308723949a0a5d0df71b3b7a56e54ac -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/higakikeita
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8568868e2308723949a0a5d0df71b3b7a56e54ac -
Trigger Event:
release
-
Statement type:
File details
Details for the file whyq-0.1.0-py3-none-any.whl.
File metadata
- Download URL: whyq-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8b75ad32e79bf6d3855824819853099f2fcbb47fa382ea53ace5959ea7c2ef5
|
|
| MD5 |
6c3707df1fb7a56be54ef95ed00748a6
|
|
| BLAKE2b-256 |
089749303ead71219d579e286f508f27b3ef0499e7a0d75a5912076dee57555e
|
Provenance
The following attestation bundles were made for whyq-0.1.0-py3-none-any.whl:
Publisher:
release.yml on higakikeita/whyq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whyq-0.1.0-py3-none-any.whl -
Subject digest:
f8b75ad32e79bf6d3855824819853099f2fcbb47fa382ea53ace5959ea7c2ef5 - Sigstore transparency entry: 2211925210
- Sigstore integration time:
-
Permalink:
higakikeita/whyq@8568868e2308723949a0a5d0df71b3b7a56e54ac -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/higakikeita
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8568868e2308723949a0a5d0df71b3b7a56e54ac -
Trigger Event:
release
-
Statement type: