Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
branches: [ main ]
workflow_dispatch:

permissions:
contents: read

jobs:
coverage:
runs-on: ubuntu-latest
Expand Down
7 changes: 2 additions & 5 deletions docksec/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import sys
import os
import argparse
from typing import Optional

def get_version() -> str:
"""Return the installed package version.
Expand All @@ -23,7 +22,7 @@ def get_version() -> str:
import re
setup_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'setup.py')
with open(setup_path, 'r') as f:
match = re.search(r'version="([^"]+)"', f.read())
match = re.search(r'version\s*=\s*["\']([^"\']+)["\']', f.read())
if match:
return match.group(1)
except Exception: # setup.py missing or unreadable; fall through to unknown
Expand Down Expand Up @@ -81,8 +80,7 @@ def main() -> None:

# Validate image requirement for image-based operations
if (args.image_only or args.scan_only) and not args.image:
operation = "image-only scanning" if args.image_only else "scan-only mode"
print(f"Error: Image name is required for {operation}. Use -i/--image to specify the Docker image.")
print(f"Error: Image name is required for {'image-only scanning' if args.image_only else 'scan-only mode'}. Use -i/--image to specify the Docker image.")
print("Example: docksec --image-only -i myapp:latest")
sys.exit(1)

Expand Down Expand Up @@ -124,7 +122,6 @@ def main() -> None:
from pathlib import Path

# Set up the same components as main.py
logger = get_custom_logger(name='docksec_ai')
llm = get_llm()
Report_llm = llm.with_structured_output(AnalyzesResponse, method="json_mode")
analyser_chain = docker_agent_prompt | Report_llm
Expand Down
3 changes: 1 addition & 2 deletions docksec/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

import os
import logging
from pathlib import Path
from typing import Optional, Dict, Any
from typing import Optional, Any, Dict
from dataclasses import dataclass, field

# Set up logger
Expand Down
7 changes: 2 additions & 5 deletions docksec/docker_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
import sys
import re
from pathlib import Path
from docksec.config import RESULTS_DIR
from docksec.config import docker_score_prompt
from docksec.config import RESULTS_DIR, docker_score_prompt
from docksec.utils import ScoreResponse, get_llm, print_section, get_custom_logger

# Initialize logger
Expand Down Expand Up @@ -158,7 +157,7 @@ def __init__(self, dockerfile_path: str, image_name: str, results_dir: str = RES

# Verify Docker image exists (using validated image_name)
try:
result = subprocess.run(
subprocess.run(
['docker', 'image', 'inspect', self.image_name],
capture_output=True,
check=True,
Expand Down Expand Up @@ -1051,8 +1050,6 @@ def save_results_to_html(self, results: Dict) -> str:
# Sanitize image name for filename
safe_image_name = re.sub(r'[:/.\-]', '_', self.image_name)
output_file = os.path.join(self.RESULTS_DIR, f"{safe_image_name}_security_report.html")
# template_path = os.path.join(os.path.dirname(__file__), 'templates', 'report_template.html')
template_path = os.path.join(os.path.dirname(__file__), 'report_template.html')

try:
from docksec.config import html_template
Expand Down
1 change: 0 additions & 1 deletion docksec/report_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from typing import Dict, List, Optional
from datetime import datetime
from fpdf import FPDF
from pathlib import Path

from docksec.config import RESULTS_DIR, html_template
from docksec.utils import get_custom_logger
Expand Down
2 changes: 0 additions & 2 deletions docksec/score_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
It uses LLM-based analysis to provide comprehensive security scoring.
"""

import logging
import re
from typing import Dict
from docksec.config import docker_score_prompt
from docksec.utils import ScoreResponse, get_llm, get_custom_logger
Expand Down
4 changes: 1 addition & 3 deletions docksec/setup_external_tools.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#!/usr/bin/env python3
import subprocess
import sys
import os
import platform
import shutil
import zipfile
from pathlib import Path
import urllib.request
import stat
import zipfile
import json

def get_os_type():
Expand Down Expand Up @@ -117,7 +116,6 @@ def install_trivy():
# Download URL for Windows
url = f"https://github.com/aquasecurity/trivy/releases/download/v{version}/trivy_{version}_windows-64bit.zip"
zip_path = install_dir / "trivy.zip"
exe_path = install_dir / "trivy.exe"

# Download and extract
print(f"Downloading Trivy v{version}...")
Expand Down
6 changes: 2 additions & 4 deletions docksec/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import logging
import sys
import os
from typing import Union
import time
from typing import Union, List, Optional

# Import OpenAI (required)
try:
Expand Down Expand Up @@ -43,12 +44,9 @@
"Either 'pydantic' or 'langchain-core' must be installed. "
"Install with: pip install pydantic langchain-core"
)
from typing import List, Optional
import time
from tqdm import tqdm
from colorama import Fore, Style, init
from rich.console import Console
from rich.table import Table
from tenacity import (
retry,
stop_after_attempt,
Expand Down
12 changes: 6 additions & 6 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Core dependencies - pinned to specific versions for fast, reliable installs
pydantic==2.13.4
langchain-core==0.3.26
langchain==0.3.13
langchain-openai==0.2.10
langchain-anthropic==0.3.0
langchain-google-genai==2.0.5
langchain-ollama==0.2.0
langchain-core==1.3.3
langchain==1.2.18
langchain-openai==1.2.1
langchain-anthropic==1.4.3
langchain-google-genai==4.2.2
langchain-ollama==1.1.0
python-dotenv==1.2.2
pandas==3.0.2

Expand Down
14 changes: 7 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="docksec",
version="2026.5.6",
version="2026.5.15",
description="AI-Powered Docker Security Analyzer",
long_description=long_description,
long_description_content_type="text/markdown",
Expand All @@ -25,12 +25,12 @@
python_requires=">=3.12",
install_requires=[
"pydantic==2.13.4",
"langchain-core==0.3.26",
"langchain==0.3.13",
"langchain-openai==0.2.10",
"langchain-anthropic==0.3.0",
"langchain-google-genai==2.0.5",
"langchain-ollama==0.2.0",
"langchain-core==1.3.3",
"langchain==1.2.18",
"langchain-openai==1.2.1",
"langchain-anthropic==1.4.3",
"langchain-google-genai==4.2.2",
"langchain-ollama==1.1.0",
"python-dotenv==1.2.2",
"pandas==3.0.2",
"tqdm==4.67.3",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_docker_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_check_tools_missing(self, mock_subprocess):
# Mock FileNotFoundError for missing tool
mock_subprocess.side_effect = FileNotFoundError()

dockerfile = self.create_test_dockerfile()
self.create_test_dockerfile()

with patch('docksec.docker_scanner.get_llm'):
scanner = DockerSecurityScanner.__new__(DockerSecurityScanner)
Expand Down
Loading