Install
$ agentstack add skill-rubyroidlabs-rails-audit-skill-rails-audit-skill ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Rails Tech Review Skill
Perform comprehensive technical reviews of Ruby on Rails applications. This skill runs automated analysis tools, inspects source code manually, and produces a structured audit report with prioritized findings.
Audit Scope
The audit can be run in two modes:
- Full Application Audit: Analyze entire Rails application (default)
- Targeted Audit: Analyze specific files or directories
Execution Flow
Phase 1: Project Discovery
- Verify this is a Rails project. Check for
config/application.rb,Gemfile, andapp/directory. If none of these exist, immediately abort and tell the user: "This does not appear to be a Ruby on Rails project. This skill only supports Rails applications." - Extract key metadata:
- Ruby version (from
.ruby-version,Gemfile.lock, or.tool-versions) - Rails version (from
Gemfile.lock— look forrails (entry) - Database adapter (from
config/database.ymlorGemfile.lock) - Background job framework (check Gemfile for Sidekiq, GoodJob, DelayedJob, Resque)
- Frontend setup (check
package.json,app/javascript/,app/assets/) - CI/CD (check
.github/workflows/,.gitlab-ci.yml,Jenkinsfile) - Test framework (check for
spec/directory → RSpec,test/directory → Minitest) - Infrastructure signals (check for
Procfile,Dockerfile,docker-compose.yml,app.json)
- Attempt
bundle installto verify dependencies resolve. Note any failures. - Attempt to run the app (
bin/rails server— just verify it starts). Note errors or missing secrets. - If tests exist, run a single quick test to verify the suite is functional:
- RSpec:
bundle exec rspec spec/models/..._spec.rb:(pick any spec file, run one example) - Minitest:
bundle exec rails test test/models/..._test.rb: - This verifies the test framework works — the full suite can be run later with coverage instrumentation via the optional SimpleCov agent
- If even a single test fails to run, note the errors — this is itself a finding
Phase 2: Tool Selection
Determine which tools to use based on project characteristics:
Linter selection logic (Ruby):
- Check for
.rubocop.ymlin project root ORrubocopinGemfile→ use RuboCop - Else check for
.standard.ymlin project root ORstandardinGemfile→ use standardrb - Else → default to standard + standard-rails (install if needed)
ESLint (JavaScript):
- Only applicable if JS files are detected: check for
app/javascript/,package.json,.js/.jsx/.ts/.tsxfiles - Check if the project already has ESLint configured: look for
eslint.config.js,eslint.config.mjs,.eslintrc.js,.eslintrc.json,.eslintrc.yaml - If NO config file exists → skip ESLint entirely. Note in the report. Never create a config file from scratch.
- If a config file exists AND
package.jsonexists → the project intends to use ESLint. Proceed (even if eslint is not yet inpackage.jsonornode_modulesis missing — Phase 3 handles setup inline using the same stash/restore pattern as Ruby gems). - If no
package.jsonbut JS files exist (e.g., importmaps, Sprockets) → skip ESLint
Importmap audit (Rails 7+):
- Check if
bin/importmapexists and is executable ANDconfig/importmap.rbexists - If both present → the project uses importmaps;
bin/importmap auditcan check for outdated/vulnerable JS packages - If not present → skip (not an importmap project, or Rails .md from the skill directory and follow all steps
described in it. The project root is: . Return the data in the output format specified in that file.
**While agents run**, execute these additional checks. Some temporarily modify files (package.json, Gemfile) — use the stash/restore pattern for those and verify the working tree is clean afterward:
1. **Ruby linter**: Run the selected linter with offense reporting:
- RuboCop: `bundle exec rubocop --format offenses --format worst` (or `rubocop` standalone)
- standardrb: `bundle exec standardrb --format offenses` (or `standardrb` standalone)
- Capture: total offenses, top offense types by count, worst-offending files
2. **ESLint** — if a config file exists AND `package.json` exists (from Phase 2 detection):
- **Backup**: `git stash push -m "rails-audit-eslint-setup" -- package.json yarn.lock package-lock.json` (or `cp` fallback)
- **Setup**: If eslint is not in `package.json`, add it: `npm install --save-dev eslint` (or `yarn add -D eslint`)
- **Run**: `npx eslint app/javascript --format json` (or target the relevant JS directory)
- **Capture**: total errors/warnings, top rules violated, worst-offending files
- **Restore**: `git stash pop` (or restore from backup copies, then delete backups)
- **Verify**: `git status` — confirm no leftover changes
- If eslint is already present in `package.json` AND `node_modules/` exists → skip backup/restore, just run it
- If the config file exists but eslint produces only config errors → note the config issue in the report
3. **Importmap audit** (if `bin/importmap` exists AND `config/importmap.rb` exists):
- Run: `bin/importmap audit`
- This checks pinned JS packages for known vulnerabilities and outdated versions
- Capture: any vulnerabilities found, outdated packages, and the summary line
- If the command fails or isn't available, skip — note that importmap tooling is present but `audit` may not be supported in this Rails version
4. **Rails ERD** (entity-relationship diagram + invalid association detection):
- If `rails-erd` is in the Gemfile: run `bundle exec erd` directly
- If not in Gemfile: use stash/restore to add `gem "rails-erd", group: :development`, `bundle install`, run, then restore (same pattern as other tools)
- **Capture stderr** — rails-erd logs association warnings there, e.g. "WARNING: Cannot resolve association..." or "failed to load model"
- Parse: models with invalid associations (referencing non-existent tables, columns, or classes) → High finding
- The Mermaid diagram (`erd.mmd`) itself is documentation; the warnings are the audit value
- Cleanup: `rm -f erd.mmd` and restore Gemfile if it was modified
5. **Rails stats**: Run `bin/rails stats` (or `bin/rake stats`)
- Capture: code-to-test ratio, lines of code by directory
**After all agents complete**, clean up any generated files:
- `rm -rf coverage/` (if SimpleCov ran)
- `rm -rf tmp/rubycritic/` (if RubyCritic ran)
- `rm -f brakeman_output.json gitleaks-report.json bundle-audit-output.json erd.mmd`
CRITICAL: After cleanup, run `git status` and verify no files were left modified. The working tree must be clean — every temporary modification (Gemfile, package.json, yarn.lock, package-lock.json, test helpers) must have been restored to its original state. If any files are unexpectedly dirty, restore them with `git checkout -- `.
**Interpreting agent responses:**
- `RUBYCRITIC_FAILED` / `COVERAGE_FAILED` / `BRAKEMAN_FAILED` / `BUNDLE_AUDIT_FAILED` / `GITLEAKS_FAILED` / `DEBRIDE_FAILED`: Note the failure reason in the report, omit or estimate that section
- `RUBYCRITIC_DATA`: parse and keep for Source Code Health and Code Design sections (score, ratings, smells, complexity)
- `BRAKEMAN_DATA`: parse and keep for Security Analysis section (warnings grouped by confidence and type)
- `BUNDLE_AUDIT_DATA`: parse and keep for Dependencies Vulnerabilities section (advisories grouped by severity)
- `GITLEAKS_DATA`: parse and keep for Git section (leaks, affected commits, secret types)
- `DEBRIDE_DATA`: parse and keep for the Dead Code subsection — potentially dead methods (candidates, not certainties)
- `COVERAGE_DATA`: parse and keep for the Testing section — includes both coverage percentages and test metrics (count, pass/fail, run time) from the SimpleCov run
- If the user skipped SimpleCov and no test suite was run, only the Phase 1 single-test verification result is available for the Testing section
### Phase 4: Load Reference Materials
Read the reference files to inform manual code review patterns:
- `references/code_smells.md` — Code smell patterns to identify
- `references/security_checklist.md` — Security vulnerability patterns + full authorization framework audit procedure
- `references/rails_antipatterns.md` — Rails-specific antipatterns
- `references/detection_patterns.md` — Grep/Glob patterns to use during manual analysis
### Phase 5: Manual Code Review
Analyze the codebase by category, cross-referencing tool output. As you review, collect findings with Problem/Priority/Solution details.
**Severity ordering:** Within each subsection, list findings from most severe to least severe — Critical first, then High, Medium, Low. This applies to both the report output and how you organize findings during review.
**Positive observations:** For each section, start with a 1-3 sentence summary of the overall assessment — including what's working well, not just problems. E.g., "In general, database structure looks good. All needed indexes are applied. There are only a few issues described below." This gives a balanced report.
#### 5.1 Back-end
**Source Code Health:**
- If RubyCritic data: report the overall score, worst-rated files (D/F ratings), most common smells, most complex files
- If no RubyCritic data: manually assess based on code review observations
- Identify files that RubyCritic flags as problematic for deeper manual review
**Dependencies:**
- Count gems in production group vs development/test
- Identify potentially unused gems (listed in Gemfile but never required/used)
- Flag gems that are unmaintained (no releases in >1 year)
- Flag gems with native extensions that could complicate deployment
- Check if `Gemfile.lock` is committed (should be) and up to date
**Dependencies Vulnerabilities:**
- If bundle-audit data: group vulnerabilities by severity (Critical/High/Medium/Low)
- For each high-severity finding, document the vulnerability and its fix
**Code Quality & Style:**
- If linter data: report total offenses, top offense types, worst-offending files
- Assess whether the team follows a consistent style
- Check if there's a linter configuration committed to the repo
**Security Analysis:**
- If brakeman data: group warnings by confidence (High/Medium/Weak) and severity
- Cross-reference with `references/security_checklist.md` patterns
- Key areas to check manually:
- SQL injection risks (string interpolation in queries)
- Mass assignment (`params.permit!`, missing strong parameters)
- XSS vulnerabilities (`raw`, `html_safe`, `` always exits 0 regardless of whether the file matches. Do NOT chain it with `&&`/`||` to decide if a file is tracked — this produces false positives.
Use these correct checks instead:
1. **Is a file gitignored?** `git check-ignore -v ` — exits 0 (with output) if ignored, exits 1 if NOT ignored. Use this first: if a file is gitignored and has never been committed, it's safe.
2. **Is a file tracked (in the index)?** `git ls-files --error-unmatch ` — exits 0 if tracked, exits 1 if NOT tracked. The `--error-unmatch` flag makes the exit code meaningful.
3. **Was it ever committed?** `git log --all -- ` — empty output means no commits touched this file. Non-empty means it exists in history even if deleted/ignored now.
**Checklist for sensitive files:**
- `config/master.key` — must be gitignored AND never committed. If committed: Critical.
- `.env`, `.env.production`, `.env.staging` — must be gitignored. If committed: High (even if only containing public keys).
- Check for other credential files: `*.pem`, `*.p12`, `credentials.json`, `service-account.json`
**General git checklist:**
- Check for Rails credentials usage (`config/credentials/`) — is `master.key` gitignored?
- Assess git flow: branch naming conventions, PR templates, commit message quality
- Check `.gitignore` completeness: are log files, tmp files, coverage reports, `node_modules/` ignored?
#### 5.5 Infrastructure (if signals detected)
- Heroku: check `Procfile`, `app.json` — is setup straightforward? Note Heroku's end-of-development status
- AWS: check for SDK usage, S3 configuration, infrastructure-as-code
- Docker: evaluate `Dockerfile` and `docker-compose.yml` completeness
- CI/CD: assess pipeline configuration, check if linters/security scanners run in CI
- Check for deployment documentation
#### 5.6 Development Setup
- README quality: does it explain what the app does and how to set it up?
- Local setup experience: what difficulties were encountered?
- Docker Compose for dependencies?
- Seed data quality: are seeds present and functional?
- Missing config files: `.node-version`, `.ruby-version`, `.tool-versions`
- **Docs vs reality mismatch**: cross-reference documentation against actual infrastructure:
- README/docs mention services not in Gemfile or not used (e.g., AWS SDK documented but app deployed on Heroku)
- Outdated deployment docs (e.g., Heroku instructions when app uses Kamal/Docker)
- Stale architecture docs describing removed features
- Findings → Low/Medium
#### 5.7 AI Development Setup
Assess the project's AI-assisted development tooling:
- Check for: `.claude/` directory, `CLAUDE.md`, `.cursor/`, `.cursorrules`, `.github/copilot-instructions.md`, `AGENTS.md`
- Check for MCP configuration: `.mcp.json`, `.claude/settings.json` with mcp servers
- Check for project skills: `.claude/skills/` or plugin configs
- If present: assess quality — are rules consistent with the codebase? Do they cover project-specific conventions?
- If absent: recommend setting up:
- `CLAUDE.md` (or `AGENTS.md`) — project rules: commands, architecture, conventions
- Skills — repeatable workflows (testing, deployment)
- MCP servers — tool integrations (databases, issue trackers)
- Findings → Low severity (nice-to-have, not critical)
### Phase 6: Generate Report
Write `RAILS_AUDIT_REPORT.md` in the project root using the structure defined in `references/report_template.md`.
**Guidelines:**
- Group related findings under category sections
- Within each section, group findings by severity using `### Critical`, `### High`, `### Medium`, `### Low` sub-headers. Omit severity levels with no findings.
- Each finding uses the Problem → Priority → Solution format. When the finding references specific code, include before/after code blocks:
`### Critical` (or High/Medium/Low — omit empty levels)
`#### [Issue Title]`
`**File:** \`path/to/file.rb:line\``
`#### Problem` — what was found, in which file(s), why it matters, concrete impact
`#### Priority` — Critical/High/Medium/Low
`#### Solution` — prose explanation of the fix
`**Current Code:**` — the actual problematic code in a fenced code block
`**Recommendation:**` — the fixed code in a fenced code block
- For structural/architectural findings without specific code to show, omit the code blocks
- **Positive notes for clean sections**: if a section has no findings, write a brief positive note (e.g., "Authentication is properly configured. No issues were found."). Don't leave sections empty.
- **REDACT SENSITIVE DATA**: Never include actual secrets, tokens, passwords, or API keys in the report. Replace secret values with `***[REDACTED]***`, or show only the first/last 4 characters for identification. This applies to: gitleaks findings, hardcoded credentials, environment variable values, and any tokens found in source code.
- The Conclusion must include a score out of 10 (rarely below 4 or above 9)
- Prioritized recommendations in three tiers: Quick Wins (immediate), Short-term (this sprint), Long-term (technical debt)
- No screenshot references — text descriptions and code blocks only
- No company branding or contact information
**Post-report artifact offer** (only if supported by the environment):
After the report is saved, detect whether the environment supports visual artifacts:
- **Claude Code (official Anthropic)**: the session model is Claude (con
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [rubyroidlabs](https://github.com/rubyroidlabs)
- **Source:** [rubyroidlabs/rails-audit-skill](https://github.com/rubyroidlabs/rails-audit-skill)
- **License:** MIT
- **Homepage:** https://rubyroidlabs.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.