如何授予工程师过滤数据库访问权限 Hello Blazer 进入 Hypershield 将其全部完成!

2025-06-07

如何授予工程师过滤数据库访问权限

你好,布雷泽

进入 Hypershield

总结

完毕!

许多公司(包括 DEV)经常面临的一个问题是,应该赋予工程师多少数据访问权限。允许工程师访问生产数据有很多好处。这可以帮助他们在项目过程中做出更明智的决策,因为他们对将要处理的数据有清晰的了解。当生产代码出现故障,工程师需要找出原因时,这在调试过程中也非常有用。

另一方面,允许工程师访问生产数据也存在风险。你肯定不希望工程师意外更改数据库中不该更改的内容。你的数据库中可能还包含一些你不想让工程师看到的敏感客户数据。我们在 DEV 就遇到过类似的问题,并找到了一个非常满意的解决方案,我想与大家分享。

你好,布雷泽

首先,我们解决了数据库访问问题。我们如何授权工程师访问数据库及其所有信息?有些公司允许工程师访问生产控制台。但这对我们来说不可行,因为我们使用 Heroku,只有几位高级工程师拥有启动控制台所需的 Heroku 完整访问权限。

既然控制台访问已经无法实现,我们开始寻找其他方法。这时,我们发现了Andrew Kane 编写的Blazer 插件。安装后,Blazer 允许用户通过如下所示的 Web UI 查询数据库。

替代文本

除了允许用户查询数据库之外,Blazer 还有许多其他不错的功能,例如:

替代文本

这正是我们所寻找的,因此我们继续按照 gem 主页上概述的步骤将Blazer 添加到 DEV 。

有几点需要注意。首先,我们只开放了super_adminsBlazer 的访问权限,因为我们还需要解决数据隐私和只读访问的问题。

authenticate :user, ->(user) { user.has_role?(:super_admin) } do
  mount Blazer::Engine, at: "blazer"
end
Enter fullscreen mode Exit fullscreen mode

开发设置

请注意,Blazer 使用 ENV 变量BLAZER_DATABASE_URL来指定指向数据库的位置。在开发过程中,我发现如果BLAZER_DATABASE_URL该变量为 nil,Blazer 将使用 ActiveRecord 连接与数据库通信。这使得 Blazer 的设置和开发工作变得非常容易。

生产设置

您还可以BLAZER_DATABASE_URL设置 Blazer,使用单独的用户与数据库通信。使用 Blazer 时,我们最想避免的一件事就是工程师意外更改生产数据。根据 Blazer 的 README 文件:

Blazer 尝试防止修改数据的查询(通过在事务中运行每个查询并将其回滚),但更安全的方法是使用只读用户。

尽管 Blazer 使用了事务,但我们还是想格外小心,通过只读用户来使用它。使用与默认 ActiveRecord 连接不同的 URL,我们可以在 URL 中使用只读用户的凭据,以确保数据不会被更改。

ENV["BLAZER_DATABASE_URL"] = "postgres://read-only-user:read-only-user-password@hostname:5432/database-name"
Enter fullscreen mode Exit fullscreen mode

设置只读用户

Blazer 甚至提供了关于如何为指定数据库设置只读用户的文档。由于我们使用 Postgres 和 Heroku,我根据 Heroku Postgres指南 中概述的步骤,通过 Heroku Postgres 插件创建了只读用户

替代文本

一旦您有了新用户,您就需要获取该用户的名称和密码以及您的数据库名称并创建您的BLAZER_DATABASE_URL

有了这套BLAZER_DATABASE_URL设置,我们现在有了查询生产数据库的 UI,并且数据库受到了保护,不会被任何方式更改。剩下唯一要做的就是过滤数据。

进入 Hypershield

替代文本

不,不是那种盾牌!我们想要的盾牌是能够隐藏敏感用户数据的盾牌。为了实现这一点,我们再次使用了 Andrew Kane 的另一款杰作——Hypershield。它的工作原理如下:

Hypershield 创建屏蔽视图(默认在 hypershield 模式中),用于隐藏敏感表和列。与列级权限相比,这种方法的优势在于您可以使用 SELECT *。

要使其正常工作,第一步是安装 gem,并创建我们想要屏蔽的列列表。我们将 gem 安装在生产组中,因为我们只想在生产环境中运行它。

group :production do
  gem "hypershield", "~> 0.2.0" # Allow admins to query data via internal
  gem "nakayoshi_fork", "~> 0.0.4" # solves CoW friendly problem on MRI 2.2 and later
  gem "rack-host-redirect", "~> 1.3" # Lean and simple host redirection via Rack middleware
end
Enter fullscreen mode Exit fullscreen mode

接下来,我们在初始化文件中创建了我们想要屏蔽的列的列表hypershield.rb

