Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
declarative-policy — 声明式授权库,提供用于编写策略规则、条件和缓存的DSL。支持Ruby应用程序实现可扩展、DRY的权限管理。 | Kitploit
工具/GitLabGitLab/gitlab-org/ruby/gems/declarative-policy
身份验证与授权实用工具与框架
GitLabgitlab-org/ruby/gems/declarative-policy

declarative-policy

声明式授权库,提供用于编写策略规则、条件和缓存的DSL。支持Ruby应用程序实现可扩展、DRY的权限管理。

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
171026个月前尚未审核

DeclarativePolicy:一个声明式授权库

Gem Version

该库提供了一个用于编写授权策略的 DSL。

它可以用于将逻辑与权限分离,并已在 GitLab.com 的生产环境中大规模使用。

该库的原始作者是 Jeanine Adkisson,版权归 GitLab 所有。

安装

在应用的 Gemfile 中添加以下内容:

root@kitploit:~
gem 'declarative_policy'

然后执行:

root@kitploit:~
$ bundle install

或者通过以下方式自行安装:

root@kitploit:~
$ gem install declarative_policy

示例

root@kitploit:~
require 'declarative_policy'

class User
  attr_reader :name

  def initialize(name:)
    @name = name
  end
end

class Vehicle
  def initialize(owner:, trusted: [])
    @owner = owner
    @trusted = trusted
  end

  def owner?(user)
    @owner.name == user.name
  end

  def trusted?(user)
    @owner.name == user.name || @trusted.detect { |t| t.name == user.name }
  end
end

class VehiclePolicy < DeclarativePolicy::Base
  condition(:owns) { @subject.owner?(@user) }
  condition(:trusted) { @subject.trusted?(@user) }

  rule { owns }.enable :sell_vehicle
  rule { trusted }.enable :drive_vehicle
end

jack = User.new(name: 'jack')
jill = User.new(name: 'jill')
jacks_vehicle = Vehicle.new(owner: jack, trusted: [jill])
jills_vehicle = Vehicle.new(owner: jill, trusted: [jack])

puts "Jack can drive Jack's vehicle? -> #{DeclarativePolicy.policy_for(jack, jacks_vehicle).can?(:drive_vehicle)}"
puts "Jack can drive Jill's vehicle? -> #{DeclarativePolicy.policy_for(jack, jills_vehicle).can?(:drive_vehicle)}"
puts "Jack can sell Jack's vehicle? -> #{DeclarativePolicy.policy_for(jack, jacks_vehicle).can?(:sell_vehicle)}"
puts "Jack can sell Jill's vehicle? -> #{DeclarativePolicy.policy_for(jack, jills_vehicle).can?(:sell_vehicle)}"
root@kitploit:~
$ ruby example.rb
Jack can drive Jack's vehicle? -> true
Jack can drive Jill's vehicle? -> true
Jack can sell Jack's vehicle? -> true
Jack can sell Jill's vehicle? -> false

使用

该库的核心抽象是 Policy(策略)。策略结合了:

  • 事实(称为 conditions,条件)——关于世界状态的事实
  • 对这些事实的判断(称为 rules,规则)

该库的存在是为了确定以下形式语句的真值:

root@kitploit:~
用户 谓语 [主体]

关于将 用户 重命名为 行动者、主体 重命名为 资源 的讨论,请参阅此 issue。

例如:

  • user :is_alive
  • user :can_drive car
  • user :can_sell car

它通过允许我们将一个 Policy(一组关于哪些语句为真的规则)与语句的对象关联起来实现这一点。如果没有任何规则 prevents(阻止)它,并且至少有一条规则 enables(启用)它,则认为该语句成立。

例如,假设我们有一个包含车辆和用户的数据模型,我们想知道用户是否可以驾驶一辆车。我们需要一个 VehiclePolicy:

