claude-agent-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +128 -0
  2. package/bin/claude-framework +3 -0
  3. package/framework/agents/design-lead.md +240 -0
  4. package/framework/agents/product-owner.md +179 -0
  5. package/framework/agents/tech-lead.md +226 -0
  6. package/framework/commands/ayuda.md +127 -0
  7. package/framework/commands/a/303/261adir.md +98 -0
  8. package/framework/commands/backup.md +397 -0
  9. package/framework/commands/cambiar.md +110 -0
  10. package/framework/commands/cloud.md +457 -0
  11. package/framework/commands/code.md +142 -0
  12. package/framework/commands/debug.md +334 -0
  13. package/framework/commands/deploy.md +383 -0
  14. package/framework/commands/deshacer.md +120 -0
  15. package/framework/commands/estado.md +218 -0
  16. package/framework/commands/explica.md +227 -0
  17. package/framework/commands/feature.md +120 -0
  18. package/framework/commands/git.md +427 -0
  19. package/framework/commands/historial.md +202 -0
  20. package/framework/commands/learn.md +408 -0
  21. package/framework/commands/movil.md +245 -0
  22. package/framework/commands/nuevo.md +118 -0
  23. package/framework/commands/plan.md +134 -0
  24. package/framework/commands/prd.md +113 -0
  25. package/framework/commands/probar.md +148 -0
  26. package/framework/commands/revisar.md +208 -0
  27. package/framework/commands/seeds.md +230 -0
  28. package/framework/commands/seguridad.md +226 -0
  29. package/framework/commands/tasks.md +157 -0
  30. package/framework/skills/architecture/algorithms.md +970 -0
  31. package/framework/skills/architecture/clean-code.md +1080 -0
  32. package/framework/skills/architecture/design-patterns.md +1984 -0
  33. package/framework/skills/architecture/functional-programming.md +972 -0
  34. package/framework/skills/architecture/solid.md +991 -0
  35. package/framework/skills/cloud/cloud-aws.md +848 -0
  36. package/framework/skills/cloud/cloud-azure.md +931 -0
  37. package/framework/skills/cloud/cloud-gcp.md +848 -0
  38. package/framework/skills/cloud/message-queues.md +1229 -0
  39. package/framework/skills/core/accessibility.md +401 -0
  40. package/framework/skills/core/api.md +474 -0
  41. package/framework/skills/core/authentication.md +306 -0
  42. package/framework/skills/core/authorization.md +388 -0
  43. package/framework/skills/core/background-jobs.md +341 -0
  44. package/framework/skills/core/caching.md +473 -0
  45. package/framework/skills/core/code-review.md +341 -0
  46. package/framework/skills/core/controllers.md +290 -0
  47. package/framework/skills/core/cua.md +285 -0
  48. package/framework/skills/core/documentation.md +472 -0
  49. package/framework/skills/core/file-uploads.md +351 -0
  50. package/framework/skills/core/hotwire-native.md +296 -0
  51. package/framework/skills/core/hotwire.md +278 -0
  52. package/framework/skills/core/i18n.md +334 -0
  53. package/framework/skills/core/imports-exports.md +750 -0
  54. package/framework/skills/core/infrastructure.md +337 -0
  55. package/framework/skills/core/models.md +228 -0
  56. package/framework/skills/core/notifications.md +672 -0
  57. package/framework/skills/core/payments.md +581 -0
  58. package/framework/skills/core/performance.md +361 -0
  59. package/framework/skills/core/rails-scaffold.md +131 -0
  60. package/framework/skills/core/search.md +518 -0
  61. package/framework/skills/core/security.md +565 -0
  62. package/framework/skills/core/seeds.md +307 -0
  63. package/framework/skills/core/seo.md +542 -0
  64. package/framework/skills/core/testing.md +393 -0
  65. package/framework/skills/core/views.md +260 -0
  66. package/framework/skills/core/websockets.md +564 -0
  67. package/framework/skills/data/advanced-sql.md +1204 -0
  68. package/framework/skills/data/nosql.md +1141 -0
  69. package/framework/skills/devops/containers-advanced.md +1237 -0
  70. package/framework/skills/devops/debugging.md +834 -0
  71. package/framework/skills/devops/git-workflow.md +752 -0
  72. package/framework/skills/devops/networking.md +932 -0
  73. package/framework/skills/devops/shell-scripting.md +1132 -0
  74. package/framework/sub-agents/architecture-patterns-agent.md +1450 -0
  75. package/framework/sub-agents/cloud-agent.md +677 -0
  76. package/framework/sub-agents/data.md +504 -0
  77. package/framework/sub-agents/debugging-agent.md +554 -0
  78. package/framework/sub-agents/devops.md +483 -0
  79. package/framework/sub-agents/docs.md +176 -0
  80. package/framework/sub-agents/frontend-dev.md +349 -0
  81. package/framework/sub-agents/git-workflow-agent.md +697 -0
  82. package/framework/sub-agents/integrations.md +630 -0
  83. package/framework/sub-agents/native-dev.md +434 -0
  84. package/framework/sub-agents/qa.md +138 -0
  85. package/framework/sub-agents/rails-dev.md +375 -0
  86. package/framework/sub-agents/security.md +526 -0
  87. package/framework/sub-agents/ui.md +437 -0
  88. package/framework/sub-agents/ux.md +284 -0
  89. package/framework/templates/api-spec.md +500 -0
  90. package/framework/templates/component-spec.md +248 -0
  91. package/framework/templates/feature.json +13 -0
  92. package/framework/templates/model-spec.md +318 -0
  93. package/framework/templates/prd-template.md +80 -0
  94. package/framework/templates/task-plan.md +122 -0
  95. package/framework/templates/task-user-story.md +52 -0
  96. package/framework/templates/technical-spec.md +260 -0
  97. package/framework/templates/user-story.md +95 -0
  98. package/package.json +42 -0
  99. package/project-templates/CLAUDE.md +42 -0
  100. package/project-templates/contexts/architecture.md +25 -0
  101. package/project-templates/contexts/conventions.md +46 -0
  102. package/project-templates/contexts/design-system.md +47 -0
  103. package/project-templates/contexts/requirements.md +38 -0
  104. package/project-templates/contexts/stack.md +30 -0
  105. package/project-templates/history/active/models.md +11 -0
  106. package/project-templates/history/changelog.md +15 -0
  107. package/project-templates/workspace/.gitkeep +0 -0
  108. package/src/cli.js +52 -0
  109. package/src/init.js +104 -0
  110. package/src/status.js +75 -0
  111. package/src/update.js +88 -0