if Rails.env.production?
  Hypershield.enabled = ENV["ENABLE_HYPERSHIELD"].present?

  # Validate that hypershield schema exists before trying to use it
  begin
    if ActiveRecord::Base.connection.schema_exists?("hypershield")
      # Specify the schema to use and columns to show and hide
      Hypershield.schemas = {
        hypershield: {
          # columns to hide
          # matches table.column
          hide: %w[
            auth_data_dump
            email
            encrypted
            encrypted_password
            message_html
            message_markdown
            password
            previous_refresh_token
            refresh_token
            secret
            token
            current_sign_in_ip
            last_sign_in_ip
            reset_password_token
            remember_token
            unconfirmed_email
          ]
        }
      }

      # Log SQL statements
      Hypershield.log_sql = false
    end
  rescue ActiveRecord::NoDatabaseError
    Rails.logger.error("Hypershield initializer failed to check schema due to NoDatabaseError")
  end
end
Enter fullscreen mode Exit fullscreen mode

你会注意到,在配置 Hypershield 之前,我们额外加了几行代码来做不同的检查。首先,我们有:

Hypershield.enabled = ENV["ENABLE_HYPERSHIELD"].present?
Enter fullscreen mode Exit fullscreen mode

如果不存在ENV 变量,此行将禁用在运行迁移时发生的Hypershield 模式refresh任务。ENABLE_HYPERSHIELD

接下来我们有:

if ActiveRecord::Base.connection.schema_exists?("hypershield")
Enter fullscreen mode Exit fullscreen mode

这确保了如果 HyperShield 架构不存在,我们不会尝试设置它并报错。这两行代码非常重要,因为其他社区正在使用 DEV 应用程序源代码,我们不希望由于我们添加到应用程序中的缺失(完全可选)功能而导致其他社区无法使用。

创建架构

一旦 gem 和初始化程序准备就绪,接下来我们需要创建 hypershield 模式。由于我们使用的是 Postgres,因此以下是设置步骤。这些设置步骤以及其他数据库类型的设置步骤均记录在gem 的 README 文件中。

在数据库中创建新的架构

CREATE SCHEMA hypershield;
Enter fullscreen mode Exit fullscreen mode

向您已使用 Blazer 设置的用户授予权限。在本例中,我们希望将所有这些权限授予我们通过 Heroku 设置的只读 Blazer 用户。

GRANT USAGE ON SCHEMA hypershield TO readonly-blazer-username;

-- replace migrations with the user who manages your schema
ALTER DEFAULT PRIVILEGES FOR ROLE heroku-default-user IN SCHEMA hypershield
    GRANT SELECT ON TABLES TO readonly-blazer-username;

-- keep public in search path for functions
ALTER ROLE readonly-blazer-username SET search_path TO hypershield, public;
Enter fullscreen mode Exit fullscreen mode

如果您正在使用 Heroku,则可以通过 Rails 控制台运行这些命令。

sql = <<-SQL
  CREATE SCHEMA hypershield;
SQL
ActiveRecord::Base.connection.execute(sql)
Enter fullscreen mode Exit fullscreen mode

或者您可以使用之前设置的 Blazer 用户凭据通过 Heroku CLI 直接连接到 Postgres。

heroku pg:psql postgres-app-name --credential readonly-blazer-username --app your-app-name
Enter fullscreen mode Exit fullscreen mode

我发现最后一条ALTER ROLE语句需要由我们的只读 Blazer 用户运行,因此您可能需要使用 Heroku CLI 并结合该用户的凭据来执行该语句。另一个 Heroku 小问题是,当您设置只读 Blazer 用户时,它会被授予对公共架构的完全访问权限。您需要使用以下命令撤销此权限。这可确保您的 Blazer 用户只能查看由 Hypershield Gem 设置的屏蔽视图。

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM readonly-blazer-username;
Enter fullscreen mode Exit fullscreen mode

总结

替代文本

在您为 Blazer 只读用户设置好屏蔽模式后,就可以在 Blazer 上进行测试,以确保一切正常。一个简单的方法是SELECT *在您希望过滤的表之一上运行查询。在我们的例子中,我使用消息进行了测试。

替代文本

正如预期的那样,没有任何消息文本或正文字段存在。另一种测试方法是从表中请求您屏蔽的字段之一。在本例中,我尝试message_html从消息中显式请求,但如您所见,我收到了错误。

替代文本

当你对所有测试都满意后,最后要做的就是将 Blazer 开放给你希望使用它的人。在 DEV,我们选择允许所有技术管理员(主要是工程师)访问 Blazer 控制台。

authenticate :user, ->(user) { user.has_role?(:tech_admin) } do
  mount Blazer::Engine, at: "blazer"
end
Enter fullscreen mode Exit fullscreen mode

完毕!

这样就大功告成了!现在,就坐下来,静待同事们的赞叹吧,因为他们终于可以访问他们急需的数据了。

替代文本

文章来源:https://dev.to/molly/how-to-give-engineers-filtered-database-access-8b6
PREV
如何设置只读 Rails 控制台 MySQL Redis Elasticsearch 其他选项
NEXT
开始使用 Elasticsearch 和 Ruby 轮到你了!