{"id":18656565,"url":"https://github.com/zendesk/samlr","last_synced_at":"2025-11-12T21:41:25.170Z","repository":{"id":4197885,"uuid":"5317046","full_name":"zendesk/samlr","owner":"zendesk","description":"Clean room implementation of SAML for Ruby","archived":false,"fork":false,"pushed_at":"2025-11-07T12:59:51.000Z","size":250,"stargazers_count":29,"open_issues_count":5,"forks_count":11,"subscribers_count":409,"default_branch":"main","last_synced_at":"2025-11-07T13:07:24.155Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zendesk.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2012-08-06T17:16:25.000Z","updated_at":"2025-10-30T13:26:02.000Z","dependencies_parsed_at":"2025-04-11T20:51:04.450Z","dependency_job_id":"d2a847cf-0c7c-427a-9b65-552ef16dc004","html_url":"https://github.com/zendesk/samlr","commit_stats":null,"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/zendesk/samlr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fsamlr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fsamlr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fsamlr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fsamlr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zendesk","download_url":"https://codeload.github.com/zendesk/samlr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zendesk%2Fsamlr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284115869,"owners_count":26949957,"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","status":"online","status_checked_at":"2025-11-12T02:00:06.336Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-07T07:24:03.059Z","updated_at":"2025-11-12T21:41:25.144Z","avatar_url":"https://github.com/zendesk.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Samlr\n\nSamlr is a clean room implementation of SAML for Ruby. It's focused on implementing the service provider (SP) side rather than the identity provider (IdP).\n\nSamlr leverages Nokogiri for the heavy lifting and keeps things simple. Samlr allows you to receive and validate SAML authentication requests. It's SAML 2.0 only, doesn't support everything and makes liberal assumptions about the input - none of which cannot be improved going forward.\n\n### Initiating an authentication request\n\n```ruby\nsaml_request = Samlr::Request.new(nil, {\n    :issuer               =\u003e request.host,\n    :name_identity_format =\u003e Samlr::EMAIL_FORMAT,\n    :consumer_service_url =\u003e \"https://#{request.host}/auth/saml\"\n  })\n```\n\nAt this point you can access `request.param` if all you want is the encoded params, or you can get a fully valid request URL with an appropriate `RelayState` value:\n\n```ruby\nredirect_to saml_request.url(\n  \"https://idp.example.com/auth/saml\", { :RelayState =\u003e request.url }\n)\n```\n\nOnce the IdP receives the request, it prompts the user to authenticate, after which it sends the SAML response to your application.\n\n### Verifying a SAML response\n\nYou can validate a SAML response string using either of the below approaches. The fingerprint is a certificate fingerprint, and the certificate is the certificate PEM (from which Samlr will obtain the fingerprint).\n\n```ruby\nsaml_response = Samlr::Response.new(params[:SAMLResponse], :fingerprint =\u003e fingerprint)\n```\n\nOr using a certificate:\n\n```ruby\nsaml_response = Samlr::Response.new(params[:SAMLResponse], :certificate =\u003e certificate)\n```\n\nYou then verify the response by calling\n\n```ruby\nsaml_response.verify!\n```\n\nIf the verification fails for whatever reason, a `Samlr::Error` will be thrown. This error class has several subclasses and generally contains a useful error message that can help trouble shooting. The error also has a `Samlr::Error#details` value, which contains potentially sensitive data (fingerprint values, canonicalization results).\n\n```ruby\nbegin\n  saml_response.verify!\n  redirect_to success!(saml_response.name_id)\nrescue Samlr::SamlrError =\u003e e\n  logger.warn(\"SAML error #{e.class} #{e.message} #{e.details}\")\n  flash[:error] = e.message\nend\n```\n\nWhen the verification suceeds,the resulting response object will surface `saml_response.name_id` (String) and `saml_response.attributes` (Hash).\n\n### Handling a LogoutRequest from the IdP\n\ni.e. (https://example.com/logout?SAMLRequest=encoded_saml_logout_request)\n\n**Decode the request**\n\n```ruby\nidp_logout_request = Samlr::LogoutRequest.new(params[\"SAMLRequest\"])\n```\n\nThen after logging out the user out you can get a fully valid response URL by:\n\n```ruby\nlogout_response_options = {\n  :destination =\u003e remote_logout_url,\n  :in_response_to =\u003e idp_logout_request.id\n}\nlogout_response = Samlr::LogoutResponse.new(nil, logout_response_options)\n\nlogout_response.url(authentication.remote_logout_url)\n```\n\n### Metadata\n\nCurrently no support for signing, but that should be fairly easy to extract from the `Samlr::Tools::ResponseBuilder`. Get a metadata XML document like this:\n\n```ruby\nxml = Samlr::Tools::MetadataBuilder.build({\n  :entity_id            =\u003e \"https://sp.example.com/saml\",\n  :name_identity_format =\u003e Samlr::EMAIL_FORMAT,\n  :consumer_service_url =\u003e \"https://sp.example.com/saml\"\n})\n```\n\n### Command line\n\nUseful to work with files, e.g.\n\n```\n$ samlr -v --skip-conditions -f 83:CC:12:...:F7:9D:19 response.xml.base64\n$ Verification passed\n```\n\nRun `samlr -h` for options.\n\n```\nSAML response command line tool.\n\nUsage examples:\n  samlr --verify --fingerprint ab:23:cd --skip-conditions \u003cresponse.xml|directory of responses\u003e\n  samlr --verify --skip-fingerprint --skip-conditions \u003cresponse.xml|directory of responses\u003e\n  samlr --schema-validate response.xml\n  samlr --print response.xml[.base64]\n\nTry it with the gem example:\n  ruby -Ilib bin/samlr -v -s -f 44:D2:9D:98:49:66:27:30:3A:67:A2:5D:97:62:31:65:57:9F:57:D1 test/fixtures/sample_response.xml\n\nFull list of options:\n            --verify, -v:   Verify a SAML response document\n   --fingerprint, -f \u003cs\u003e:   The fingerprint to verify the certificate against\n   --skip-conditions, -s:   Skip conditions check\n   --skip-validation, -k:   Skip schema validation rejection\n           --logging, -l:   Log to STDOUT\n  --skip-fingerprint, -i:   Skip certificate fingerprint check\n   --schema-validate, -c:   Perform a schema validation against the input\n             --print, -p:   Pretty prints the XML\n              --help, -h:   Show this message\n```\n\nYou can also validate/test manually using e.g. `xmllint`:\n\n```\nxmllint --noout --schema schema.xsd file.xml\n```\n\n### Testing\n\n```\nbundle install\nrake\n```\n\n### Supported IdPs\n\nPlease help adding IdP's or IdP services you find to work with Samlr. The below list of are known to work:\n\n* Novell/NetIQ\n* MS ADFS 2.0\n* Oracle WebLogic\n* http://simplesamlphp.org/\n* http://www.ssoeasy.com/\n* http://www.okta.com/\n* http://www.onelogin.com/\n* [Salesforce SAML IdP](https://login.salesforce.com/help/doc/en/identity_provider_about.htm)\n\n### Security\n\nAs part of keeping things secure, Samlr does schema validation on all response documents. You can control what it should do in case of invalid documents:\n\n1. Reject the request. This is the recommended and default.\n2. Log the errorneous document. In case you're transitioning to Samlr and want reassurance.\n\nYou control this by setting the schema validation mode in e.g. an initializer\n\n```ruby\nSamlr.validation_mode = :reject\nSamlr.validation_mode = :log\n```\n\n### Logging\n\nSamlr has a (silent) default logger that prints to STDOUT. You can change the log level of this logger if you want to see the output:\n\n```ruby\nSamlr.logger.level = Logger::DEBUG\n```\n\nOr you can replace the logger altogether\n\n```ruby\nSamlr.logger = Rails.logger\n```\n\n### Known Issues\n\nDoes not build on JRuby. See issue #2.\n\n### Contributing\n\nPull requests very welcome. Write tests. Adhere to standards employed (indentation, spaces vs. tabs etc.).\n\n### Releasing a new version\nA new version is published to RubyGems.org every time a change to `version.rb` is pushed to the `main` branch.\nIn short, follow these steps:\n1. Update `version.rb`,\n2. merge this change into `main`, and\n3. look at [the action](https://github.com/zendesk/samlr/actions/workflows/publish.yml) for output.\n\nTo create a pre-release from a non-main branch:\n1. change the version in `version.rb` to something like `1.2.0.pre.1` or `2.0.0.beta.2`,\n2. push this change to your branch,\n3. go to [Actions → “Publish to RubyGems.org” on GitHub](https://github.com/zendesk/samlr/actions/workflows/publish.yml),\n4. click the “Run workflow” button,\n5. pick your branch from a dropdown.\n\n### Error reporting\n\nPull requests with a failing test case much preferred.\n\n### License\n\nCopyright 2014 Zendesk\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzendesk%2Fsamlr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzendesk%2Fsamlr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzendesk%2Fsamlr/lists"}