Policy as Code之OPA实现

开发
OPA主要功能是将策略决策与应用程序的业务逻辑分离,将策略看作一组规则。请求被发送到引擎后,引擎会根据规则来进行决策。

作者 | 刘林

前言

在实际生产环境中,许多场景需要进行策略控制,例如,不同团队的API需要限制访问权限,以避免未经授权的网络访问。为实现这种控制,可以采用策略控制的方法。然而,实施策略控制需要修改代码,而且策略通常很分散。为了解决这个问题,可以使用OPA(Open Policy Agent)进行策略控制。

OPA 可以通过定义的策略查询输入数据,并生成决策。例如:

  • 控制哪些用户可以访问哪些资源
  • 控制用户是否有权访问服务器或执行某些操作
  • 控制哪些项目/组件可以部署
  • 控制如何访问数据库
  • 控制哪些资源可以部署到 Kubernetes 中

OPA简介及原理

OPA 是什么

OPA(Open Policy Agent)是一个开源的通用策略引擎,由 Styra 公司于2016年创建并开源,目前已是 CNCF 的毕业项目。其主要功能是将策略决策与应用程序的业务逻辑分离,将策略看作一组规则。请求被发送到引擎后,引擎会根据规则来进行决策。OPA 并不负责具体任务的执行,它仅负责决策。请求通过 JSON 方式传递给 OPA,决策结果也以 JSON 的形式返回。OPA将策略配置统一到一处,极大地降低维护成本,并将策略与对应的软件/服务解耦,方便进行移植和复用。

OPA 策略

OPA 中的策略是以 Rego 这种DSL(Domain Specific Language)来表示的。每个规则都是由头部和主体组成。在 Rego 中,如果规则主体对于某些变量赋值为真,那么我们说规则头为真。可以通过绝对路径引用任何加载到 OPA 中的规则来查询它的值。规则的路径总是:data.PACKAGE.RULE (规则生成的所有值都可以通过全局 data 变量进行查询) 。如果有多个规则相同,则一旦匹配到一个为true的规则,就为true。下面的案例中有具体代码,可在后面的章节详细了解rego编写。

OPA 原理

OPA 将策略执行与决策解耦。当软件需要做出决策时,它向OPA 查询并提供结构化数据(例如JSON)作为输入。其工作原理如下图所示:图片

  • 请求达到OPA Server之后,OPA会将输入的JSON数据作为数据源,并使用定义的规则进行查询。
  • OPA 将查询的结果返回给Server端。
  • Service端根据查询的结果放行或拒绝request。

如何使用OPA

案例一:OPA 实现API权限控制

如果要实现放行角色为admin的用户请求,并且所有人都能够访问路径为/public的GET类型的API,我们可以探究一下OPA 如何实现这个需求:

规则代码

文件名: policy.rego

图片

文件名: input.json 

图片

测试代码

文件名: policy_test.rego

图片

使用命令行验证policy逻辑

如下命令使用input.json文件来验证是否能满足policy.rego文件中的data.policy.allow规则。

图片

附:如只想查看最终结果,可加上--format raw参数,输出如下

图片

使用OPA server验证policy逻辑

opa run 会启动一个交互式 shell ( REPL) 。我们可以使用 REPL 来试验策略和构建策略。

“读取-求值-输出” 循环(Read-Eval-Print Loop,简称REPL)

我们也可以将策略直接加载进去,或者将 OPA 作为一个服务运行并通过 HTTP 执行查询。默认情况下,OPA 监会监听在 8181 端口。

图片

打开postman访问 OPA server, postman信息如下

图片

OPA策略执行流程分析

下图中的请求何满足策略规则呢?

图片

上图请求表示,使用OPA Server中policy包中的allow规则校验该请求。

(1) 查看第一条allow策略 

图片

该策略中仅允许roles是admin的用户执行操作,查看我们postman中body数据,得知roles是developer,顾这条策略不满足,OPA会继续查看其他策略。

(2) 查看第二条allow策略

图片

该策略中仅允许request path是/public开头且请求方法是GET的请求, 满足我们postman中的request内容,顾该请求满足策略要求。

案例二:OPA在Kubernetes中的使用案例

由于OPA应用到Kubernetes中时,需要较多的Kubernetes基础,这里想淡化对Kubernetes基础的要求,所以使用Gatekeeper来集成Kubernetes。

Gatekeeper是一个开源的使用OPA来定义和执行策略的系统

下文将实现不允许在default namespace中部署deployment资源的案例。

部署Gatekeeper到Kubernetes

图片

Kubernetes中的策略

(1) 策略文件准备 

文件名:template.yaml

图片图片

文件名:constraint.yaml

图片图片

文件名nginx-app.yaml

图片

(2) 创建策略 

图片

验证策略

(1) 尝试在default namespace中创建deployment资源

尝试创建资源的时候,会出现如下报错,因为OPA策略中已经指定,不允许在default namespace中创建deployment资源。 

图片

(2) 尝试在其他namespace中创建deployment资源

创建demo namespace,并尝试在该namespace中创建deployment资源,可成功创建。

图片图片

总结

  • OPA是一个开放源代码的通用策略引擎,将策略决策与应用程序的业务逻辑分离。
  • OPA将输入的JSON数据作为数据源,使用定义的规则进行查询,返回最终的结果(allow 或者 deny)。
  • 目前基于OPA的产品有Gatekeeper, Styra。如果是项目使用的话,个人推荐使用Styra,因为Styra的策略和input数据是有可视化页面的,使用和排错成本较低。
  • Rego是基于查询进行断言的语言,基于规则查询结果,给出true或false的查询语言。
责任编辑:赵宁宁 来源: Thoughtworks洞见
相关推荐

2023-06-26 10:51:56

开源API

2021-11-19 11:53:42

云计算混合云Kubernetes

2024-02-02 12:42:42

C++Policy模板

2022-07-28 10:46:16

开放策略代理引擎

2022-03-28 07:33:13

GatekeeperOPA 策略管理CRD

2011-03-17 17:10:49

iptablesmatchpolicy

2023-04-13 07:52:59

2022-08-19 08:00:00

OPA集成Kubernetes集群

2012-03-07 14:32:41

Node.js

2014-03-12 09:52:17

XcodeCode Snippe

2020-10-12 14:40:28

VS Code代码平台

2011-02-25 09:59:25

ibmdwJava

2022-03-24 07:44:41

OPA安全策略Rego

2013-11-14 13:27:38

AndroidAudio

2018-09-12 15:11:35

微软GitHub开发者

2021-04-14 20:10:50

Netfileter Iptables 源码

2021-08-03 05:00:57

Python实现导数

2010-01-21 11:19:44

TCP Socketlinux

2016-11-25 10:52:10

WOT2016大数据

2021-08-11 07:02:04

Python激活函数
点赞
收藏

51CTO技术栈公众号