@@ -0,0 +1,565 @@
1
+ # Skill: Security
2
+
3
+ ## Purpose
4
+
5
+ Implementar y mantener la seguridad de aplicaciones Rails siguiendo las mejores prácticas y estándares de la industria (OWASP).
6
+
7
+ ## Herramientas de auditoría
8
+
9
+ ### Brakeman (análisis estático)
10
+
11
+ ```bash
12
+ # Gemfile
13
+ group :development do
14
+ gem "brakeman", require: false
15
+ end
16
+
17
+ # Ejecutar
18
+ bundle exec brakeman
19
+
20
+ # Generar reporte HTML
21
+ bundle exec brakeman -o tmp/brakeman-report.html
22
+
23
+ # Solo warnings altos
24
+ bundle exec brakeman -w2
25
+
26
+ # Ignorar falsos positivos (crear config/brakeman.ignore)
27
+ bundle exec brakeman -I
28
+ ```
29
+
30
+ ### Bundler Audit (dependencias vulnerables)
31
+
32
+ ```bash
33
+ # Gemfile
34
+ group :development do
35
+ gem "bundler-audit", require: false
36
+ end
37
+
38
+ # Actualizar DB de vulnerabilidades
39
+ bundle exec bundle-audit update
40
+
41
+ # Ejecutar auditoría
42
+ bundle exec bundle-audit check
43
+
44
+ # Actualizar gems vulnerables automáticamente
45
+ bundle exec bundle-audit check --update
46
+ ```
47
+
48
+ ### CI/CD Integration
49
+
50
+ ```yaml
51
+ # .github/workflows/security.yml
52
+ name: Security
53
+
54
+ on: [push, pull_request]
55
+
56
+ jobs:
57
+ security:
58
+ runs-on: ubuntu-latest
59
+ steps:
60
+ - uses: actions/checkout@v4
61
+
62
+ - name: Set up Ruby
63
+ uses: ruby/setup-ruby@v1
64
+ with:
65
+ ruby-version: '3.3'
66
+ bundler-cache: true
67
+
68
+ - name: Run Brakeman
69
+ run: bundle exec brakeman -q -w2
70
+
71
+ - name: Run Bundle Audit
72
+ run: |
73
+ bundle exec bundle-audit update
74
+ bundle exec bundle-audit check
75
+ ```
76
+
77
+ ## OWASP Top 10 - Prevención
78
+
79
+ ### A01: Broken Access Control
80
+
81
+ ```ruby
82
+ # ✅ Usar Pundit para autorización
83
+ class PostsController < ApplicationController
84
+ def show
85
+ @post = Post.find(params[:id])
86
+ authorize @post # Verificar permisos
87
+ end
88
+
89
+ def index
90
+ @posts = policy_scope(Post) # Solo posts autorizados
91
+ end
92
+ end
93
+
94
+ # ✅ Verificar ownership
95
+ class PostPolicy < ApplicationPolicy
96
+ def update?
97
+ record.user == user || user.admin?
98
+ end
99
+ end
100
+
101
+ # ✅ No exponer IDs secuenciales (usar UUIDs o tokens)
102
+ class Post < ApplicationRecord
103
+ has_secure_token :public_id
104
+
105
+ def to_param
106
+ public_id
107
+ end
108
+ end
109
+ ```
110
+
111
+ ### A02: Cryptographic Failures
112
+
113
+ ```ruby
114
+ # ✅ Usar has_secure_password (bcrypt)
115
+ class User < ApplicationRecord
116
+ has_secure_password
117
+
118
+ # Password requirements
119
+ validates :password, length: { minimum: 12 }, if: :password_required?
120
+ validates :password, format: {
121
+ with: /\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
122
+ message: "must include uppercase, lowercase, and number"
123
+ }, if: :password_required?
124
+ end
125
+
126
+ # ✅ Encriptar datos sensibles con Active Record Encryption
127
+ class User < ApplicationRecord
128
+ encrypts :ssn
129
+ encrypts :api_key, deterministic: true # Para búsquedas
130
+ end
131
+
132
+ # ✅ Configurar encryption
133
+ # config/credentials.yml.enc
134
+ active_record_encryption:
135
+ primary_key: xxx
136
+ deterministic_key: xxx
137
+ key_derivation_salt: xxx
138
+ ```
139
+
140
+ ### A03: Injection
141
+
142
+ ```ruby
143
+ # SQL Injection Prevention
144
+
145
+ # ❌ VULNERABLE
146
+ User.where("email = '#{params[:email]}'")
147
+ User.where("role IN (#{params[:roles].join(',')})")
148
+
149
+ # ✅ SEGURO
150
+ User.where(email: params[:email])
151
+ User.where("email = ?", params[:email])
152
+ User.where(role: params[:roles])
153
+
154
+ # XSS Prevention - Ya escapado por defecto en ERB
155
+ # Solo usar html_safe o raw cuando sea absolutamente necesario
156
+
157
+ # ✅ Sanitizar HTML permitido
158
+ <%= sanitize @post.body, tags: %w[p br strong em a], attributes: %w[href class] %>
159
+
160
+ # Command Injection Prevention
161
+ # ❌ VULNERABLE
162
+ system("convert #{params[:filename]} output.png")
163
+
164
+ # ✅ SEGURO
165
+ system("convert", params[:filename], "output.png")
166
+ # O usar Shellwords
167
+ system("convert #{Shellwords.escape(params[:filename])} output.png")
168
+ ```
169
+
170
+ ### A04: Insecure Design
171
+
172
+ ```ruby
173
+ # ✅ Validar entrada temprano
174
+ class User < ApplicationRecord
175
+ validates :email, presence: true,
176
+ format: { with: URI::MailTo::EMAIL_REGEXP },
177
+ length: { maximum: 255 }
178
+
179
+ validates :name, presence: true,
180
+ length: { minimum: 2, maximum: 100 }
181
+ end
182
+
183
+ # ✅ Principio de mínimo privilegio
184
+ class ApplicationPolicy
185
+ def initialize(user, record)
186
+ @user = user
187
+ @record = record
188
+ end
189
+
190
+ # Denegar todo por defecto
191
+ def index? = false
192
+ def show? = false
193
+ def create? = false
194
+ def update? = false
195
+ def destroy? = false
196
+ end
197
+
198
+ # ✅ Defense in depth
199
+ class PostsController < ApplicationController
200
+ before_action :authenticate_user! # Capa 1: Autenticación
201
+ before_action :set_post, only: [:show, :edit, :update, :destroy]
202
+ after_action :verify_authorized # Capa 2: Autorización
203
+
204
+ def update
205
+ authorize @post # Capa 3: Verificación explícita
206
+ # ...
207
+ end
208
+ end
209
+ ```
210
+
211
+ ### A05: Security Misconfiguration
212
+
213
+ ```ruby
214
+ # config/environments/production.rb
215
+ Rails.application.configure do
216
+ # ✅ Forzar SSL
217
+ config.force_ssl = true
218
+
219
+ # ✅ No mostrar errores detallados
220
+ config.consider_all_requests_local = false
221
+
222
+ # ✅ Logs seguros
223
+ config.log_level = :info
224
+
225
+ # ✅ Configurar hosts permitidos
226
+ config.hosts << "myapp.com"
227
+ config.hosts << /.*\.myapp\.com/
228
+ end
229
+
230
+ # config/initializers/content_security_policy.rb
231
+ Rails.application.configure do
232
+ config.content_security_policy do |policy|
233
+ policy.default_src :self
234
+ policy.font_src :self, :data
235
+ policy.img_src :self, :data, :blob, "https:"
236
+ policy.object_src :none
237
+ policy.script_src :self
238
+ policy.style_src :self, :unsafe_inline
239
+ policy.frame_ancestors :none
240
+ policy.base_uri :self
241
+ policy.form_action :self
242
+ end
243
+
244
+ config.content_security_policy_nonce_generator = ->(request) {
245
+ SecureRandom.base64(16)
246
+ }
247
+ end
248
+
249
+ # config/initializers/permissions_policy.rb
250
+ Rails.application.config.permissions_policy do |policy|
251
+ policy.camera :none
252
+ policy.microphone :none
253
+ policy.geolocation :none
254
+ policy.usb :none
255
+ end
256
+ ```
257
+
258
+ ### A06: Vulnerable Components
259
+
260
+ ```ruby
261
+ # Gemfile - Mantener actualizadas
262
+ ruby "3.3.0"
263
+
264
+ gem "rails", "~> 8.0"
265
+
266
+ # Verificar regularmente
267
+ # bundle outdated
268
+ # bundle update --conservative
269
+
270
+ # Automatizar con Dependabot
271
+ # .github/dependabot.yml
272
+ version: 2
273
+ updates:
274
+ - package-ecosystem: "bundler"
275
+ directory: "/"
276
+ schedule:
277
+ interval: "weekly"
278
+ open-pull-requests-limit: 5
279
+ ```
280
+
281
+ ### A07: Authentication Failures
282
+
283
+ ```ruby
284
+ # ✅ Rate limiting para login
285
+ # config/initializers/rack_attack.rb
286
+ class Rack::Attack
287
+ throttle("logins/ip", limit: 5, period: 60.seconds) do |req|
288
+ req.ip if req.path == "/session" && req.post?
289
+ end
290
+
291
+ throttle("logins/email", limit: 5, period: 60.seconds) do |req|
292
+ if req.path == "/session" && req.post?
293
+ req.params.dig("session", "email")&.downcase
294
+ end
295
+ end
296
+ end
297
+
298
+ # ✅ Account lockout
299
+ class User < ApplicationRecord
300
+ MAX_LOGIN_ATTEMPTS = 5
301
+ LOCKOUT_DURATION = 15.minutes
302
+
303
+ def locked?
304
+ locked_at.present? && locked_at > LOCKOUT_DURATION.ago
305
+ end
306
+
307
+ def increment_failed_attempts!
308
+ increment!(:failed_attempts)
309
+ update!(locked_at: Time.current) if failed_attempts >= MAX_LOGIN_ATTEMPTS
310
+ end
311
+
312
+ def reset_failed_attempts!
313
+ update!(failed_attempts: 0, locked_at: nil)
314
+ end
315
+ end
316
+
317
+ # ✅ Secure session management
318
+ # config/initializers/session_store.rb
319
+ Rails.application.config.session_store :cookie_store,
320
+ key: "_myapp_session",
321
+ secure: Rails.env.production?,
322
+ httponly: true,
323
+ same_site: :lax,
324
+ expire_after: 12.hours
325
+ ```
326
+
327
+ ### A08: Data Integrity Failures
328
+
329
+ ```ruby
330
+ # ✅ Verificar integridad de uploads
331
+ class Document < ApplicationRecord
332
+ has_one_attached :file
333
+
334
+ validates :file, content_type: {
335
+ in: %w[application/pdf image/png image/jpeg],
336
+ message: "must be a PDF or image"
337
+ }
338
+
339
+ validates :file, size: { less_than: 10.megabytes }
340
+
341
+ # Verificar checksum
342
+ after_attach :verify_checksum
343
+
344
+ private
345
+
346
+ def verify_checksum
347
+ return unless file.attached?
348
+
349
+ expected = file.checksum
350
+ actual = Digest::MD5.base64digest(file.download)
351
+
352
+ raise "Checksum mismatch" unless expected == actual
353
+ end
354
+ end
355
+
356
+ # ✅ Signed URLs para downloads
357
+ <%= rails_blob_url(@document.file, disposition: "attachment", expires_in: 1.hour) %>
358
+ ```
359
+
360
+ ### A09: Logging & Monitoring
361
+
362
+ ```ruby
363
+ # ✅ Log eventos de seguridad
364
+ class SecurityLogger
365
+ def self.log_event(event_type, details = {})
366
+ Rails.logger.info({
367
+ type: "security_event",
368
+ event: event_type,
369
+ timestamp: Time.current.iso8601,
370
+ ip: Current.request&.remote_ip,
371
+ user_id: Current.user&.id,
372
+ **details
373
+ }.to_json)
374
+ end
375
+ end
376
+
377
+ # Usar en controllers
378
+ class SessionsController < ApplicationController
379
+ def create
380
+ if user&.authenticate(params[:password])
381
+ SecurityLogger.log_event("login_success", email: params[:email])
382
+ # ...
383
+ else
384
+ SecurityLogger.log_event("login_failure", email: params[:email])
385
+ # ...
386
+ end
387
+ end
388
+ end
389
+
390
+ # ✅ Filtrar parámetros sensibles
391
+ # config/initializers/filter_parameter_logging.rb
392
+ Rails.application.config.filter_parameters += [
393
+ :password, :password_confirmation,
394
+ :token, :secret, :api_key,
395
+ :credit_card, :cvv, :ssn,
396
+ :authorization
397
+ ]
398
+ ```
399
+
400
+ ### A10: Server-Side Request Forgery (SSRF)
401
+
402
+ ```ruby
403
+ # ✅ Validar URLs antes de hacer requests
404
+ class UrlValidator
405
+ BLOCKED_HOSTS = %w[localhost 127.0.0.1 0.0.0.0 ::1]
406
+ BLOCKED_NETWORKS = [
407
+ IPAddr.new("10.0.0.0/8"),
408
+ IPAddr.new("172.16.0.0/12"),
409
+ IPAddr.new("192.168.0.0/16"),
410
+ IPAddr.new("169.254.0.0/16")
411
+ ]
412
+
413
+ def self.safe?(url)
414
+ uri = URI.parse(url)
415
+ return false unless %w[http https].include?(uri.scheme)
416
+ return false if BLOCKED_HOSTS.include?(uri.host)
417
+
418
+ ip = IPAddr.new(Resolv.getaddress(uri.host))
419
+ BLOCKED_NETWORKS.none? { |net| net.include?(ip) }
420
+ rescue StandardError
421
+ false
422
+ end
423
+ end
424
+
425
+ # Usar antes de hacer requests externos
426
+ def fetch_external_resource(url)
427
+ raise "Unsafe URL" unless UrlValidator.safe?(url)
428
+
429
+ HTTP.get(url)
430
+ end
431
+ ```
432
+
433
+ ## Headers de seguridad
434
+
435
+ ```ruby
436
+ # app/controllers/application_controller.rb
437
+ class ApplicationController < ActionController::Base
438
+ before_action :set_security_headers
439
+
440
+ private
441
+
442
+ def set_security_headers
443
+ # Prevenir clickjacking
444
+ response.headers["X-Frame-Options"] = "DENY"
445
+
446
+ # Prevenir MIME sniffing
447
+ response.headers["X-Content-Type-Options"] = "nosniff"
448
+
449
+ # XSS filter (legacy browsers)
450
+ response.headers["X-XSS-Protection"] = "1; mode=block"
451
+
452
+ # Referrer policy
453
+ response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
454
+
455
+ # Permissions policy
456
+ response.headers["Permissions-Policy"] = "geolocation=(), microphone=(), camera=()"
457
+ end
458
+ end
459
+ ```
460
+
461
+ ## Manejo de secretos
462
+
463
+ ```bash
464
+ # Generar master key
465
+ rails credentials:edit
466
+
467
+ # Estructura recomendada
468
+ # config/credentials.yml.enc
469
+ secret_key_base: generado_automaticamente
470
+
471
+ # Base de datos
472
+ database:
473
+ password: xxx
474
+
475
+ # Servicios externos
476
+ stripe:
477
+ secret_key: sk_xxx
478
+ publishable_key: pk_xxx
479
+ webhook_secret: whsec_xxx
480
+
481
+ aws:
482
+ access_key_id: xxx
483
+ secret_access_key: xxx
484
+ bucket: myapp-production
485
+
486
+ # Email
487
+ smtp:
488
+ user_name: xxx
489
+ password: xxx
490
+ ```
491
+
492
+ ```ruby
493
+ # Acceder a credentials
494
+ Rails.application.credentials.stripe[:secret_key]
495
+
496
+ # En config
497
+ config.stripe_key = Rails.application.credentials.dig(:stripe, :secret_key)
498
+ ```
499
+
500
+ ## Testing de seguridad
501
+
502
+ ```ruby
503
+ # spec/requests/security_spec.rb
504
+ RSpec.describe "Security", type: :request do
505
+ describe "headers" do
506
+ before { get root_path }
507
+
508
+ it "sets X-Frame-Options" do
509
+ expect(response.headers["X-Frame-Options"]).to eq("DENY")
510
+ end
511
+
512
+ it "sets X-Content-Type-Options" do
513
+ expect(response.headers["X-Content-Type-Options"]).to eq("nosniff")
514
+ end
515
+
516
+ it "sets CSP header" do
517
+ expect(response.headers["Content-Security-Policy"]).to be_present
518
+ end
519
+ end
520
+
521
+ describe "authentication" do
522
+ it "requires login for protected resources" do
523
+ get dashboard_path
524
+ expect(response).to redirect_to(new_session_path)
525
+ end
526
+ end
527
+
528
+ describe "authorization" do
529
+ let(:user) { create(:user) }
530
+ let(:other_user) { create(:user) }
531
+ let(:post) { create(:post, user: other_user) }
532
+
533
+ it "prevents unauthorized access" do
534
+ sign_in user
535
+ patch post_path(post), params: { post: { title: "Hacked" } }
536
+ expect(response).to have_http_status(:forbidden)
537
+ end
538
+ end
539
+
540
+ describe "rate limiting" do
541
+ it "blocks excessive login attempts" do
542
+ 6.times do
543
+ post session_path, params: { email: "test@test.com", password: "wrong" }
544
+ end
545
+
546
+ expect(response).to have_http_status(:too_many_requests)
547
+ end
548
+ end
549
+ end
550
+ ```
551
+
552
+ ## Checklist de seguridad
553
+
554
+ ### Antes de deploy
555
+
556
+ - [ ] Brakeman sin warnings críticos/altos
557
+ - [ ] bundler-audit sin vulnerabilidades
558
+ - [ ] Secrets en credentials, no en código
559
+ - [ ] HTTPS forzado
560
+ - [ ] Headers de seguridad configurados
561
+ - [ ] CSP implementado
562
+ - [ ] Rate limiting activo
563
+ - [ ] Logs filtrados (sin passwords/tokens)
564
+ - [ ] Backups configurados
565
+ - [ ] Monitoreo de errores activo