3

多云API授权面临的两大挑战

 2 years ago
source link: https://www.51cto.com/article/702415.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
多云API授权面临的两大挑战-51CTO.COM
多云API授权面临的两大挑战 译文
作者:李睿 2022-02-24 08:00:00
本文将介绍声明式应用程序接口(Declarative API)授权如何帮助用户,以及API提供者在部署和运行它们时面临的挑战。

译者 | 李睿

审校 | 梁策 孙淑娟

随着越来越多的企业采用多云战略并增加对云原生基础设施的使用,在多云环境中大规模交付API给API提供者带来了巨大压力。与此同时,无论企业采用何种云平台,API都应遵循每个公司的不同安全要求和优秀实践惯例,而这也是许多API提供者的API授权要求如此复杂的原因。

假设在一家公司中,来自不同业务部门的多个团队正在Azure云平台中构建和部署API。在构建这些API时,不同的团队使用不同的技术(例如Azure Functions、Node.js)。同时该公司可能会托管在同一网络上使用API的应用程序,例如该公司的AWS账户或外部SaaS应用程序。

a4516ce36e77b8047e1034de5fd8be392bd558.png

接着,我们来看看API提供者在部署和运行这些API时会面临什么挑战。

如上所述,在多云环境中构建和部署API时,多个团队使用的技术不尽相同。因此需要一种验证API的方法来确保它们遵循优秀实践惯例。一些企业选择让其各个团队负责,希望由他们提出一些优秀实践,但这种方式通常会导致混乱。要么各个团队遵循的标准和优秀实践无法统一,要么这一过程就因为要加快交付而被忽视。另一种方式则是通过卓越中心(COE)来审查所有API并确保它们遵循优秀实践。但这种方法不可扩展,交付几个API可能适用,但在处理数千个API时,因为需要很长时间,审查就会遭遇阻碍。

很多公司希望这种流程能够自动化,作为持续集成/持续交付(CI/CD)流程的一部分自动验证API。假设每个API都使用API密钥身份验证和授权保证安全,这意味着需要采取一种方式来确保部署API之前开发人员已在API之上采用了正确的安全策略。

在多云环境中执行授权可能会变得更加复杂,给API提供者带来严峻挑战。典型的用例情境是API提供者希望控制允许调用其API的应用程序、用户和IP范围。

存储授权数据的常用方法之一是由身份提供商(IDP)存储,并使用JWT令牌将其传递给后端API。由于这些环境的分布式特性,并可能使用不同授权技术,这种方法通常不适合多云环境。例如,AWS用户与Azure和SaaS用户使用的IDP可能不尽相同。

将用户跨多个IDP的授权数据进行复制,并使它们保持同步是复杂且低效的。API提供者在每个IDP中存储的数据也可能存在一些限制。比如,在本文的典型用例情境下,AWS的IDP管理员就会疑惑为什么他们需要存储AzureAPI的授权数据。

解决方案:声明式API授权

为了解决这个问题,可以使用带有API Ops、Kong Gateway和OPA的声明式配置。在深入探讨它们如何协同工作之前,先来了解一些基础知识。

(1)API Ops

API Ops将DevOps和GitOps原则引入API和微服务生命周期,以尽可能将这些阶段自动化。通过采取声明性配置,这当中很大一部分的自动化都可实现。如果企业一直在使用Kubernetes或DevOps,那么或许已了解声明式配置的概念。使用声明性配置,API Ops可以把API生命周期的大部分自动化。

12915cf45c909f274fd35056935f6efcdb4070.png

(2)开放策略代理(OPA)

开放策略代理(OPA)是一个开源策略引擎,允许用户将策略定义为代码。OPA使用Rego语言来定义这些策略。

可以使用OPA将策略创建为代码,并在其组织中的不同应用程序中执行它们,同时创建能够回答以下问题的OPA策略:

  • 应用程序能否调用客户API?
  • 用户X可以调用客户API吗?
  • 用户A是否有权查看用户B的数据?

OPA的声明性使其非常适合API Ops。创建这些策略,将它们存储在代码存储库中,并在API生命周期的不同阶段使用。

(3)Kong Gateway和开放策略代理

可以将OPA与Kong Gateway集成。下面来看看API使用者、Kong Gateway、OPA服务器和后端API之间的交互过程:

855448028220296953b40615d3676502d78cfa.png

①API消费者向Kong Gateway发送请求。

②Kong Gateway使用OPA插件调用OPA服务器中的策略并接收响应。

③根据OPA服务器的响应,KongGateway判断将请求转发到后端API或返回错误。

OPA策略架构的一个重要部分是将数据与策略定义解耦。在这种情况下,策略可以通过两种方式访问它需要判断的信息:

  • 输入:输入是指消费者向Kong Gateway发送的请求。此外还可以配置OPA插件以将网关的服务、消费者和路由对象也作为输入的一部分发送。
  • 数据:可以使用OPA的API将任意JSON数据推送到策略中。可能有人会问为什么需要数据元素,这是因为输入是关于当前使用者的,而做判断有时需要更多信息,不仅仅是当前的用户场景。例如,任意数据可与用户角色和访问级别有关,而这在输入请求中不存在。

