{"id":13878042,"url":"https://github.com/kobaltz/action_auth","last_synced_at":"2025-07-16T14:30:46.315Z","repository":{"id":206027055,"uuid":"715672469","full_name":"kobaltz/action_auth","owner":"kobaltz","description":"ActionAuth is an authentication Rails engine crafted to integrate seamlessly with your Rails application. Optimized for Rails 7.1.0, it employs the most modern authentication techniques and streamlined token reset processes.","archived":false,"fork":false,"pushed_at":"2024-10-24T03:02:01.000Z","size":234,"stargazers_count":112,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-24T15:09:06.600Z","etag":null,"topics":["authentication","rails","rails-7-1","ruby-on-rails"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kobaltz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-07T15:52:10.000Z","updated_at":"2024-10-24T03:02:05.000Z","dependencies_parsed_at":"2024-01-28T01:25:08.943Z","dependency_job_id":"ed2116f7-a188-4588-8fb8-f1c52b21e836","html_url":"https://github.com/kobaltz/action_auth","commit_stats":null,"previous_names":["kobaltz/action_auth"],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kobaltz%2Faction_auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kobaltz%2Faction_auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kobaltz%2Faction_auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kobaltz%2Faction_auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kobaltz","download_url":"https://codeload.github.com/kobaltz/action_auth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226134226,"owners_count":17578778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","rails","rails-7-1","ruby-on-rails"],"created_at":"2024-08-06T08:01:38.232Z","updated_at":"2025-07-16T14:30:46.290Z","avatar_url":"https://github.com/kobaltz.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# ActionAuth\nActionAuth is an authentication Rails engine crafted to integrate seamlessly\nwith your Rails application. Optimized for Rails 7.2.0, it employs the most modern authentication\ntechniques and streamlined token reset processes. Its simplicity and ease of use let you concentrate\non developing your application, while its reliance on ActiveSupport::CurrentAttributes ensures a\nuser experience akin to that offered by the well-regarded Devise gem.\n\n[![Ruby](https://github.com/kobaltz/action_auth/actions/workflows/test.yml/badge.svg)](https://github.com/kobaltz/action_auth/actions/workflows/test.yml)\n\n## Table of Contents\n1. [Introduction](#introduction)\n2. [Installation](#installation)\n3. [Features](#features)\n4. [Security Features](#security-features)\n   - [Password Security](#password-security)\n   - [Session Security](#session-security)\n   - [Rate Limiting](#rate-limiting)\n   - [Multi-Factor Authentication](#multi-factor-authentication)\n5. [Usage](#usage)\n   - [Routes](#routes)\n   - [Helper Methods](#helper-methods)\n   - [Restricting and Changing Routes](#restricting-and-changing-routes)\n6. [Have I Been Pwned](#have-i-been-pwned)\n7. [Magic Links](#magic-links)\n8. [SMS Authentication](#sms-authentication)\n9. [Account Deletion](#account-deletion)\n10. [WebAuthn](#webauthn)\n11. [Within Your Application](#within-your-application)\n12. Customizing\n   - [Sign In Page](https://github.com/kobaltz/action_auth/wiki/Overriding-Sign-In-page-view)\n13. [License](#license)\n14. [Credits](#credits)\n\n\n## Minimum Requirements\n\n- Ruby 3.3.0 or later recommended\n- Rails 7.2.0 or later **required**\n\n## Installation\n\n### Automatic Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\nbundle add action_auth\n```\n\nThen run the rake task to copy over the migrations, config and routes.\n\n```bash\nbin/rails action_auth:install\n```\n\n### Manual Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\nbundle add action_auth\nbin/rails action_auth:install:migrations\n```\n\nModify config/routes.rb to include the following (note that the path can be anything you want):\n\n```ruby\nmount ActionAuth::Engine =\u003e 'action_auth'\n```\n\nIn your view layout\n\n```ruby\n\u003c% if user_signed_in? %\u003e\n  \u003cli\u003e\u003c%= link_to \"Security\", user_sessions_path %\u003e\u003c/li\u003e\n  \u003cli\u003e\u003c%= button_to \"Sign Out\", user_session_path(current_session), method: :delete %\u003e\u003c/li\u003e\n\u003c% else %\u003e\n  \u003cli\u003e\u003c%= link_to \"Sign In\", new_user_session_path %\u003e\u003c/li\u003e\n  \u003cli\u003e\u003c%= link_to \"Sign Up\", new_user_registration_path %\u003e\u003c/li\u003e\n\u003c% end %\u003e\n```\n\nIf you're using something like importmaps and plain css, then you may need to add the lines below to your `app/assets/config/manifest.js` file.\n\n```javascript\n//= link action_auth/application.css\n//= link action_auth/application.js\n```\n\nSee [WebAuthn](#webauthn) for additional configuration steps if you want to enable WebAuthn.\nIn your `config/initializers/action_auth.rb` file, you can add the following configuration\nsettings.\n\n```ruby\nActionAuth.configure do |config|\n  config.allow_user_deletion = true\n  config.default_from_email = \"from@example.com\"\n  config.magic_link_enabled = true\n  config.passkey_only = true # Allows sign in with only a passkey\n  config.pwned_enabled = true # defined?(Pwned)\n  config.password_complexity_check = true # Requires complex passwords\n  config.session_timeout = 2.weeks # Session expires after this period of inactivity\n  config.sms_auth_enabled = false\n  config.verify_email_on_sign_in = true\n  config.webauthn_enabled = true # defined?(WebAuthn)\n  config.webauthn_origin = \"http://localhost:3000\" # or \"https://example.com\"\n  config.webauthn_rp_name = Rails.application.class.to_s.deconstantize\n\n  config.insert_cookie_domain = false\nend\n\nRails.application.config.after_initialize do\n  ActionAuth.configure do |config|\n    config.sms_send_class = SmsSender\n  end\nend\n```\n\n## Features\n\nThese are the planned features for ActionAuth. The ones that are checked off are currently implemented. The ones that are not checked off are planned for future releases.\n\n✅ - Sign Up, Sign In, Sign Out\n\n✅ - Password reset\n\n✅ - Account Email Verification\n\n✅ - Cookie-based sessions\n\n✅ - Device Session Management\n\n✅ - Multifactor Authentication (through Passkeys)\n\n✅ - Passkeys/Hardware Security Keys\n\n✅ - Passkeys sign in without email/password\n\n✅ - Magic Links\n\n⏳ - OAuth with Google, Facebook, Github, Twitter, etc.\n\n✅ - SMS Authentication\n\n✅ - Have I Been Pwned Integration\n\n✅ - Account Deletion\n\n✅ - Password Complexity Validation\n\n✅ - Rate Limiting\n\n✅ - Session Timeout\n\n✅ - HTTPS-only cookies in production\n\n⏳ - Account Lockout\n\n⏳ - Account Suspension\n\n⏳ - Account Impersonation\n\n## Security Features\n\nActionAuth comes with a robust set of security features designed to protect user accounts and data:\n\n### Password Security\n- Minimum password length of 12 characters\n- Password complexity validation requiring uppercase, lowercase, numbers, and special characters\n- Integration with Have I Been Pwned to check for compromised passwords\n- Password complexity validation can be configured to suit your application's needs\n\n### Session Security\n- Session timeout with configurable duration (default: 2 weeks)\n- Automatic session invalidation on password change\n- HTTPS-only cookies in production environments\n- HttpOnly flag on cookies to prevent JavaScript access\n- SameSite=Lax attribute to prevent CSRF attacks\n- IP address and user agent tracking to detect session hijacking\n- Suspicious activity detection for changed IP/user agent\n\n### Rate Limiting\n- Protection against brute force attacks on login\n- Rate limiting on registration attempts\n- Rate limiting on password reset attempts\n- Rate limiting on WebAuthn authentication\n\n### Multi-Factor Authentication\n- Support for WebAuthn/passkeys as a second factor\n- Modern security key and biometric authentication support\n- Magic link authentication as an alternative authentication method\n\n### Configuration Options\n```ruby\nActionAuth.configure do |config|\n  # Enable password complexity validation\n  config.password_complexity_check = true\n\n  # Set session timeout (defaults to 2 weeks)\n  config.session_timeout = 2.weeks\n\n  # Other settings as needed...\nend\n```\n\n## Usage\n\n### Routes\n\nWithin your application, you'll have access to these routes. They have been styled to be consistent with Devise.\n\n    Method\t\t\t\tVerb\t\tParams\tDescription\n    user_sessions_path\t\tGET\t\t\tDevice session management\n    user_session_path\t\tDELETE\t\t[:id]\tLog Out\n    new_user_session_path\t\tGET\t\t\tLog in\n    new_user_registration_path\tGET\t\t\tSign Up\n    edit_password_path\t\tGET\t\t\tChange Password\n    password_path\t\t\tPATCH\t\t\tUpdate Password\n\n### Helper Methods\n\n    Method\t\t\tDescription\n    current_user\t\tReturns the currently logged in user\n    user_signed_in?\t\tReturns true if the user is logged in\n    current_session\t\tReturns the current session\n\n### Restricting and Changing Routes with Constraints\n\nSometimes, there could be some routes that you would want to prevent access to unless the\nuser is an admin. These routes could be for managing users, or other sensitive data. You\ncan create a constraint to restrict access to these routes.\n\n    # app/constraints/admin_constraint.rb\n\n    class AdminConstraint\n      def self.matches?(request)\n        user = current_user(request)\n        user \u0026\u0026 user.admin?\n      end\n\n      def self.current_user(request)\n         session_token = request.cookie_jar.signed[:session_token]\n         session = ActionAuth::Session.find_by(id: session_token)\n         return nil unless session.present?\n         session.action_auth_user\u0026.becomes(User)\n      end\n    end\n\n    # config/routes.rb\n\n    constraints AdminConstraint do\n      mount GoodJob::Engine =\u003e 'good_job'\n    end\n\nOther times, you may want to have a different kind of view for a user that is logged in\nversus a user that is not logged in.\n\n    # app/constraints/authenticated_constraint.rb\n    class AuthenticatedConstraint\n      def self.matches?(request)\n        session_token = request.cookie_jar.signed[:session_token]\n        ActionAuth::Session.exists?(session_token)\n      end\n    end\n\n    # config/routes.rb\n    constraints AuthenticatedConstraint do\n      root to: 'dashboard#index'\n    end\n    root to: 'welcome#index'\n\n## Have I Been Pwned\n\n[Have I Been Pwned](https://haveibeenpwned.com/) is a way that youre able to check if a password has been compromised in a data breach. This is a great way to ensure that your users are using secure passwords.\n\nAdd the `pwned` gem to your Gemfile. That's all you'll have to do to enable this functionality.\n\n```ruby\nbundle add pwned\n```\n\n## Magic Links\n\nMagic Links are a way to authenticate a user without requiring a password. This is done by sending\nan email to the user with a link that will log them in. This is a great way to allow users to log in\nwithout having to remember a password. This is especially useful for users who may not have a password\nmanager or have a hard time remembering passwords.\n\n## SMS Authentication\n\nSMS Authentication is disabled by default. The purpose of this is to allow users to authenticate\nwith a phone number. This is useful and specific to applications that may require a phone number\ninstead of an email address for authentication. The basic workflow for this is to register a phone\nnumber, and then send a code to the phone number. The user will then enter the code to authenticate.\n\nNo password or email is required for this. I do not recommend enabling this feature for most applications.\n\nYou must set up your own SMS Provider. This is not included in the gem. You will need to configure the\n`sms_send_class` to send the SMS code. This will expect a class method called `send_code` that will take in the parameters\n`phone_number` and `code`.\n\n```ruby\nrequire 'twilio-ruby'\n\nclass SmsSender\n  def self.send_code(phone_number, code)\n    account_sid = ENV['TWILIO_ACCOUNT_SID']\n    auth_token = ENV['TWILIO_AUTH_TOKEN']\n    from_number = ENV['TWILIO_PHONE_NUMBER']\n\n    client = Twilio::REST::Client.new(account_sid, auth_token)\n\n    client.messages.create(\n      from: from_number,\n      to: phone_number,\n      body: \"Your verification code is #{code}\"\n    )\n  end\nend\n```\n\nSince this file could live in the `app/models` or elsewhere, we will need to set its configuration after the Rails\napplication has been loaded. This can be done in an initializer.\n\n```ruby\nRails.application.config.after_initialize do\n  ActionAuth.configure do |config|\n    config.sms_send_class = SmsSender\n  end\nend\n```\n\n## Account Deletion\n\nAccount deletion is a feature that is enabled by default. When a user deletes their account, the account\nis marked as deleted and the user is logged out. The user will no longer be able to log in with their\nemail and password. The user will need to create a new account if they wish to continue using the application.\n\nHere's an example of how you may want to add a delete account button to your application. Obviously, you\nwill want to style this to fit your application and have some kind of confirmation dialog.\n\n```\n\u003cp\u003e\n  Unhappy with the service?\n  \u003c%= button_to \"Delete Account\", action_auth.users_path, method: :delete %\u003e\n\u003c/p\u003e\n```\n\n## WebAuthn\n\nActionAuth's approach for WebAuthn is simplicity. It is used as a multifactor authentication step,\nso users will still need to register their email address and password. Once the user is registered,\nthey can add a Passkey to their account. The Passkey could be an iCloud Keychain, a hardware security\nkey like a Yubikey, or a mobile device. If enabled and configured, the user will be prompted to use\ntheir Passkey after they log in.\n\n#### Configuration\n\nThe migrations are already copied over to your application when you run\n`bin/rails action_auth:install:migrations`. There are only two steps that you have to take to enable\nWebAuthn for your application.\n\nThe reason why you need to add the gem is because it's not added to the gemspec of ActionAuth. This is\nintentional as not all users will want to add this functionality. This will help minimize\nthe number of gems that your application relies on unless if they are features that you want to use.\n\n#### Add the gem\n\n```\nbundle add webauthn\n```\n\n### Configure the WebAuthn settings\n\n**Note:** that the origin name does not have a trailing / or a port number.\n\n```\nActionAuth.configure do |config|\n  config.webauthn_enabled = true\n  config.webauthn_origin = \"http://localhost:3000\" # or \"https://example.com\"\n  config.webauthn_rp_name = Rails.application.class.to_s.deconstantize\n  config.verify_email_on_sign_in = true\n  config.default_from_email = \"from@example.com\"\nend\n```\n\n### Demo\n\nHere's a view of the experience with WebAuthn\n\n![action_auth](https://github.com/kobaltz/action_auth/assets/635114/fa88d83c-5af5-471b-a094-ec9785ea2f87)\n\n## Within Your Application\n\nIt can be cumbersome to have to reference ActionAuth::User within the application as well as in the\nrelationships between models. Luckily, we can use ActiveSupport::CurrentAttributes to make this\nprocess easier as well as inheritance of our models.\n\n#### Setting up the User model\n\n```ruby\n# app/models/user.rb\nclass User \u003c ActionAuth::User\n  has_many :posts, dependent: :destroy\nend\n```\n\n#### Setting up the Current model\n\nWe can set the user to become a User record instead of an ActionAuth::User record. This will then allow `Current.user.posts` to work.\n\n```ruby\n# app/models/current.rb\nclass Current \u003c ActiveSupport::CurrentAttributes\n  def user\n    return unless ActionAuth::Current.user\n    ActionAuth::Current.user\u0026.becomes(User)\n  end\nend\n```\n\n#### Generating an association\n\nWe are using `user:belongs_to` instead of `action_auth_user:belongs_to`.\n\n```bash\nbin/rails g scaffold posts user:belongs_to title\n```\n\nAnd the post model doesn't need anything special to ActionAuth.\n\n```ruby\n# app/models/post.rb\nclass Post \u003c ApplicationRecord\n  belongs_to :user\nend\n```\n\n#### Using the Current model\n\nNow, you'll be able to do things like `Current.user` and `Current.user.posts` within your application. However, I recommend that you still use\nthe helpers around `user_signed_in?` to verify that the `ActionAuth::Current.user` is not nil (or nil if they are signed out). This will help ensure that any thread safety issues are avoided.\n\n## License\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n\n## Credits\n\n❤️ Heavily inspired by [Drifting Ruby #300](https://www.driftingruby.com/episodes/authentication-from-scratch)\nand [Authentication Zero](https://github.com/lazaronixon/authentication-zero) and\n[cedarcode](https://www.cedarcode.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkobaltz%2Faction_auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkobaltz%2Faction_auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkobaltz%2Faction_auth/lists"}