Curated library of atomic skills and personas for Hanami, dry-rb, and ROM Ruby development. Covers actions, slices, repositories, relations, changesets, providers, DI, operations, TDD, CLI, views, routing, validation, and 10 orchestration personas. Shared Ruby process skills have moved to ruby-core-skills. Uses Markdown + Front-matter architecture.
95
95%
Does it follow best practices?
Impact
96%
1.20xAverage score across 45 eval scenarios
Passed
No known issues
Use this skill when reviewing Hanami 2.x code for security concerns.
Core principle: Security is layered. Validate at the boundary, authenticate explicitly, and never trust input.
Follow this sequence when performing a security review. For each step, the Red Flag column indicates a failing condition; if a red flag is found, apply the remediation noted in Core Rules below.
| # | Concern | Grep / Check | Red Flag | Severity |
|---|---|---|---|---|
| 1 | Param validation | grep -rn 'request.params' app/actions/ | grep -v 'params do' | request.params used directly in business logic without a params block | Critical |
| 2 | CSRF protection | Check config/app.rb for config.actions.csrf_protection | Missing csrf_protection = true for HTML endpoints | Critical |
| 3 | Authentication | grep -rn 'def handle' app/actions/ cross-checked with grep -rn 'authenticate' | Auth assumed by convention, no explicit before :authenticate! | Critical |
| 4 | Authorization | Review Actions and service objects for role/permission checks | Only authn present, no authz | High |
| 5 | Secrets in code | grep -rn 'secret|password|api_key|token' app/ config/ --include='*.rb' | grep -v 'settings|ENV' | Hardcoded strings for keys/secrets in source files | Critical |
| 6 | Logging | grep -rn 'logger' app/ | grep 'password|token|secret' | params[:password] or tokens in log calls | High |
| 7 | SQL injection | grep -rn 'where("' app/ | String interpolation in where("...") | Critical |
| 8 | XSS / template output | grep -rn 'raw ' app/ | raw or html_safe on user input | Critical |
| 9 | Session config | Review config.sessions in config/app.rb | No secret, hardcoded secret, or no expiration | High |
| 10 | Error messages | Review auth failure responses | Messages like "User not found" or "Password incorrect" (user enumeration) | Advisory |
After completing all steps, compile findings into a summary:
For each finding, report: location (file + line), severity, a summary of the issue (never include actual secret values, passwords, tokens, or API keys — describe their presence without exposing them), and the recommended fix (see Core Rules).
Detailed remediation patterns for each finding category.
Validate all params via the Params DSL:
# GOOD
params do
required(:email).value(:string, format?: /\A.+@.+\z/)
required(:password).value(:string, min_size?: 8)
end
# BAD
user_repo.create(request.params)Enable CSRF protection for HTML endpoints:
# config/app.rb
config.actions.csrf_protection = trueAuthenticate in Actions using injected services:
include Deps["authentication"]
before :authenticate!
def authenticate!(request, response)
halt 401 unless authentication.valid?(request)
endNever log sensitive data:
# GOOD
logger.info("Login attempt: #{params[:email]}")
# BAD: logger.info("Login: #{params[:email]}, password: #{params[:password]}")Store secrets in settings, never in code:
# config/settings.rb
setting :session_secret, constructor: Types::String# .env
SESSION_SECRET=your-secret-herePrevent SQL injection using ROM's query interface:
# GOOD: users.where(email: params[:email]).one
# BAD: users.where("email = '#{params[:email]}'").oneEscape output in templates — ERB auto-escapes by default; never use raw on user input:
<!-- GOOD -->
<p><%= user.bio %></p>Use secure session configuration:
config.sessions = :cookie, {
key: "my_app.session",
secret: settings.session_secret,
expire_after: 60 * 60 * 24 * 7
}Return generic error messages for auth failures:
# GOOD: halt 401, { error: "Invalid credentials" }.to_json
# BAD: halt 401, { error: "User not found" }.to_json| Related Skill | When to chain |
|---|---|
| validate-params | All params must be validated before use. |
| handle-errors | Error responses must not leak sensitive information. |
| settings | Secrets and configuration must use Settings, not hardcoded values. |
| code-review | Security review is part of every code review. |
| setup-authentication | For implementing auth strategies. |
| security-review-process (from ruby-core-skills) | OWASP checklist, Ruby-level security concerns. |
.tessl-plugin
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
scenario-42
scenario-43
scenario-44
scenario-45
skills
actions
build-json-api
create-action
handle-errors
validate-params
context
load-context
db
create-changeset
create-repository
define-relation
write-migration
dry-monads
handle-result-pattern
dry-rb
create-operation
create-validation-contract
personas
providers
configure-providers
implement-di
review-security
routing
define-routes
slices
configure-slice
create-slice
extract-slice
review-slice-boundaries
test-slice