Skip to content

Commit f2a90cc

Browse files
committed
chore: fix all lint errors, rewrite README, add release workflow
- Fix all 47 ruff lint errors (unused imports, ambiguous variables) - Rewrite README.md documenting all 26 commands - Add CI badges (CI status, license, Python version) - Add PyPI release workflow with trusted publishing - Remove stale roadmap (all items implemented) - Fix GitHub URLs to kirankotari/ossguard
1 parent 9a80135 commit f2a90cc

24 files changed

Lines changed: 181 additions & 133 deletions

.github/workflows/release.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.12"
20+
- run: pip install -e ".[dev]"
21+
- run: pytest --tb=short -q
22+
23+
build:
24+
needs: test
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: actions/setup-python@v5
29+
with:
30+
python-version: "3.12"
31+
- run: pip install build
32+
- run: python -m build
33+
- uses: actions/upload-artifact@v4
34+
with:
35+
name: dist
36+
path: dist/
37+
38+
publish:
39+
needs: build
40+
runs-on: ubuntu-latest
41+
environment: pypi
42+
permissions:
43+
id-token: write
44+
steps:
45+
- uses: actions/download-artifact@v4
46+
with:
47+
name: dist
48+
path: dist/
49+
- uses: pypa/gh-action-pypi-publish@release/v1
50+
51+
github-release:
52+
needs: publish
53+
runs-on: ubuntu-latest
54+
permissions:
55+
contents: write
56+
steps:
57+
- uses: actions/checkout@v4
58+
- name: Create GitHub Release
59+
env:
60+
GH_TOKEN: ${{ github.token }}
61+
run: gh release create "${{ github.ref_name }}" --generate-notes

README.md

Lines changed: 98 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1-
# ossguard
1+
# OSSGuard
22

33
**One CLI to guard any OSS project with OpenSSF security best practices — bootstrap, scan, and monitor.**
44