将外部数据注入OPA策略还有其他方法:

(4)持续集成/持续交付(CI/CD)工具和开放策略代理

OPA的一大优点是它可以与大多数技术集成,只要这些技术生成和使用JSON。如今,大多数CI/CD工具都具备开箱即用的库或第三方插件来支持JSON。在部署期间,可以使用OPA来验证:

  • 应用于API的强制Kong插件(例如,身份验证插件)
  • 强制测试用例已经包含在项目中。
  • 用户有权将API部署到目标环境。

在持续部署中执行声明式授权:

①API开发人员使用Insomnia设计API,定义Kong插件并将API规范检查到代码库中。

②作为持续部署的一部分,CI/CD工具对OPA 策略进行调用。OPA策略验证API规范、Kong插件、测试用例和开发人员的授权。

③如果结果成功,CI/CD工具继续该过程,反之停止。

(5)API Ops、Kong Gateway和OPA如何协同工作

b49be6389af382f61f221811f24bf5ae24088c.png

实施此解决方案可按以下步骤:

①在将API部署到Kong Gateway之前,CI/CD工具会调用OPA,并验证强制插件是否在API定义中。如果策略检查通过,那么它会使用声明性配置来部署API。

②消费者应用程序使用IDP或任何其他方法来创建JWT令牌。此令牌具有用户的唯一ID。在此假设用户ID在不同的云平中是唯一的。

③消费者应用程序将请求发送到Kong Gateway。

④Kong Gateway将请求发送到OPA服务器。OPA服务器执行策略并返回结果。

⑤如果Kong Gateway成功,请求将发送到后端API,反之返回错误。

以下将讨论具体执行和详细内容,这里将使用GitHub Actions实现API部署自动化,读者可根据使用的CI/CD工具调整这些脚本。

如何设置GitHub操作和OPA

解决方案的第一部分是确保开发人员已在API之上纳入正确的策略。这意味着API规范中应存在密钥认证和OPA插件。

API开发人员可以使用“x-kong-plugin-”前缀将所需的插件添加到他们的API中。客户Customer API的OpenAPI规范(OAS)如下所示:

openapi: "3.0.0"
info:
  version: 1.0.1
  title: customer api
  license:
    name: Kong

servers:
  - url: ${UPSTREAM_SERVER_URL}$
    description: Upstream server URL.

# Key Auth plugin enables authentication for this service
x-kong-plugin-key-auth:
  enabled: true
  config:
    key_names:
    - apikey

x-kong-plugin-opa:
      enabled: true
      config:
        opa_host: ${OPA_HOST}$
        opa_port: ${OPA_PORT}$
        opa_path: /v1/data/userAuthz/allowUser
        include_consumer_in_opa_input: true
        include_route_in_opa_input: true
        include_service_in_opa_input: true

可以简单地创建一个OPA策略,并在API规范中查找这些插件。

package apiCDAuthz

default allow = false


allow {
  input["x-kong-plugin-key-auth"].enabled == true
  input["x-kong-plugin-opa"].enabled == true

}

如上可见,这一策略在OAS规范中查找这两个插件(例如输入)并检查它们是否已启用。如果两个策略都存在并启用,则返回true;否则,它返回false。

可以通过调用OPA的创建策略API创建此策略:

curl -XPUT http://<opa-server:port>/v1/policies/apiCDAuthz --data-binary @./opa/apiCDAuthz.rego

下一步是将OAS规范发送到OPA策略并检查结果。在这个例子中,OAS规范采用YAML编写,而OPA只能处理JSON。因此,第一步需要导出客户规范并将其转换为JSON,如下GitHub Action工作流程所示:

# Export customer yaml
      - name: Export customer yaml
        run: inso export spec customer-opa --output customer.yaml
      # Transform OAS to JSON
      - uses: fabasoad/yaml-json-xml-converter-action@main
        id: yaml2json
        with:
          path: 'customer.yaml'
          from: 'yaml'
          to: 'json'      
      - name: Prepare OPA input
        run: |
           cat <<EOF > ./v1-data-input.json
           {
                "input": ${{ steps.yaml2json.outputs.data }}
           }
           EOF

然后,可以调用OPA策略并验证JSON数据。

# Check deployment authorisation
      - name: Call OPA to Check Deployment Authorisation
        id: call-opa
        run: |          
            result=$(curl ${{ secrets.OPA_HOST }}/v1/data/apiCDAuthz -d @./v1-data-input.json \
            -H 'Content-Type: application/json' | jq '.result.allow')                      
            echo "::set-output name=result::$result"
            
      - name: Should I continue?       
        run: |
          if ${{ steps.call-opa.outputs.result }}; then
            echo "Call OPA Result: ${{ steps.call-opa.outputs.result }}"            
          else
              echo "Call OPA Result: ${{ steps.call-opa.outputs.result }}"
              exit 1
          fi