root@kitploit:~
class VehiclePolicy < DeclarativePolicy::Base
  # 相关事实
  condition(:owns) { @subject.owner == @user }
  condition(:has_access_to) { @subject.owner.trusts?(@user) }
  condition(:old_enough_to_drive) { @user.age >= laws.minimum_age }
  condition(:has_driving_license) { @user.driving_license&.valid? }
  # 昂贵的规则可以有 'score'。分数越高,计算成本越高
  condition(:owns, score: 0) { @subject.owner == @user }
  condition(:has_access_to, score: 3) { @subject.owner.trusts?(@user) }
  condition(:intoxicated, score: 5) { @user.blood_alcohol > laws.max_blood_alcohol }

  # 我们可以得出的结论:
  rule { owns }.enable :drive_vehicle
  rule { has_access_to }.enable :drive_vehicle
  rule { ~old_enough_to_drive }.prevent :drive_vehicle
  rule { intoxicated }.prevent :drive_vehicle
  rule { ~has_driving_license }.prevent :drive_vehicle

  # 我们可以使用方法抽象公共逻辑
  def laws
    @subject.registration.country.driving_laws
  end
end

需要注意几点:我们可以将其写成一条大规则((owns | has_access_to) & old_enough_to_drive & ~intoxicated & has_driving_license),但我们可以看出声明式策略的一些特性使其适用于大型系统:规则可以拆分成小元素,并组合成更大的规则。可以随时添加新的条件和规则。

不太明显的是,许多性能优化已经为我们透明地处理了:

  • 成本更高的条件会在后面被调用
  • 我们自动获得所需的分组(评估所有可能阻止某个动作的条件,但一旦我们至少有一个启用调用就停止)
  • 中间值会被缓存
  • 策略支持继承和委托,这意味着授权逻辑保持 DRY(不重复自己)。

简而言之,该库旨在声明式:我们声明重要的规则,库来安排如何评估它们。

缓存是策略的一个特别有价值的功能。例如,如果我们在出售车辆时添加新规则:

root@kitploit:~
rule { owns }.enable :sell_vehicle

那么所有权的事实可以在对策略的不同调用之间共享,从而节省数据库调用和其他昂贵的 I/O 操作。

评估策略:

我们可以通过以下方式检查策略的判定:

root@kitploit:~
cache = Session.current_session
policy = DeclarativePolicy.policy_for(user, car, cache: cache)
policy.can?(:drive_vehicle)

有关更多使用细节,请参阅文档。

开发

签出仓库后,运行 bundle install 来安装依赖项。然后运行 rake spec 来运行测试。你也可以运行 bin/console 来获得一个交互式提示符,以便进行实验。

要将此 gem 安装到你的本地机器上,运行 bundle exec rake install。要发布新版本,请更新 version.rb 中的版本号,然后运行 bundle exec rake release,这将为该版本创建一个 git 标签,推送 git 提交和标签,并将 .gem 文件推送到 rubygems.org。

补充阅读材料

有关策略和自定义角色的更多详细信息,请参阅以下页面:

  • DeclarativePolicy 框架的开发流程
  • 自定义角色文档

贡献

欢迎在 GitLab 上提交错误报告和合并请求:https://gitlab.com/gitlab-org/ruby/gems/declarative-policy。该项目旨在成为一个安全、欢迎合作的协作空间,贡献者应遵守 GitLab 行为准则。

发布流程

我们不定期发布 declarative_policy。发布没有规律性,我们只在做出更改时发布——无论更改大小如何。

发布新版本:

  1. 创建一个合并请求。
  2. 使用合并请求模板 Release.md。
  3. 遵循说明。
  4. 合并请求合并后,新版本的 gem 会自动发布。
  5. 一旦新版本的 gem 在 RubyGems.org 上可见,建议更新 GitLab 的 Gemfile,将 declarative_policy Ruby gem 升级到新版本。

许可证

该 gem 以 MIT 许可证 的条款作为开源发布。

行为准则

所有与 DeclarativePolicy 项目的代码库、问题跟踪器、聊天室和邮件列表互动的人员都应遵守行为准则。

下载工具