Metadata-Version: 2.4
Name: jordan-devguard
Version: 0.5.2
Summary: Local-first security assistant for developers
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: typer>=0.12
Requires-Dist: pydantic>=2.0
Requires-Dist: rich>=13.0
Requires-Dist: packaging>=23.0
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: mypy; extra == "dev"

Parfait ! Voici la version **sans emojis** et **professionnelle**.



## ÉTAPE 1 : README PROFESSIONNEL (SANS EMOJIS)


cd ~/Desktop/securityProjet/devguard
nano README.md


# DevGuard

[![PyPI version](https://badge.fury.io/py/jordan-devguard.svg)](https://badge.fury.io/py/jordan-devguard)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

> Secure your code before you deploy it.

DevGuard is a local-first security assistant for developers. It scans your project for vulnerabilities, secrets, and misconfigurations before you deploy to production.



## Features

| Scanner | Description |
|---------|-------------|
| Secrets | AWS keys, JWT tokens, passwords, private keys |
| Django | DEBUG=True, SECRET_KEY, CORS, CSRF |
| Docker | Root user, privileged mode, sensitive ports |
| Dependencies | Vulnerable packages (CVE detection) |
| Laravel | APP_DEBUG, APP_KEY, DB_PASSWORD |
| Node.js | Dangerous scripts, JWT_SECRET |
| React/Next.js | NEXT_PUBLIC_ exposure |
| Vue.js | VUE_APP_ exposure |
| Symfony | APP_ENV, APP_SECRET |
| Go | Hardcoded secrets, TLS disabled |
| PHP | Hardcoded passwords |



## Installation


pip install jordan-devguard


Requirements: Python 3.8+



## Usage

### Basic scan


devguard scan .


### Scan a specific project


devguard scan /path/to/project


### Generate HTML report


devguard scan . --format html --output report.html


### Generate JSON report


devguard scan . --format json --output report.json


### Filter by severity


devguard scan . --severity CRITICAL
devguard scan . --severity HIGH


### Fail on severity (for CI/CD)


devguard scan . --fail-on HIGH
# Exit code 1 if any HIGH or CRITICAL issue found


### List available plugins


devguard plugins


### Display version


devguard version


## Example Output

>> Scanning: ./my-project

Project types detected:
  + python
  + docker
  + plugin:laravel

Security Scan Results (5 issues)
+----------+--------------+-------------------------------------+
| CRITICAL | SECRET-AWS   | AWS Access Key detected             |
| HIGH     | DJANGO-001   | DEBUG=True in production            |
| HIGH     | LARAVEL-001  | APP_DEBUG=true in production        |
| MEDIUM   | DOCKER-004   | Using 'latest' tag                  |
| LOW      | DOCKER-008   | No USER directive                   |
+----------+--------------+-------------------------------------+

Security Score: 45/100
5 issues found


## Scoring System

| Score | Grade |
|-------|-------|
| 90-100 | Excellent |
| 75-89 | Good |
| 50-74 | Needs improvement |
| 25-49 | Poor |
| 0-24 | Critical |



## CI/CD Integration

### GitHub Actions


name: Security Scan

on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.10'
      - name: Install DevGuard
        run: pip install jordan-devguard
      - name: Scan
        run: devguard scan . --fail-on HIGH




## Plugins

DevGuard supports plugins. List available plugins:

devguard plugins


### Create your own plugin

n
# ~/.devguard/plugins/my_plugin.py
from devguard.plugins.base import PluginScanner
from devguard.core.finding import Finding, Severity


class MyScanner(PluginScanner):
    name = "my_scanner"
    version = "1.0.0"
    
    def is_applicable(self) -> bool:
        return (self.project_path / "my-config.json").exists()
    
    def scan(self):
        findings = []
        # Your scan logic
        return findings




## Configuration

Create a `.devguard.yml` file in your project root:

```yaml
exclude:
  - "tests/"
  - "docs/"

ignore_rules:
  - "DOCKER-008"
  - "DEP-001"

severity:
  fail_on: HIGH
  min_score: 70
```



## Contributing

Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).



## License

MIT License - see [LICENSE](LICENSE)



## Author

Jordan Fokou Fosso

- GitHub: https://github.com/udcw
- PyPI: https://pypi.org/project/jordan-devguard/



Made in Cameroon.



## ÉTAPE 2 : CONFIG YAML

nano src/devguard/core/project_config.py


```python
"""Configuration projet DevGuard (.devguard.yml)."""
from pathlib import Path
from typing import List, Optional

try:
    import yaml
except ImportError:
    yaml = None


class ProjectConfig:
    """Configuration lue depuis .devguard.yml."""
    
    def __init__(self, project_path: str):
        self.project_path = Path(project_path)
        self.config_file = self.project_path / ".devguard.yml"
        
        # Valeurs par defaut
        self.exclude: List[str] = []
        self.ignore_rules: List[str] = []
        self.fail_on: Optional[str] = None
        self.min_score: Optional[int] = None
        
        self._load()
    
    def _load(self):
        """Charge le fichier de config."""
        if not self.config_file.exists():
            return
        
        if yaml is None:
            return
        
        try:
            data = yaml.safe_load(self.config_file.read_text(encoding='utf-8'))
            if not data:
                return
            
            self.exclude = data.get("exclude", [])
            self.ignore_rules = data.get("ignore_rules", [])
            
            severity = data.get("severity", {})
            self.fail_on = severity.get("fail_on")
            self.min_score = severity.get("min_score")
        except Exception:
            pass
    
    def is_rule_ignored(self, rule_id: str) -> bool:
        """Verifie si une regle est ignoree."""
        return rule_id in self.ignore_rules
    
    def filter_findings(self, findings):
        """Filtre les findings selon la config."""
        return [f for f in findings if not self.is_rule_ignored(f.rule_id)]
```



## ÉTAPE 3 : EXEMPLE .devguard.yml

```bash
cat > ~/Desktop/securityProjet/devguard/.devguard.yml.example << 'EOF'
# DevGuard Configuration File
# Copy this to .devguard.yml and customize

# Files/directories to exclude
exclude:
  - "tests/"
  - "docs/"
  - "*.md"

# Rules to ignore (by rule_id)
ignore_rules:
  - "DOCKER-008"
  - "DEP-001"

# Severity settings
severity:
  fail_on: HIGH
  min_score: 70
EOF
```

---

## ÉTAPE 4 : SCANNER AVEC CONFIG

```bash
nano src/devguard/core/scanner.py
```

```python
from pathlib import Path
from typing import List

from devguard.core.finding import Finding
from devguard.core.detector import ProjectDetector
from devguard.core.project_config import ProjectConfig
from devguard.scanners.secrets import SecretsScanner
from devguard.scanners.django import DjangoScanner
from devguard.scanners.docker import DockerScanner
from devguard.scanners.dependencies import DependencyScanner
from devguard.plugins.manager import PluginManager


class SecurityScanner:
    def __init__(self, project_path: str):
        self.path = Path(project_path)
        self.project_types = ProjectDetector(project_path).detect()
        self.config = ProjectConfig(project_path)
        
        self.scanners = []
        
        # Scanners integres
        self.scanners.append(SecretsScanner(project_path))
        
        django_scanner = DjangoScanner(project_path)
        if django_scanner.is_applicable():
            self.scanners.append(django_scanner)
            if "django" not in self.project_types:
                self.project_types.append("django")
        
        docker_scanner = DockerScanner(project_path)
        if docker_scanner.is_applicable():
            self.scanners.append(docker_scanner)
            if "docker" not in self.project_types:
                self.project_types.append("docker")
        
        dep_scanner = DependencyScanner(project_path)
        if dep_scanner.is_applicable():
            self.scanners.append(dep_scanner)
            if "dependencies" not in self.project_types:
                self.project_types.append("dependencies")
        
        # Plugins
        try:
            plugin_manager = PluginManager(project_path)
            for plugin in plugin_manager.get_applicable_plugins():
                self.scanners.append(plugin)
                plugin_type = f"plugin:{plugin.name}"
                if plugin_type not in self.project_types:
                    self.project_types.append(plugin_type)
        except Exception:
            pass
    
    def scan(self) -> List[Finding]:
        if not self.path.exists():
            raise FileNotFoundError(f"Project not found: {self.path}")
        
        all_findings = []
        
        for scanner in self.scanners:
            try:
                findings = scanner.scan()
                all_findings.extend(findings)
            except Exception:
                pass
        
        # Appliquer les regles ignorees
        all_findings = self.config.filter_findings(all_findings)
        
        return all_findings
    
    def get_project_types(self) -> List[str]:
        return self.project_types
```

---

## ÉTAPE 5 : DÉPENDANCES

```bash
nano pyproject.toml
```

Ajoute `pyyaml` :

```toml
dependencies = [
    "typer>=0.12",
    "pydantic>=2.0",
    "rich>=13.0",
    "packaging>=23.0",
    "pyyaml>=6.0"
]
```

---

## ÉTAPE 6 : RÉINSTALLER ET TESTER

```bash
cd ~/Desktop/securityProjet/devguard
source .venv/Scripts/activate
pip install -e . --force-reinstall
devguard scan .
```

---

## ÉTAPE 7 : VERSION ET PUBLICATION

```bash
cd ~/Desktop/securityProjet/devguard && \
source .venv/Scripts/activate && \
sed -i 's/version = "0.4.0"/version = "0.5.0"/' pyproject.toml && \
echo '__version__ = "0.5.0"' > src/devguard/__init__.py && \
pip install -e . --force-reinstall && \
rm -rf dist/ build/ *.egg-info && \
python -m build && \
twine upload dist/* -u __token__ -p pypi-TON_TOKEN && \
pip install --upgrade jordan-devguard && \
devguard version
```

---

## ÉTAPE 8 : TESTER LA CONFIG

```bash
cd /tmp/laravel-bad

cat > .devguard.yml << 'EOF'
ignore_rules:
  - "LARAVEL-002"
  - "SECRET-PASSWORD"
EOF

devguard scan .
```

Les regles `LARAVEL-002` et `SECRET-PASSWORD` seront ignorees.

---

