diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e03fe41 --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +# Database +DATABASE_URL=postgresql://openshield:openshield@localhost:5432/openshield + +# Auth +JWT_SECRET=change-me-in-production + +# AI providers - add at least one +ANTHROPIC_API_KEY= +GROQ_API_KEY= +GEMINI_API_KEY= + +# Optional +NVD_API_KEY= +SENTRY_DSN= diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2d216b6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,27 @@ +# Global owner - final merge approval +* @Vishnu2707 + +# Scanner rules +/scanner/rules/ @SHAURYAKSHARMA24 @TFT444 +/playbooks/ @SHAURYAKSHARMA24 @TFT444 + +# AI layer +/ai/ @ritiksah141 @TFT444 + +# Frontend +/frontend/ @vogonPrayas @SHAURYAKSHARMA24 + +# API and backend +/api/ @ritiksah141 + +# Tests +/tests/ @ritiksah141 @parthrohit22 + +# Compliance +/compliance/ @SHAURYAKSHARMA24 + +# Docs +/docs/ @parthrohit22 + +# CI/CD and infra +/.github/ @Vishnu2707 @ritiksah141 diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 086751f..91491df 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,15 +1,20 @@ --- -name: Bug report +name: Bug Report about: Something is broken +title: 'bug: ' labels: bug +assignees: '' --- ## What happened? ## What did you expect? -## Steps to reproduce? +## Steps to reproduce ## Environment +- OpenShield version: - Python version: -- Azure SDK version: \ No newline at end of file +- OS: + +## Logs or screenshots diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 627de2f..00f232c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,69 +1,15 @@ +--- name: Feature Request -about: Suggest a new rule, compliance mapping, playbook, or capability for OpenShield -title: "feat: " +about: Suggest a new feature or improvement +title: 'feat: ' labels: enhancement assignees: '' --- -## Summary - -A clear one-sentence description of the feature you are proposing. - -## Problem It Solves - -What is the current limitation or gap? Why does this matter for Azure cloud security posture? -Link any related issues or discussions if relevant. - -## Proposed Solution - -Describe what you want to happen. Be specific. - ---- - -**If proposing a new scanner rule, fill in all fields below:** - -- Azure resource type: -- Misconfiguration it detects: -- Suggested RULE_ID (format: `AZ--`, e.g. `AZ-KV-003`): -- Severity: (CRITICAL / HIGH / MEDIUM / LOW) -- Compliance frameworks it maps to: - - CIS Azure Benchmark control: - - NIST CSF control: - - ISO 27001 control: -- Does a matching remediation playbook need to be created? (Yes / No) - ---- - -**If proposing a compliance mapping:** - -- Framework name and version: -- Control ID(s): -- Which existing rules does it apply to: -- Source documentation link: - ---- - -**If proposing an API or CLI change:** - -- Endpoint or command affected: -- Current behaviour: -- Proposed behaviour: -- Example request/response or command: - ---- - -## Alternatives Considered - -What other approaches did you consider, and why did you rule them out? - -## Additional Context - -Add any Azure documentation links, CVE references, CIS Benchmark pages, screenshots, or reference implementations here. +## What problem does this solve? -## Contribution +## Describe the solution -Are you willing to implement this yourself? +## Alternatives considered -- [ ] Yes, I plan to open a PR for this -- [ ] I can help review a PR but cannot implement it myself -- [ ] I am not able to contribute code for this \ No newline at end of file +## Additional context diff --git a/.github/ISSUE_TEMPLATE/new_rule.md b/.github/ISSUE_TEMPLATE/new_rule.md index 170fe57..c08f63b 100644 --- a/.github/ISSUE_TEMPLATE/new_rule.md +++ b/.github/ISSUE_TEMPLATE/new_rule.md @@ -1,24 +1,28 @@ --- -name: New scan rule -about: Propose a new Azure misconfiguration rule -labels: new-rule, good-first-issue +name: New Scanner Rule +about: Propose a new Azure security scanner rule +title: 'feat(scanner): add AZ-XXX-000 rule name' +labels: scanner-rule +assignees: '' --- -## Rule proposal +## Rule Details +- Rule ID: AZ-XXX-000 +- Severity: HIGH / MEDIUM / LOW +- Category: Storage / Network / Identity / Database / Compute / Key Vault / PostQuantum +- Frameworks: CIS / NIST / ISO 27001 / SOC 2 -**Rule ID:** AZ-XXX-000 -**Rule name:** -**Severity:** HIGH / MEDIUM / LOW -**Category:** Storage / Network / Identity / Database / Compute / Key Vault +## What does it detect? -## What misconfiguration does it detect? +## Detection logic -## Why is it a security risk? +## Why is this a security risk? -## Which frameworks does it map to? -- CIS: -- NIST: -- ISO 27001: -- SOC 2: +## Remediation steps -## Remediation (how to fix it)? +## Test plan +- [ ] Tested against real Azure free trial subscription +- [ ] Compliant case returns no findings +- [ ] Non-compliant case returns correct finding +- [ ] CLI playbook written and tested +- [ ] All four compliance framework JSONs updated diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..95dc39a --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,19 @@ +name: Dependency Review + +on: + pull_request: + branches: [dev, main] + +permissions: + contents: read + pull-requests: write + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + comment-summary-in-pr: always diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..1426245 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,42 @@ +name: Docker Build and Push + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/openshield-org/openshield + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..22d5ee9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,21 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + make_latest: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..88fd8c5 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,25 @@ +name: Mark stale issues and PRs + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: 'This issue has been inactive for 30 days and will be closed in 7 days unless there is activity.' + stale-pr-message: 'This PR has been inactive for 14 days. Please update or it will be closed in 7 days.' + close-issue-message: 'Closing due to inactivity. Feel free to reopen if still relevant.' + close-pr-message: 'Closing due to inactivity. Feel free to reopen if still relevant.' + days-before-issue-stale: 30 + days-before-pr-stale: 14 + days-before-issue-close: 7 + days-before-pr-close: 7 + stale-issue-label: stale + stale-pr-label: stale + exempt-issue-labels: 'pinned,security,roadmap' + exempt-pr-labels: 'pinned,security' diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0725bfa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.11-slim-bookworm + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir --upgrade pip && \ + pip install --no-cache-dir -r requirements.txt + +COPY . . + +EXPOSE 8000 + +CMD ["gunicorn", "--workers", "2", "--threads", "2", "--timeout", "120", "--bind", "0.0.0.0:8000", "api.app:app"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7f44484 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +version: '3.8' + +services: + db: + image: postgres:15-alpine + environment: + POSTGRES_DB: openshield + POSTGRES_USER: openshield + POSTGRES_PASSWORD: openshield + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U openshield"] + interval: 10s + timeout: 5s + retries: 5 + + api: + build: . + ports: + - "8000:8000" + environment: + DATABASE_URL: postgresql://openshield:openshield@db:5432/openshield + JWT_SECRET: change-me-in-production + ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} + NVD_API_KEY: ${NVD_API_KEY:-} + depends_on: + db: + condition: service_healthy + + frontend: + image: node:20-alpine + working_dir: /app + volumes: + - ./frontend:/app + command: sh -c "npm install && npm run dev -- --host" + ports: + - "5173:5173" + environment: + VITE_API_BASE_URL: http://localhost:8000 + +volumes: + postgres_data: diff --git a/requirements.txt b/requirements.txt index 12a58f3..921e8f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,7 +17,7 @@ psycopg2-binary==2.9.9 python-dotenv==1.2.2 pyjwt==2.13.0 requests==2.34.2 -pyyaml==6.0.1 +PyYAML==6.0.3 gunicorn==26.0.0 cryptography==49.0.0 msrest==0.7.1 @@ -32,3 +32,5 @@ python-json-logger>=2.0.7 sentry-sdk>=1.40.0 pytest>=7.4.0 pytest-cov>=4.1.0 +certifi==2026.6.17 +cryptography==49.0.0