{"id":23011560,"url":"https://github.com/ayarotsky/rack-shield","last_synced_at":"2025-06-10T10:40:26.176Z","repository":{"id":49553029,"uuid":"186977595","full_name":"ayarotsky/rack-shield","owner":"ayarotsky","description":"Rack middleware for blocking abusive requests","archived":false,"fork":false,"pushed_at":"2025-03-24T23:08:13.000Z","size":89,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-02T13:11:26.598Z","etag":null,"topics":["rack","rack-middleware","rails","redis","ruby"],"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/ayarotsky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2019-05-16T07:42:12.000Z","updated_at":"2025-02-16T03:50:43.000Z","dependencies_parsed_at":"2024-05-28T04:01:15.089Z","dependency_job_id":"65425bf9-a4ac-4414-8e7e-cc01fded5299","html_url":"https://github.com/ayarotsky/rack-shield","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayarotsky%2Frack-shield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayarotsky%2Frack-shield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayarotsky%2Frack-shield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayarotsky%2Frack-shield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ayarotsky","download_url":"https://codeload.github.com/ayarotsky/rack-shield/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayarotsky%2Frack-shield/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259057401,"owners_count":22799149,"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":["rack","rack-middleware","rails","redis","ruby"],"created_at":"2024-12-15T10:09:29.052Z","updated_at":"2025-06-10T10:40:26.142Z","avatar_url":"https://github.com/ayarotsky.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rack::Shield\n\n![Build Status](https://github.com/ayarotsky/rack-shield/actions/workflows/code_review.yml/badge.svg?branch=main) [![codecov](https://codecov.io/gh/ayarotsky/rack-shield/branch/main/graph/badge.svg?token=X765RW7E2T)](https://codecov.io/gh/ayarotsky/rack-shield)\n\nRack middleware for blocking abusive requests.\nIt uses [redis-shield](https://github.com/ayarotsky/redis-shield) as the rate limiter.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'rack-shield', github: 'ayarotsky/rack-shield'\n```\n\nAnd then execute:\n\n    $ bundle\n\nConfigure your __rack__ application to use `rack-shield` as a middleware:\n\n```ruby\n# In config.ru\n\nrequire 'rack/shield'\nuse Rack::Shield\n```\n\n__IMPORTANT__: `rack-shield` does nothing until you configure protection rules.\nYou can check out the\n[configuration](https://github.com/ayarotsky/rack-shield/blob/master/examples/config.ru)\nexamples.\n\n## Usage\n\n### Redis\n\nThe gem is using `redis` as its backend. First, you need to provide a redis connection:\n\n```ruby\nRack::Shield.redis = Redis.new\n```\n\n### Logging\n\nBy default, no information is logged. But if the logger is configured, the middleware will\noutput its interactions with every request.\n\n```ruby\nRack::Shield.logger = Logger.new(STDOUT)\n```\n\n    [2020-02-25T23:03:08.340305 #70798]  INFO -- : No buckets match request\n    [2020-02-25T23:03:08.148961 #70798]  INFO -- : Request accepted by bucket \"rate limit by PATH_INFO\"\n    [2020-02-25T23:03:07.900751 #70798]  INFO -- : Request rejected by bucket \"rate limit by PATH_INFO\"\n\n### Configuration\n\nThen you can take our example configuration and tailor it to your needs, or check out the advanced configuration examples.\n\nIt's possible to define as many rules as you want. Call `Rack::Shield.configure_bucket` in any file that runs when your app is being initialized. For rails apps this means creating a new file named config/initializers/rack_attack.rb and writing your rules there.\n\n```ruby\n# Configure a bucked named \"rate limit by PATH_INFO\"\nRack::Shield.configure_bucket 'rate limit by PATH_INFO' do |bucket|\n  # A unique key used to store rule data in redis\n  bucket.key = -\u003e(req) { \"test_key_#{req.ip}\" }\n  # A proc to test whether a request should be counted by the bucket\n  bucket.filter = -\u003e(req) { req.env['PATH_INFO'] == '/' }\n  # Bucket lifetime in seconds\n  bucket.period = 1\n  # Number of requests allowed per period\n  bucket.replenish_rate = 4\n  # Rack app used to render a response when a request exceeds the limit\n  bucket.throttled_response = -\u003e(env) { [429, {'Content-Type' =\u003e 'text/plain'}, ['Too Many Requests']] }\nend\n```\n\n#### `#key`\n\nA unique key used to store bucket data in redis.\n\n```ruby\n# Can be a plain string\nRack::Shield.configure_bucket 'test' do |bucket|\n  # [...]\n  bucket.key = 'test_bucket'\nend\n\n# Can be a proc that accepts `Rack::Request` and returns a string\nRack::Shield.configure_bucket 'test' do |bucket|\n  # [...]\n  bucket.key = -\u003e(req) { \"test_key_#{req.ip}\" }\nend\n```\n\n#### `#filter`\n\nA proc that accepts `Rack::Request` and returnsa truthy value that defines whether the request should\nbe counted by the bucket.\n\n```ruby\nRack::Shield.configure_bucket 'test' do |bucket|\n  # [...]\n  bucket.filter = -\u003e(req) { req.env['PATH_INFO'] == '/login' }\nend\n```\n\n#### `#period`\n\nDefines a period in seconds used to limit the number of requests.\n\n#### `#replenish_rate`\n\nNumber of requests allowed per period.\n\n#### `#throttled_response`\n\nA [rack-compatible](https://rack.github.io) object used to render a response when a\nrequest exceeds the limit.\n\nIt can be a simple proc that acceppts\n[rack environment](https://rubydoc.info/github/rack/rack/master/file/SPEC) and returns\nan array of exactly three values: **status**, **headers**, and **body**:\n\n```ruby\nRack::Shield.configure_bucket 'test' do |bucket|\n  # [...]\n  bucket.throttled_response = -\u003e(env) { [429, {'Content-Type' =\u003e 'text/plain'}, ['Too Many Requests']]\nend\n```\n\nOr it can be a Plain Old Ruby Object that contains some complex logic, as shown in\n[examples](https://github.com/ayarotsky/rack-shield/blob/master/examples/throttled_response.rb).\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run rubocop and tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayarotsky%2Frack-shield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fayarotsky%2Frack-shield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayarotsky%2Frack-shield/lists"}