Skip to main content
Glama
security.yml5.97 kB
name: Security Scanning on: push: branches: [main] pull_request: branches: [main] schedule: # Run weekly on Mondays at 10:00 UTC - cron: '0 10 * * 1' workflow_dispatch: permissions: contents: read security-events: write actions: read jobs: bandit: name: Bandit Security Scan runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v5 - name: Install uv uses: astral-sh/setup-uv@v7 - name: Create virtual environment run: uv venv - name: Install dependencies run: uv pip install bandit[toml] - name: Run Bandit run: | uv run bandit -r src/mnemex -f json -o bandit-report.json || true - name: Upload Bandit results uses: actions/upload-artifact@v4 if: always() with: name: bandit-results path: bandit-report.json - name: Create issues for HIGH Bandit findings if: always() uses: actions/github-script@v8 with: script: | const fs = require('fs'); const path = 'bandit-report.json'; if (!fs.existsSync(path)) { core.info('No bandit-report.json found'); return; } const data = JSON.parse(fs.readFileSync(path, 'utf8')); const results = Array.isArray(data.results) ? data.results : []; const highs = results.filter(r => (r.issue_severity || '').toUpperCase() === 'HIGH'); core.info(`Found ${highs.length} HIGH severity findings`); for (const r of highs) { const testId = r.test_id || 'UNKNOWN'; const file = r.filename || 'unknown-file'; const line = r.line_number || 0; const title = `[Bandit:${testId}] ${file}:${line}`; const body = [ `Bandit detected a HIGH severity issue.`, '', `- Rule: ${testId}`, `- File: ${file}`, `- Line: ${line}`, `- Severity: ${r.issue_severity}`, `- Confidence: ${r.issue_confidence}`, `- More info: ${r.more_info || 'n/a'}`, '', 'Issue text:', '```', (r.issue_text || '').trim(), '```' ].join('\n'); // Check if an open issue with same title already exists const { data: existing } = await github.rest.search.issuesAndPullRequests({ q: `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open in:title "${title.replace(/"/g, '\\"')}"` }); if (existing.total_count > 0) { core.info(`Issue already exists for ${title}`); continue; } await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title, body, labels: ['security', 'bandit'] }); core.info(`Created issue: ${title}`); } pip-audit: name: Dependency Vulnerability Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Install uv uses: astral-sh/setup-uv@v7 - name: Create virtual environment run: uv venv - name: Install dependencies run: | uv pip install -e ".[dev]" uv pip install pip-audit - name: Run pip-audit continue-on-error: true run: | uv run pip-audit --desc --format json --output pip-audit-report.json || true uv run pip-audit --desc - name: Upload pip-audit results uses: actions/upload-artifact@v4 if: always() with: name: pip-audit-results path: pip-audit-report.json codeql: name: CodeQL Analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v4 with: languages: python queries: security-extended,security-and-quality - name: Autobuild uses: github/codeql-action/autobuild@v4 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 with: category: "/language:python" sbom: name: Generate SBOM (CycloneDX) runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - name: Install uv uses: astral-sh/setup-uv@v7 - name: Create virtual environment run: uv venv - name: Install dependencies run: | uv pip install -e ".[dev]" uv pip install cyclonedx-bom - name: Generate SBOM (JSON) run: | uv run cyclonedx-py environment --output-format JSON --output-file sbom.json - name: Upload SBOM artifact uses: actions/upload-artifact@v4 with: name: cyclonedx-sbom path: sbom.json security-summary: name: Security Summary runs-on: ubuntu-latest needs: [bandit, pip-audit, codeql, sbom] if: always() steps: - name: Check scan results run: | echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "✅ All security scans completed" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "- Bandit: ${{ needs.bandit.result }}" >> $GITHUB_STEP_SUMMARY echo "- pip-audit: ${{ needs.pip-audit.result }}" >> $GITHUB_STEP_SUMMARY echo "- CodeQL: ${{ needs.codeql.result }}" >> $GITHUB_STEP_SUMMARY echo "- SBOM (CycloneDX): ${{ needs.sbom.result }}" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Review detailed results in the workflow artifacts and Security tab." >> $GITHUB_STEP_SUMMARY

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mnemexai/mnemex'

If you have feedback or need assistance with the MCP directory API, please join our Discord server