mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-02-09 02:30:43 +00:00
feat(threatscore): support user token
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# ThreatScore Compliance Report Generator
|
||||
|
||||
This tool generates a PDF compliance report using Prowler's API endpoints, summarizing compliance requirements, risk levels, and findings for a given scan and compliance framework.
|
||||
This tool generates a compliance PDF report using Prowler's API endpoints, summarizing requirements, risk levels, and findings for a given scan and compliance framework.
|
||||
|
||||
## Features
|
||||
- Authenticates with the Prowler API using email and password
|
||||
- Retrieves compliance requirements and attributes for a given scan and compliance framework
|
||||
- Generates a visually rich PDF report, including:
|
||||
- Authenticate with the Prowler API using email+password or token
|
||||
- Retrieve compliance requirements and attributes for a given scan and framework
|
||||
- Generate a visually rich PDF report, including:
|
||||
- Compliance summary and description
|
||||
- Compliance score by section (with charts)
|
||||
- Critical failed requirements (with risk and weight)
|
||||
@@ -23,30 +23,34 @@ pip install matplotlib requests reportlab
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python3 util/compliance_report/generate_threatscore_report.py \
|
||||
python3 util/compliance_report/threatscore_report_generator.py \
|
||||
--scan-id <scan_id> \
|
||||
--compliance-id <compliance_id> \
|
||||
--email <email> \
|
||||
--password <password> \
|
||||
[--token <token>] \
|
||||
[--output <output_path>] \
|
||||
[--base-url <base_url>] \
|
||||
[--only-failed] \
|
||||
[--min-risk-level <level>]
|
||||
```
|
||||
|
||||
> **Note:** You must provide either both `--email` and `--password`, or a `--token`. One of these authentication methods is required. If you provide a token, email and password are ignored.
|
||||
|
||||
### Arguments
|
||||
- `--scan-id` (required): ID of the scan executed by Prowler.
|
||||
- `--compliance-id` (required): Compliance framework ID (e.g., `prowler_threatscore_azure`, `nis2_azure`).
|
||||
- `--email` (required): Email for API authentication.
|
||||
- `--password` (required): Password for API authentication.
|
||||
- `--email` (required*): Email for API authentication (*required if `--token` is not used).
|
||||
- `--password` (required*): Password for API authentication (*required if `--token` is not used).
|
||||
- `--token` (required*): JWT token for authentication (*required if `--email` and `--password` are not used).
|
||||
- `--output` (optional): Output PDF file path (default: `threatscore_report.pdf`).
|
||||
- `--base-url` (optional): Base URL for the API (default: `http://localhost:8080`).
|
||||
- `--only-failed` (optional): Only include failed requirements in the report.
|
||||
- `--min-risk-level` (optional): Minimum risk level for critical failed requirements (default: 4).
|
||||
- `--min-risk-level` (optional): Minimum risk level to show critical failed requirements (default: 4).
|
||||
|
||||
### Example
|
||||
```bash
|
||||
python3 util/compliance_report/generate_threatscore_report.py \
|
||||
python3 util/compliance_report/threatscore_report_generator.py \
|
||||
--scan-id 12345678-1234-5678-1234-567812345678 \
|
||||
--compliance-id prowler_threatscore_azure \
|
||||
--email user@example.com \
|
||||
@@ -57,6 +61,15 @@ python3 util/compliance_report/generate_threatscore_report.py \
|
||||
--min-risk-level 4
|
||||
```
|
||||
|
||||
Or using a token:
|
||||
```bash
|
||||
python3 util/compliance_report/threatscore_report_generator.py \
|
||||
--scan-id 12345678-1234-5678-1234-567812345678 \
|
||||
--compliance-id prowler_threatscore_azure \
|
||||
--token eyJhbGciOi... \
|
||||
--output my_report.pdf
|
||||
```
|
||||
|
||||
## Output
|
||||
- The script will generate a PDF file with:
|
||||
- Compliance framework summary
|
||||
@@ -65,6 +78,6 @@ python3 util/compliance_report/generate_threatscore_report.py \
|
||||
- Detailed breakdown of each requirement and its findings
|
||||
|
||||
## Notes
|
||||
- The script authenticates with the API and retrieves all necessary data automatically.
|
||||
- If you encounter authentication errors, check your email, password, and API URL.
|
||||
- For more details, see the script source: `util/compliance_report/generate_threatscore_report.py`
|
||||
- The script can authenticate with email/password or directly with a JWT token. **One of these authentication methods is mandatory.**
|
||||
- If you encounter authentication errors, check your credentials, token, and API URL.
|
||||
- For more details, see the source code: `util/compliance_report/threatscore_report_generator.py`
|
||||
|
||||
@@ -44,6 +44,7 @@ def generate_threatscore_report(
|
||||
output_path: str,
|
||||
email: str,
|
||||
password: str,
|
||||
token: str,
|
||||
base_url: str,
|
||||
only_failed: bool = True,
|
||||
min_risk_level: int = 4,
|
||||
@@ -57,6 +58,7 @@ def generate_threatscore_report(
|
||||
- output_path: Output PDF file path (e.g., "threatscore_report.pdf").
|
||||
- email: Email for the API authentication.
|
||||
- password: Password for the API.
|
||||
- token: Token for the API.
|
||||
- base_url: Base URL for the API.
|
||||
- only_failed: If True, only requirements with status "FAIL" will be included in the list of requirements.
|
||||
- min_risk_level: Minimum risk level for critical failed requirements.
|
||||
@@ -134,40 +136,46 @@ def generate_threatscore_report(
|
||||
textColor=colors.Color(0.2, 0.2, 0.2),
|
||||
fontName="PlusJakartaSans",
|
||||
)
|
||||
|
||||
url_credentials = f"{base_url}/api/v1/tokens"
|
||||
payload = {
|
||||
"data": {
|
||||
"type": "tokens",
|
||||
"attributes": {
|
||||
"email": email,
|
||||
"password": password,
|
||||
},
|
||||
if not token:
|
||||
if not email or not password:
|
||||
raise Exception("Email and password are required to generate a token")
|
||||
url_credentials = f"{base_url}/api/v1/tokens"
|
||||
payload = {
|
||||
"data": {
|
||||
"type": "tokens",
|
||||
"attributes": {
|
||||
"email": email,
|
||||
"password": password,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
resp_credentials = requests.post(
|
||||
url_credentials,
|
||||
json=payload,
|
||||
headers={"Content-Type": "application/vnd.api+json"},
|
||||
).json()
|
||||
if resp_credentials.get("errors"):
|
||||
print(resp_credentials.get("errors"))
|
||||
raise Exception(resp_credentials.get("errors"))
|
||||
token = resp_credentials.get("data", {}).get("attributes", {}).get("access")
|
||||
resp_credentials = requests.post(
|
||||
url_credentials,
|
||||
json=payload,
|
||||
headers={"Content-Type": "application/vnd.api+json"},
|
||||
).json()
|
||||
if resp_credentials.get("errors"):
|
||||
print(resp_credentials.get("errors"))
|
||||
raise Exception(resp_credentials.get("errors"))
|
||||
token = resp_credentials.get("data", {}).get("attributes", {}).get("access")
|
||||
|
||||
url_reqs = f"{base_url}/api/v1/compliance-overviews/requirements?filter[compliance_id]={compliance_id}&filter[scan_id]={scan_id}"
|
||||
resp_reqs = (
|
||||
requests.get(url_reqs, headers={"Authorization": f"Bearer {token}"})
|
||||
.json()
|
||||
.get("data", [])
|
||||
)
|
||||
try:
|
||||
url_reqs = f"{base_url}/api/v1/compliance-overviews/requirements?filter[compliance_id]={compliance_id}&filter[scan_id]={scan_id}"
|
||||
resp_reqs = (
|
||||
requests.get(url_reqs, headers={"Authorization": f"Bearer {token}"})
|
||||
.json()
|
||||
.get("data", [])
|
||||
)
|
||||
|
||||
url_attrs = f"{base_url}/api/v1/compliance-overviews/attributes?filter[compliance_id]={compliance_id}"
|
||||
resp_attrs = (
|
||||
requests.get(url_attrs, headers={"Authorization": f"Bearer {token}"})
|
||||
.json()
|
||||
.get("data", [])
|
||||
)
|
||||
url_attrs = f"{base_url}/api/v1/compliance-overviews/attributes?filter[compliance_id]={compliance_id}"
|
||||
resp_attrs = (
|
||||
requests.get(url_attrs, headers={"Authorization": f"Bearer {token}"})
|
||||
.json()
|
||||
.get("data", [])
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise Exception(e)
|
||||
|
||||
compliance_name = resp_reqs[0]["attributes"]["framework"]
|
||||
compliance_version = resp_reqs[0]["attributes"]["version"]
|
||||
@@ -876,6 +884,11 @@ if __name__ == "__main__":
|
||||
action="store_true",
|
||||
help="Only include failed requirements in the list of requirements",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--token",
|
||||
default="",
|
||||
help="Token for the API",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--base-url",
|
||||
default="http://localhost:8080",
|
||||
@@ -895,6 +908,7 @@ if __name__ == "__main__":
|
||||
args.output,
|
||||
args.email,
|
||||
args.password,
|
||||
args.token,
|
||||
args.base_url,
|
||||
args.only_failed,
|
||||
args.min_risk_level,
|
||||
|
||||
Reference in New Issue
Block a user