5-
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/0000/badge)](https://www.bestpractices.dev/)
5+
[![CI](https://github.com/kirankotari/ossguard/actions/workflows/ci.yml/badge.svg)](https://github.com/kirankotari/ossguard/actions/workflows/ci.yml)
6+
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
7+
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
68

7-
> *ossguard implements OpenSSF best practices and is intended for future contribution to the OpenSSF community.*
9+
> *OSSGuard implements OpenSSF best practices and is intended for future contribution to the OpenSSF community.*
810
911
---
1012

1113
## The Problem
1214

1315
The [OpenSSF](https://openssf.org/) ecosystem has 30+ excellent tools, frameworks, and guides for securing open source software — Scorecard, Sigstore, SLSA, SBOM, CodeQL, Dependabot, and more.
1416

15-
But setting them all up manually takes **hours**. And once set up, there's no unified way to monitor your dependency health or track security posture over time.
17+
But setting them all up manually takes **hours**. And once set up, there's no unified way to monitor dependency health, track compliance, or assess supply-chain risk.
1618

17-
**ossguard** solves this with a single CLI:
19+
**OSSGuard** solves this with **26 commands** covering the full security lifecycle:
1820

1921
1. **Bootstrap** — set up all OpenSSF security configurations in one command
20-
2. **Scan** — audit your project's security posture
21-
3. **Deps** *(coming soon)* — analyze dependency health across Scorecard, OSV, and deps.dev
22+
2. **Analyze** — audit security posture, dependencies, vulnerabilities, and compliance
23+
3. **Remediate** — auto-fix issues, generate reports, and enforce policies
2224

2325
## Quick Start
2426

@@ -32,115 +34,125 @@ ossguard init
3234

3335
# Scan your project to see what's missing
3436
ossguard scan
37+
38+
# Run a full security audit
39+
ossguard audit
40+
41+
# Check OSPS Baseline compliance
42+
ossguard baseline
3543
```
3644

37-
## What It Does
45+
## Commands
3846

39-
`ossguard init` auto-detects your project and creates:
47+
### Core
4048

41-
| File | Purpose | OpenSSF Reference |
42-
|------|---------|-------------------|
43-
| `SECURITY.md` | Vulnerability disclosure policy | [CVD Guide](https://github.com/ossf/oss-vulnerability-guide) |
44-
| `.github/workflows/scorecard.yml` | Automated security scoring | [Scorecard](https://scorecard.dev/) |
45-
| `.github/dependabot.yml` | Dependency update automation | [Best Practices](https://best.openssf.org/) |
46-
| `.github/workflows/codeql.yml` | Code scanning for vulnerabilities | [Security Tooling WG](https://github.com/ossf/wg-security-tooling) |
47-
| `.github/workflows/sbom.yml` | Software Bill of Materials generation | [SBOM Everywhere](https://github.com/ossf/sbom-everywhere) |
48-
| `.github/workflows/sigstore.yml` | Cryptographic signing of releases | [Sigstore](https://sigstore.dev/) |
49-
| `.github/BRANCH_PROTECTION.md` | Branch protection setup guide | [SCM Best Practices](https://best.openssf.org/SCM-BestPractices/) |
49+
| Command | Description |
50+
|---------|-------------|
51+
| `ossguard init` | Bootstrap OpenSSF security configs (SECURITY.md, Scorecard, Dependabot, CodeQL, SBOM, Sigstore, branch protection) |
52+
| `ossguard scan` | Read-only security posture scan |
53+
| `ossguard version` | Show version |
5054

51-
## Features
55+
### Dependency Analysis
5256

53-
### Auto-Detection
54-
Automatically detects:
55-
- **Languages**: Python, JavaScript/TypeScript, Go, Rust, Java, C/C++, Ruby, PHP, C#, and more
56-
- **Package Managers**: npm, yarn, pnpm, pip, poetry, cargo, go modules, maven, gradle, etc.
57-
- **Frameworks**: React, Vue, Angular, Next.js, Django, Flask, FastAPI, Express, etc.
58-
- **Existing Security Setup**: Won't overwrite existing configurations
57+
| Command | Description |
58+
|---------|-------------|
59+
| `ossguard deps` | Dependency health analysis — vulns (OSV), outdated packages, risk scores (deps.dev) |
60+
| `ossguard drift` | SBOM diff between releases — detect added, removed, and changed dependencies |
61+
| `ossguard watch` | Continuous vulnerability monitoring from an SBOM (post-deployment watch) |
62+
| `ossguard tpn` | Generate third-party notices from project dependencies |
5963

60-
### Smart Defaults
61-
- Scorecard workflow with weekly schedule and SARIF upload
62-
- Dependabot configured for your specific ecosystems
63-
- CodeQL with language-specific analysis and security-extended queries
64-
- SBOM in both SPDX and CycloneDX formats
65-
- Sigstore with Python-specific or generic cosign signing
66-
- SECURITY.md following OpenSSF CVD best practices
64+
### Security Analysis
6765

68-
### Commands
66+
| Command | Description |
67+
|---------|-------------|
68+
| `ossguard audit` | Comprehensive security audit (scan + deps + reachability combined) |
69+
| `ossguard reach` | Filter vulnerabilities by runtime reachability (static import analysis) |
70+
| `ossguard secrets` | Scan for leaked credentials and secrets (24 detection rules) |
6971

70-
```bash
71-
# Initialize with all defaults
72-
ossguard init
72+
### Compliance & Frameworks
7373

74-
# Specify a project path
75-
ossguard init /path/to/project
74+
| Command | Description |
75+
|---------|-------------|
76+
| `ossguard baseline` | Check against OSPS Security Baseline (34 controls, Levels 1-3) |
77+
| `ossguard badge` | Assess readiness for the OpenSSF Best Practices Badge |
78+
| `ossguard slsa` | Assess SLSA Build Level (Levels 1-4, 12 requirements) |
79+
| `ossguard maturity` | S2C2F supply chain maturity assessment (22 practices, Levels 1-4) |
80+
| `ossguard license` | Dependency license compliance and conflict detection |
81+
| `ossguard policy` | Org-wide security policy enforcement (JSON config) |
7682

77-
# Set security contact email
78-
ossguard init --email security@example.com
83+
### Supply Chain
7984

80-
# Skip specific components
81-
ossguard init --skip-scorecard --skip-codeql
85+
| Command | Description |
86+
|---------|-------------|
87+
| `ossguard supply-chain` | Malicious package detection + typosquatting analysis |
88+
| `ossguard pin` | Pin GitHub Actions to commit SHAs (resolve tags to full SHAs) |
89+
| `ossguard update` | Security-prioritized dependency update suggestions |
8290

83-
# Preview without writing files
84-
ossguard init --dry-run
91+
### Generation
8592

86-
# Overwrite existing files
87-
ossguard init --force
93+
| Command | Description |
94+
|---------|-------------|
95+
| `ossguard insights` | Generate or validate SECURITY-INSIGHTS.yml |
96+
| `ossguard sbom-gen` | Generate local SBOM (SPDX 2.3 or CycloneDX 1.5) |
97+
| `ossguard ci` | Generate unified CI security pipeline (GitHub Actions) |
98+
| `ossguard report` | Export HTML or JSON compliance report |
99+
| `ossguard fuzz` | Fuzzing readiness check + starter harness generation (7 languages) |
88100

89-
# Scan and report current security posture
90-
ossguard scan
91-
```
101+
### Container & Comparison
102+
103+
| Command | Description |
104+
|---------|-------------|
105+
| `ossguard container` | Dockerfile security linting (12 rules) |
106+
| `ossguard compare` | Side-by-side security posture comparison of two projects |
107+
| `ossguard fix` | Auto-remediate common security issues |
92108

93-
## Supported Languages
109+
## Auto-Detection
94110

95-
| Language | CodeQL | Dependabot | Sigstore |
96-
|----------|--------|------------|----------|
97-
| Python | Yes | pip | Python-specific |
98-
| JavaScript/TypeScript | Yes | npm | Generic (cosign) |
99-
| Go | Yes | gomod | Generic (cosign) |
100-
| Java/Kotlin | Yes | maven/gradle | Generic (cosign) |
101-
| Rust | No | cargo | Generic (cosign) |
102-
| C/C++ | Yes | N/A | Generic (cosign) |
103-
| Ruby | Yes | bundler | Generic (cosign) |
104-
| C# | Yes | nuget | Generic (cosign) |
111+
OSSGuard automatically detects:
112+
113+
- **Languages**: Python, JavaScript/TypeScript, Go, Rust, Java, C/C++, Ruby, PHP, C#
114+
- **Package Managers**: npm, yarn, pnpm, pip, poetry, cargo, go modules, maven, gradle
115+
- **Frameworks**: React, Vue, Angular, Next.js, Django, Flask, FastAPI, Express
116+
- **Existing Security Setup**: Won't overwrite existing configurations
117+
118+
## What `ossguard init` Generates
119+
120+
| File | Purpose | OpenSSF Reference |
121+
|------|---------|-------------------|
122+
| `SECURITY.md` | Vulnerability disclosure policy | [CVD Guide](https://github.com/ossf/oss-vulnerability-guide) |
123+
| `.github/workflows/scorecard.yml` | Automated security scoring | [Scorecard](https://scorecard.dev/) |
124+
| `.github/dependabot.yml` | Dependency update automation | [Best Practices](https://best.openssf.org/) |
125+
| `.github/workflows/codeql.yml` | Code scanning for vulnerabilities | [Security Tooling WG](https://github.com/ossf/wg-security-tooling) |
126+
| `.github/workflows/sbom.yml` | Software Bill of Materials generation | [SBOM Everywhere](https://github.com/ossf/sbom-everywhere) |
127+
| `.github/workflows/sigstore.yml` | Cryptographic signing of releases | [Sigstore](https://sigstore.dev/) |
128+
| `.github/BRANCH_PROTECTION.md` | Branch protection setup guide | [SCM Best Practices](https://best.openssf.org/SCM-BestPractices/) |
129+
130+
## How It Relates to OpenSSF
131+
132+
OSSGuard is **not** a replacement for any OpenSSF project. It's a **unifier** — it makes it trivially easy to adopt the best practices and tools that OpenSSF working groups have built:
133+
134+
- **Best Practices WG** — SECURITY.md template, Best Practices Badge assessment
135+
- **Security Tooling WG** — CodeQL setup, SBOM generation, secret scanning
136+
- **Supply Chain Integrity WG** — Sigstore signing, SLSA assessment, S2C2F maturity
137+
- **Vulnerability Disclosures WG** — CVD-compliant SECURITY.md
138+
- **Securing Software Repos WG** — Dependabot, branch protection, GitHub Actions pinning
139+
- **OSPS Baseline** — Automated compliance checking across maturity levels
105140

106141
## Development
107142

108143
```bash
109144
# Clone and install
110-
git clone https://github.com/ossguard/ossguard.git
145+
git clone https://github.com/kirankotari/ossguard.git
111146
cd ossguard
112147
pip install -e ".[dev]"
113148

114149
# Run tests
115-
pytest tests/ -v
150+
pytest
116151

117152
# Lint
118-
ruff check src/
153+
ruff check src/ tests/
119154
```
120155

121-
## How It Relates to OpenSSF
122-
123-
This tool is **not** a replacement for any OpenSSF project. It's a **unifier** — it makes it trivially easy to adopt the best practices and tools that OpenSSF working groups have built:
124-
125-
- **Best Practices WG** → SECURITY.md template, Best Practices Badge tracking
126-
- **Security Tooling WG** → CodeQL setup, SBOM generation
127-
- **Supply Chain Integrity WG** → Sigstore signing, SLSA provenance
128-
- **Vulnerability Disclosures WG** → CVD-compliant SECURITY.md
129-
- **Securing Software Repos WG** → Dependabot, branch protection
130-
131-
## Roadmap
132-
133-
- [ ] `ossguard deps` — unified dependency health dashboard (Scorecard + OSV + deps.dev)
134-
- [ ] Interactive mode with questionary prompts
135-
- [ ] GitLab CI/CD support (in addition to GitHub Actions)
136-
- [ ] SLSA provenance workflow generation
137-
- [ ] OpenSSF Best Practices Badge auto-application
138-
- [ ] Allstar configuration generation
139-
- [ ] Pre-commit hooks for security linting
140-
- [ ] Language-specific security linters (bandit, eslint-plugin-security, gosec)
141-
- [ ] Renovate as an alternative to Dependabot
142-
- [ ] SBOM drift detection between releases
143-
144156
## Contributing
145157

146158
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

src/ossguard/analyzers/badge.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pathlib import Path
77

88
from ossguard.detector import ProjectInfo, detect_project
9-
from ossguard.parsers.dependencies import parse_dependencies
109

1110

1211
@dataclass
@@ -88,7 +87,6 @@ def assess_badge_readiness(project_path: str | Path) -> BadgeReport:
8887
met = sum(1 for c in criteria if c.status == "met")
8988
unmet = sum(1 for c in criteria if c.status == "unmet")
9089
unknown = sum(1 for c in criteria if c.status == "unknown")
91-
total_assessable = met + unmet
9290
readiness = (met / len(criteria) * 100) if criteria else 0.0
9391

9492
return BadgeReport(

src/ossguard/analyzers/baseline.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
import json
65
from dataclasses import dataclass, field
76
from pathlib import Path
87

src/ossguard/analyzers/drift.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from ossguard.apis.osv import OSVClient, VulnInfo
88
from ossguard.parsers.dependencies import Dependency
9-
from ossguard.parsers.sbom import SBOMInfo, parse_sbom
9+
from ossguard.parsers.sbom import parse_sbom
1010

1111

1212
@dataclass

src/ossguard/analyzers/insights.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
import re
65
from dataclasses import dataclass, field
76
from datetime import datetime, timezone
87
from pathlib import Path

src/ossguard/analyzers/license_check.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
from __future__ import annotations
44

55
from dataclasses import dataclass, field
6-
from pathlib import Path
76

8-
from ossguard.apis.deps_dev import DepsDevClient, PackageInfo
7+
from ossguard.apis.deps_dev import DepsDevClient
98
from ossguard.parsers.dependencies import Dependency
109

1110

@@ -173,8 +172,8 @@ def _detect_conflicts(
173172
if not project_license:
174173
# Can't check compatibility without knowing the project license
175174
# But we can still detect obviously problematic combinations
176-
copyleft_deps = [l for l in licenses if l.category == "copyleft"]
177-
permissive_deps = [l for l in licenses if l.category == "permissive"]
175+
copyleft_deps = [lic for lic in licenses if lic.category == "copyleft"]
176+
permissive_deps = [lic for lic in licenses if lic.category == "permissive"]
178177

179178
if copyleft_deps and permissive_deps:
180179
for cp in copyleft_deps[:3]:

src/ossguard/analyzers/report.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from __future__ import annotations
44

55
import json
6-
from datetime import datetime, timezone
76
from pathlib import Path
87

98
from ossguard.analyzers.audit import AuditReport, run_audit

src/ossguard/analyzers/supply_chain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from dataclasses import dataclass, field
77
from pathlib import Path
88

9-
from ossguard.apis.osv import OSVClient, VulnInfo
9+
from ossguard.apis.osv import OSVClient
1010
from ossguard.parsers.dependencies import Dependency, parse_dependencies
1111

1212

0 commit comments

Comments
 (0)