如果结果为false(即API规范不符合配置的优秀实践),部署过程将自动失败,系统将通知开发人员。

此示例简单地演示了OPA在部署过程中可以发挥的作用。可以将其扩展为:

  • 检查开发人员授权。
  • 进行高级代码校验。
  • 检查API优秀实践和命名约定。

如何设置Kong Gateway和OPA

如上所述,API提供者希望将其API公开给:

  • Azure的内部使用者。
  • AWS的内部得到者。
  • 使用AWS IDP的外部使用者。
  • 使用Azure IDP的外部使用者。

与此同时,API提供者希望控制调用其API的应用程序、用户和网络。例如,API提供者可能只允许用户使用托管在公司AWS账户中的CRM应用程序调用GET客户。

API开发人员必须已在运行时为这个API配置了OPA插件。否则,它在部署过程就会失败。以下是OPA插件的配置:

x-kong-plugin-opa:
      enabled: true
      config:
        opa_host: ${OPA_HOST}$
        opa_port: ${OPA_PORT}$
        opa_path: /v1/data/userAuthz/allowUser
        include_consumer_in_opa_input: true
        include_route_in_opa_input: true
        include_service_in_opa_input: true

OPA插件将请求、使用者、服务和路由信息发送到OPA服务器中的userAuthz策略。在当前请求之上添加服务、使用者和路由信息有助于访问级别更精细。例如,该策略可以限制用户仅使用某些路由。

现在看一下userAuthz策略:

package userAuthz

default allowUser = false


allowUser = response {
  # Validate JWT token
  v := input.request.http.headers.authorization
  startswith(v, "Bearer ")
  t := substring(v, count("Bearer "), -1)
  io.jwt.verify_hs256(t, data.userAuthz.jwt_signiture)
  [_, payload, _] := io.jwt.decode(t)

  # Validate consumer app
  kong_consumer := input.consumer.username
  some j
  data.userAuthz.apps[j] == kong_consumer

  # Validate network
  net.cidr_contains(data.userAuthz.networkcidr, input.client_ip)


  # Validate user's access to api
  role := data.userAuthz.users[payload.username].role
  serviceName := input.service.name
  access := data.userAuthz.role_service_access[role][serviceName].access
  tier := data.userAuthz.role_service_access[role][serviceName].tier
  some i
  access[i] == input.request.http.method

  response := {
    "allow": true,
    "headers": {
      "x-user-tier": tier,
    },
  }
}

这一策略:

(1)从请求中读取JWT令牌,对其进行验证和解码。

(2)验证客户端IP地址是否被授权调用该API。

(3)验证消费者应用程序是否在批准的应用程序列表中。

(4)验证用户在授权用户列表中并且可执行HTTP方法。

如上所见,这策略使用了数据变量,这些数据通过OPA API注入此策略。

curl -XPUT http://<opa-server:port>/v1/data/userAuthz --data-binary @./opa/userAuthz.json 

如果数据发生变化,可以简单地更新JSON文件并再次调用OPA API。

{
  "jwt_signiture": "46546B41BD5F462719C6D6118E673A2389",
  "networkcidr": "178.10.0.0/24",
  "apps": ["insomnia"],
  "users": {
      "[email protected]": {
        "role": "admin"
      }
  },
  "role_service_access": {
    "admin": {
      "customer_api": {
        "access": ["GET"],
        "tier": "Gold"
      },
      "employee_api": {
        "access": ["GET","POST"],
        "tier": "Silver"
      }
    }
  }
}

通过使用这一策略和数据组合,API提供者只允许具有以下属性的请求调用GET客户API:

  • 由hs256和46546B41BD5F462719C6D6118E673A2389密钥签名的JWT令牌
  • 178.10.0.0/24CIDR内的IP地址
  • 用户ID [email protected]

OPA策略的另一个优点是能够将有用的信息返回到Kong Gateway。这一案例里返回的是每个API的用户访问层级(此处是Gold)。利用这一信息,Kong Gateway可以设置一些访问层级相关的操作,比如根据层级限制速率等等。

使用OPA和声明式策略正变得普遍起来,尤其是在API Ops领域。因为它们:

  • 易于集成:将OPA与Kong Gateway、Kong Mesh和CI/CD工具集成起来非常简单,将OPA与外部数据源集成也很容易。
  • 声明式:声明式使得OPA策略天生适合API Ops和自动化。API提供者可以在API生命周期的不同阶段使用OPA策略,且无需担心它会影响自动化。
  • 极其强大且灵活:OPA使用Rego语言来定义策略。Rego为引用嵌套文档提供了强大的支持,并确保查询正确明了。
  • 不依赖平台:OPA不依赖具体平台。大多数技术和平台它都适用,在不同的云计算供应商和应用程序中可以使用相同的策略。

在多云环境中构建和管理API不是一件容易事,尤其是在安全性和授权方面。将策略即代码与API Ops结合使用,不失为构建自动化和可扩展解决方案的一种好方法。

原文标题:Multi-Cloud API Authorization Challenges,作者:Nima Moghadam


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK