{"id":19745162,"url":"https://github.com/castle/castle-ruby","last_synced_at":"2025-12-17T23:26:32.439Z","repository":{"id":869070,"uuid":"12895364","full_name":"castle/castle-ruby","owner":"castle","description":"Ruby gem for Castle","archived":false,"fork":false,"pushed_at":"2024-10-31T00:42:19.000Z","size":849,"stargazers_count":34,"open_issues_count":2,"forks_count":18,"subscribers_count":22,"default_branch":"develop","last_synced_at":"2024-10-31T01:23:01.262Z","etag":null,"topics":["castle","fraud-detection","fraud-prevention","ruby","sdk"],"latest_commit_sha":null,"homepage":"https://castle.io","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/castle.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"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":"2013-09-17T13:05:43.000Z","updated_at":"2024-10-31T00:27:40.000Z","dependencies_parsed_at":"2024-08-12T08:26:03.221Z","dependency_job_id":"3235f86e-67c1-41e0-92d4-bef6899f2c32","html_url":"https://github.com/castle/castle-ruby","commit_stats":null,"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castle%2Fcastle-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castle%2Fcastle-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castle%2Fcastle-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castle%2Fcastle-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/castle","download_url":"https://codeload.github.com/castle/castle-ruby/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224202878,"owners_count":17272807,"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":["castle","fraud-detection","fraud-prevention","ruby","sdk"],"created_at":"2024-11-12T02:04:29.013Z","updated_at":"2025-10-28T10:03:40.702Z","avatar_url":"https://github.com/castle.png","language":"Ruby","readme":"# Ruby SDK for Castle\n\n[![Build Status](https://circleci.com/gh/castle/castle-ruby.svg?style=shield\u0026branch=master)](https://circleci.com/gh/castle/castle-ruby)\n[![Coverage Status](https://coveralls.io/repos/github/castle/castle-ruby/badge.svg?branch=coveralls)](https://coveralls.io/github/castle/castle-ruby?branch=coveralls)\n[![Gem Version](https://badge.fury.io/rb/castle-rb.svg)](https://badge.fury.io/rb/castle-rb)\n\n**[Castle](https://castle.io) analyzes user behavior in web and mobile apps to stop fraud before it happens.**\n\n## Installation\n\nAdd the `castle-rb` gem to your `Gemfile`\n\n```ruby\ngem 'castle-rb'\n```\n\n## Configuration\n\n### Framework configuration\n\nLoad and configure the library with your Castle API secret in an initializer or similar.\n\n```ruby\nCastle.api_secret = 'YOUR_API_SECRET'\n```\n\nA Castle client instance will be made available as `castle` in your\n\n- Rails controllers when you add `require 'castle/support/rails'`\n\n- Padrino controllers when you add `require 'castle/support/padrino'`\n\n- Sinatra app when you add `require 'castle/support/sinatra'` (and additionally explicitly add `register Sinatra::Castle` to your `Sinatra::Base` class if you have a modular application)\n\n```ruby\nrequire 'castle/support/sinatra'\n\nclass ApplicationController \u003c Sinatra::Base\n  register Sinatra::Castle\nend\n```\n\n- Hanami when you add `require 'castle/support/hanami'` and include `Castle::Hanami` to your Hanami application\n\n```ruby\nrequire 'castle/support/hanami'\n\nmodule Web\n  class Application \u003c Hanami::Application\n    include Castle::Hanami\n  end\nend\n```\n\n### Client configuration\n\n```ruby\nCastle.configure do |config|\n  # Same as setting it through Castle.api_secret\n  config.api_secret = 'secret'\n\n  # For authenticate method you can set failover strategies: allow(default), deny, challenge, throw\n  config.failover_strategy = :deny\n\n  # Castle::RequestError is raised when timing out in milliseconds (default: 1000 milliseconds)\n  config.request_timeout = 1500\n\n  # Base Castle API url\n  # config.base_url = \"https://api.castle.io/v1\"\n\n  # Logger (need to respond to info method) - logs Castle API requests and responses\n  # config.logger = Logger.new(STDOUT)\n\n  # Allowlisted and Denylisted headers are case insensitive and allow to use _ and - as a separator, http prefixes are removed\n  # Allowlisted headers\n  # By default, the SDK sends all HTTP headers, except for Cookie and Authorization.\n  # If you decide to use a allowlist, the SDK will:\n  # - always send the User-Agent header\n  # - send scrubbed values of non-allowlisted headers\n  # - send proper values of allowlisted headers.\n  # @example\n  #   config.allowlisted = ['X_HEADER']\n  #   # will send { 'User-Agent' =\u003e 'Chrome', 'X_HEADER' =\u003e 'proper value', 'Any-Other-Header' =\u003e true }\n  #\n  # We highly suggest using denylist instead of allowlist, so that Castle can use as many data points\n  # as possible to secure your users. If you want to use the allowlist, this is the minimal\n  # amount of headers we recommend:\n  config.allowlisted = Castle::Configuration::DEFAULT_ALLOWLIST\n\n  # Denylisted headers take precedence over allowlisted elements\n  # We always denylist Cookie and Authentication headers. If you use any other headers that\n  # might contain sensitive information, you should denylist them.\n  config.denylisted = ['HTTP-X-header']\n\n  # Castle needs the original IP of the client, not the IP of your proxy or load balancer.\n  # The SDK will only trust the proxy chain as defined in the configuration.\n  # We try to fetch the client IP based on X-Forwarded-For or Remote-Addr headers in that order,\n  # but sometimes the client IP may be stored in a different header or order.\n  # The SDK can be configured to look for the client IP address in headers that you specify.\n\n  # Sometimes, Cloud providers do not use consistent IP addresses to proxy requests.\n  # In this case, the client IP is usually preserved in a custom header. Example:\n  # Cloudflare preserves the client request in the 'Cf-Connecting-Ip' header.\n  # It would be used like so: config.ip_headers=['Cf-Connecting-Ip']\n  config.ip_headers = []\n\n  # If the specified header or X-Forwarded-For default contains a proxy chain with public IP addresses,\n  # then you must choose only one of the following (but not both):\n  # 1. The trusted_proxies value must match the known proxy IPs. This option is preferable if the IP is static.\n  # 2. The trusted_proxy_depth value must be set to the number of known trusted proxies in the chain (see below).\n  # This option is preferable if the IPs are ephemeral, but the depth is consistent.\n\n  # Additionally to make X-Forwarded-For and other headers work better discovering client ip address,\n  # and not the address of a reverse proxy server, you can define trusted proxies\n  # which will help to fetch proper ip from those headers\n\n  # In order to extract the client IP of the X-Forwarded-For header\n  # and not the address of a reverse proxy server, you must define all trusted public proxies\n  # you can achieve this by listing all the proxies ip defined by string or regular expressions\n  # in the trusted_proxies setting\n  config.trusted_proxies = []\n\n  # or by providing number of trusted proxies used in the chain\n  config.trusted_proxy_depth = 0\n\n  # note that you must pick one approach over the other.\n\n  # If there is no possibility to define options above and there is no other header that holds the client IP,\n  # then you may set trust_proxy_chain = true to trust all of the proxy IPs in X-Forwarded-For\n  config.trust_proxy_chain = false\n  # *Warning*: this mode is highly promiscuous and could lead to wrongly trusting a spoofed IP if the request passes through a malicious proxy\n\n  # *Note: the default list of proxies that are always marked as \"trusted\" can be found in: Castle::Configuration::TRUSTED_PROXIES\nend\n```\n\n### Multi-environment configuration\n\nIt is also possible to define multiple configs within one application.\n\n```ruby\n# Initialize new instance of Castle::Configuration\nconfig =\n  Castle::Configuration.new.tap do |c|\n    # and set any attribute\n    c.api_secret = 'YOUR_API_SECRET'\n  end\n```\n\nAfter a successful setup, you can pass the config to any API command as follows:\n\n```ruby\n::Castle::API::GetDevice.call(device_token: device_token, config: config)\n```\n\n## Usage\n\nSee [documentation](https://docs.castle.io/docs/) for how to use this SDK with the Castle APIs\n\n## Exceptions\n\n`Castle::Error` will be thrown if the Castle API returns a 400 or a 500 level HTTP response.\nYou can also choose to catch a more [finegrained error](https://github.com/castle/castle-ruby/blob/master/lib/castle/errors.rb).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcastle%2Fcastle-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcastle%2Fcastle-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcastle%2Fcastle-ruby/lists"}