Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
security-audit.ymlโ€ข8.72 kB
name: Security Audit on: push: branches: [main, develop] pull_request: branches: [main, develop] schedule: # Run daily at 9 AM UTC - cron: '0 9 * * *' workflow_dispatch: permissions: contents: read issues: write pull-requests: write security-events: write jobs: security-audit: name: Security Audit runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 # Full history for better analysis - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20.x' cache: 'npm' - name: Install dependencies run: npm ci - name: Build project run: npm run build - name: Run Security Audit id: security-audit shell: bash run: | # Create security audit script cat > run-audit.js << 'EOF' import { SecurityAuditor } from './dist/security/audit/index.js'; async function runAudit() { const config = SecurityAuditor.getDefaultConfig(); // Adjust config for CI config.reporting.formats = ['console', 'markdown', 'json']; config.reporting.createIssues = false; // Handle separately config.reporting.commentOnPr = false; // Handle separately const auditor = new SecurityAuditor(config); try { const result = await auditor.audit(); // Save results for later steps const fs = await import('fs/promises'); await fs.writeFile('security-audit-result.json', JSON.stringify(result, null, 2)); // Set exit code but don't exit immediately if (result.summary.critical > 0 || result.summary.high > 0) { process.exitCode = 1; } } catch (error) { console.error('Security audit failed:', error); process.exitCode = 1; } } runAudit(); EOF # Run the audit with error handling if ! node run-audit.js; then echo "AUDIT_FAILED=true" >> $GITHUB_ENV echo "::warning::Security audit encountered errors but workflow will continue" # Create minimal report if audit fails echo '{"findings": [], "summary": {"total": 0, "critical": 0, "high": 0, "medium": 0, "low": 0}, "error": "Audit failed to complete"}' > security-audit-result.json fi - name: Upload audit results if: always() uses: actions/upload-artifact@v4 with: name: security-audit-results path: | security-audit-report.md security-audit-report.json security-audit-result.json - name: Generate SARIF report if: always() shell: bash run: | # Convert our JSON report to SARIF format cat > convert-to-sarif.js << 'EOF' import { readFile, writeFile } from 'fs/promises'; async function convertToSarif() { const result = JSON.parse(await readFile('security-audit-result.json', 'utf-8')); const sarif = { version: '2.1.0', runs: [{ tool: { driver: { name: 'DollhouseMCP Security Audit', version: '1.0.0', rules: [] } }, results: result.findings.map(finding => ({ ruleId: finding.ruleId, level: mapSeverityToLevel(finding.severity), message: { text: finding.message }, locations: finding.file ? [{ physicalLocation: { artifactLocation: { uri: finding.file }, region: { startLine: finding.line || 1, startColumn: finding.column || 1 } } }] : [] })) }] }; await writeFile('security-audit.sarif', JSON.stringify(sarif, null, 2)); } function mapSeverityToLevel(severity) { switch (severity) { case 'critical': case 'high': return 'error'; case 'medium': return 'warning'; default: return 'note'; } } convertToSarif().catch(console.error); EOF # Convert with validation if node convert-to-sarif.js; then echo "โœ… SARIF report generated successfully" else echo "::warning::Failed to generate SARIF report" # Create minimal valid SARIF if conversion fails echo '{"version":"2.1.0","runs":[{"tool":{"driver":{"name":"DollhouseMCP Security Audit","version":"1.0.0"}},"results":[]}]}' > security-audit.sarif fi - name: Upload SARIF to GitHub if: always() uses: github/codeql-action/upload-sarif@v3 with: sarif_file: security-audit.sarif category: security-audit - name: Comment PR with results if: github.event_name == 'pull_request' && always() uses: actions/github-script@v7 with: script: | const fs = require('fs'); // Read the markdown report let report = '## ๐Ÿ”’ Security Audit Results\n\n'; try { if (fs.existsSync('security-audit-report.md')) { report += fs.readFileSync('security-audit-report.md', 'utf8'); } else { report += 'โŒ Security audit report not generated.'; } } catch (error) { report += `โŒ Error reading report: ${error.message}`; } // Add status badge const failed = process.env.AUDIT_FAILED === 'true'; if (failed) { report = '### โŒ Security Audit Failed\n\n' + report; } else { report = '### โœ… Security Audit Passed\n\n' + report; } // Comment on PR github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: report }); - name: Create issues for critical findings if: github.event_name == 'schedule' && env.AUDIT_FAILED == 'true' uses: actions/github-script@v7 with: script: | const fs = require('fs'); try { const result = JSON.parse(fs.readFileSync('security-audit-result.json', 'utf8')); const criticalFindings = result.findings.filter(f => f.severity === 'critical'); for (const finding of criticalFindings.slice(0, 5)) { // Limit to 5 issues const title = `Security: ${finding.message}`; const body = `## Security Issue Detected **Rule**: ${finding.ruleId} **Severity**: ${finding.severity} **File**: ${finding.file || 'N/A'} **Line**: ${finding.line || 'N/A'} ### Description ${finding.message} ### Remediation ${finding.remediation} ### Code \`\`\` ${finding.code || 'N/A'} \`\`\` --- *This issue was automatically created by the Security Audit workflow.*`; await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: title, body: body, labels: ['security', 'automated', 'priority: critical'] }); } } catch (error) { console.error('Failed to create issues:', error); } - name: Fail if critical issues found if: env.AUDIT_FAILED == 'true' shell: bash run: | echo "โŒ Security audit found critical issues. Please review the report above." exit 1

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/DollhouseMCP/DollhouseMCP'

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