{"id":14955252,"url":"https://github.com/manyfold3d/caber","last_synced_at":"2025-10-24T07:31:01.423Z","repository":{"id":255047088,"uuid":"848378644","full_name":"manyfold3d/caber","owner":"manyfold3d","description":"A simple ReBAC / Zanzibar gem for Rails apps","archived":false,"fork":false,"pushed_at":"2024-12-19T10:19:03.000Z","size":88,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-01-29T08:41:35.961Z","etag":null,"topics":["authorization","rails","rebac","zanzibar"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/caber","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/manyfold3d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2024-08-27T16:46:09.000Z","updated_at":"2025-01-22T17:13:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"677f8e59-d0a4-4b91-ae64-7ec90322fb59","html_url":"https://github.com/manyfold3d/caber","commit_stats":{"total_commits":41,"total_committers":1,"mean_commits":41.0,"dds":0.0,"last_synced_commit":"3ab07d7540628daf4357461c6e8f237d9c73e395"},"previous_names":["manyfold3d/caber"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manyfold3d%2Fcaber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manyfold3d%2Fcaber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manyfold3d%2Fcaber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manyfold3d%2Fcaber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manyfold3d","download_url":"https://codeload.github.com/manyfold3d/caber/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237932070,"owners_count":19389560,"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":["authorization","rails","rebac","zanzibar"],"created_at":"2024-09-24T13:10:45.705Z","updated_at":"2025-10-24T07:31:00.931Z","avatar_url":"https://github.com/manyfold3d.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Caber\n\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/manyfold3d/caber/push.yml)\n[![Maintainability](https://api.codeclimate.com/v1/badges/87209d996d4ffb7517c5/maintainability)](https://codeclimate.com/github/manyfold3d/caber/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/87209d996d4ffb7517c5/test_coverage)](https://codeclimate.com/github/manyfold3d/caber/test_coverage)\n![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/rubygems/caber)\n\n![GitHub Release](https://img.shields.io/github/v/release/manyfold3d/caber)\n![Gem Downloads (for latest version)](https://img.shields.io/gem/dtv/caber)\n![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/rubygems/caber)\n\nA simple [ReBAC](https://en.wikipedia.org/wiki/Relationship-based_access_control) / [Zanzibar](https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/) backend plugin for Rails apps. Allows you to easily specify permission relationships between pairs of objects, e.g. granting edit permission on a document to a specific user, like in Google Docs.\n\n## Installation\n\nAdd caber to your Rails application's Gemfile:\n\n```\nbundle add caber\n```\n\nThen, run the installer:\n\n```\nrails g caber:install\n```\n\nThis will create an initializer and a migration to add the `caber_relations` to your database.\n\nSet up the permission types you want in the `config/initializers/caber.rb` file - a default is provided, but you can change it to whatever combination of permissions you'd like.\n\n## Usage\n\nTo use Caber, include `Caber::Subject` in any of your models that can be given permissions (e.g. Users), and include `Caber::Object` in the things that subjects are given permission TO (e.g. documents):\n\n```\nclass User \u003c ApplicationRecord\n  include Caber::Subject\nend\n\nclass Document \u003c ApplicationRecord\n  include Caber::Object\nend\n```\n\nNow you're ready to grant some permissions! To give someone permission on something:\n\n```\ndocument.grant_permission_to \"viewer\", user\n```\n\nYou can query permissions in both directions:\n```\ndocument.grants_permission_to? \"viewer\", user\nuser.has_permission_on? \"viewer\", document\n```\n\nYou can also check more than one permission at once by passing an array.\nThe check will be positive if *either* are granted:\n\n```\ndocument.grants_permission_to? [\"viewer\", \"editor\"], user\nuser.has_permission_on? [\"viewer\", \"editor\"], document\n```\n\n### Global permissions\n\nTo grant or query permissions globally (for instance, for a public view permission), you can use a `nil` subject:\n\n```\ndocument.grant_permission_to \"viewer\", nil\n```\n\n### Relationships\n\nIn order to query lists of available objects, subjects need to be told what types they can be granted permission on. For each type, after including `Caber::Subject`, call `can_have_permissions_on` with the ActiveRecord class you want to be able to get lists of. `permitted_*` relationships are then automatically added for that type:\n\n```\nclass User \u003c ApplicationRecord\n  include Caber::Subject\n  can_have_permissions_on Document\nend\n\nuser.permitted_documents\n# =\u003e all documents with any granted permission\n\nuser.permitted_documents.with_permission \"viewer\"\n# =\u003e all documents that the user has viewer permission on\n\nuser.permitted_documents.with_permission [\"viewer\", \"editor\"]\n# =\u003e all documents that the user has viewer or editor permission on\n\n```\n\nThe inverse relationship is also possible by specifying `can_grant_permissions_to` on objects:\n\n```\nclass Document \u003c ApplicationRecord\n  include Caber::Object\n  can_grant_permissions_to User\nend\n\ndocument.permitted_users\n# =\u003e all users with any permission\n\ndocument.permitted_users.with_permission \"viewer\"\n# =\u003e all users with viewer permission\n\ndocument.permitted_users.with_permission [\"viewer\", \"editor\"]\n# =\u003e all users with viewer or editor permission\n\n```\n\n### Revoking permissions\n\nYou can revoke some or all permissions from a user:\n\n```\n# Remove a specific permission\ndocument.revoke_permission(\"viewer\", user)\n\n# Remove all permissions from a user\ndocument.revoke_all_permissions(user)\n```\n\n### Finding objects\n\nYou can get lists of objects that a user has some permission on:\n\n```\nDocument.granted_to \"viewer\", user\n# =\u003e All the documents that user has \"viewer\" permission on\n```\n\n## Usage with other gems\n\n### Pundit\n\nCaber makes for nice clear [Pundit](https://github.com/varvet/pundit) policies:\n\n```\nclass DocumentPolicy \u003c ApplicationPolicy\n  class Scope \u003c ApplicationPolicy::Scope\n    def resolve\n      scope.granted_to([\"viewer\", \"editor\", \"owner\"], user)\n    end\n  end\n\n  def update?\n    record.grants_permission_to? [\"editor\", \"owner\"], user\n  end\nend\n```\n\n### Rolify\n\nCaber doesn't include groups specifically, but you can integrate it easily with a role management gem like [Rolify](https://github.com/RolifyCommunity/rolify) pretty easily. Make your Role class a subject, and you can grant permissions to roles:\n\n```\nclass Document \u003c ApplicationRecord\n  include Caber::Object\n  can_grant_permissions_to Role\nend\n\nclass Role \u003c ApplicationRecord\n  include Caber::Subject\n  can_have_permissions_on Document\n\n  scopify\nend\n\ndocument.grant_permission_to \"editor\", Role.find_by(name: \"editor\")\n\nUser.with_role(document.permitted_roles.with_permission(\"editor\"))\n# =\u003e all users with a role that can edit the document\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/manyfold3d/caber. This project is intended to be a safe, welcoming space for collaboration; everyone interacting in the Caber project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/manyfold3d/caber/blob/master/CODE_OF_CONDUCT.md).\n\n## Acknowledgements\n\nThis gem was created as part of [Manyfold](https://manyfold.app), with funding from [NGI0 Entrust](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program.\n\n[\u003cimg src=\"https://nlnet.nl/logo/banner.png\" alt=\"NLnet foundation logo\" width=\"20%\" /\u003e](https://nlnet.nl)\n[\u003cimg src=\"https://nlnet.nl/image/logos/NGI0_tag.svg\" alt=\"NGI Zero Logo\" width=\"20%\" /\u003e](https://nlnet.nl/entrust)\n\nName: `\"ReBAC\".downcase.reverse`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanyfold3d%2Fcaber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanyfold3d%2Fcaber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanyfold3d%2Fcaber/lists"}