Files
car-tracker/executions/phase005.md
T
bionickatana 0826d267f2
CI / scan_ruby (push) Failing after 1m5s
CI / scan_js (push) Failing after 6s
CI / lint (push) Failing after 1m29s
Finished phase005
2026-09-16 15:34:50 -06:00

3.4 KiB

Phase 005 Execution

Scope

  • Added lightweight internal authentication without passwords.
  • Added database-backed monthly access keys with lazy auto-rotation.
  • Added random browser tokens stored in encrypted cookies and mapped to users through server-side session records.
  • Required identification for all application pages except the identify flow and Rails health check.
  • Replaced temporary Unknown User event attribution with the active identified user.
  • Added request and model specs for authenticated and unauthenticated flows.

Changes

  • Added AccessKey model and migration.
  • Added UserSession model and migration.
  • Added Current for request-local user/session access.
  • Added SessionsController with identify, create session, and logout behavior.
  • Added /identify, POST /identify, and DELETE /session routes.
  • Added app/views/sessions/new.html.erb for the “Identify yourself” page.
  • Updated the application layout to show the identified user and a logout button on authenticated pages.
  • Updated ApplicationController to lazily rotate access keys, load the encrypted-cookie auth token, and require identification by default.
  • Updated fuel and maintenance entry creation to set updated_by_user from Current.user.
  • Removed the temporary Unknown User seed and replaced it with initial AccessKey.current creation.
  • Updated vehicle, home, and session request/system specs for the new authentication requirements.

Decisions

  • Access keys are stored in plaintext in the database so the server manager can retrieve the current key with AccessKey.current.raw_key from Rails console.
  • Browser clients store only a random auth token in an encrypted cookie.
  • The database stores only token digests, not raw session tokens.
  • AccessKey.rotate! invalidates all active sessions by deleting UserSession records.
  • Auto-rotation is lazy and runs during normal requests when enabled and expired.
  • Default auto-rotation frequency is 30 days.
  • Auto-rotation can be disabled and re-enabled with AccessKey.current.disable_auto_rotation! and AccessKey.current.enable_auto_rotation!.
  • The rotation frequency can be changed with AccessKey.current.update!(auto_rotation_frequency_days: days).
  • Existing users are matched by normalized email and require an exact stored-name match.
  • /up remains publicly accessible for health checks.
  • DELETE /session uses the logout_path helper because session_path is already used for POST /identify.

Console API

AccessKey.current.raw_key
AccessKey.rotate!
AccessKey.current.disable_auto_rotation!
AccessKey.current.enable_auto_rotation!
AccessKey.current.auto_rotation_frequency_days
AccessKey.current.update!(auto_rotation_frequency_days: 60)

Verification

  • Passed: bundle exec rspec spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb
  • Passed: bundle exec rspec
  • Passed: bin/rubocop app/models/access_key.rb app/models/user_session.rb app/models/current.rb app/models/user.rb app/controllers/application_controller.rb app/controllers/sessions_controller.rb app/controllers/fuel_entries_controller.rb app/controllers/maintenance_entries_controller.rb spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb spec/requests/home_spec.rb spec/system/home_spec.rb db/seeds.rb
  • Passed after lint cleanup: bundle exec rspec