跳至內容

Knative 事件授權

追蹤問題#7256

概述

保護 Knative 事件處理中的事件傳遞對於防止未經授權的存取至關重要。為了對事件傳遞強制執行細粒度的控制,Knative 事件處理引入了 EventPolicy 自訂資源,允許使用者指定哪些實體被授權將事件發送到命名空間中的特定消費者。

先決條件

注意

authentication-oidc 中所述,為了確保安全驗證,也應啟用 transport-encryption。請查看 傳輸加密,其中說明如何啟用傳輸加密功能標誌。

相容性

目前支援以下元件的授權

預設授權模式

管理員可以使用 defaultAuthorizationMode 功能標誌設定預設授權模式,Knative 事件處理會在沒有 EventPolicy 適用於資源時使用此模式。可用的模式如下

  • allow-all:允許所有請求。
  • deny-all:拒絕所有請求,強制建立 EventPolicy。
  • allow-same-namespace:僅允許來自相同命名空間內主體的請求。(預設)

定義 EventPolicy

EventPolicy 定義事件傳遞的規則,方法是指定哪些主體(服務帳戶或事件來源)被允許將事件發送到指定的事件消費者。

apiVersion: eventing.knative.dev/v1alpha1
kind: EventPolicy
metadata:
  name: my-event-policy
  namespace: default
spec:
  to:
    - ref:
        apiVersion: eventing.knative.dev/v1
        kind: Broker
        name: my-broker
    - selector:
        apiVersion: eventing.knative.dev/v1
        kind: Broker
        matchLabels:
          app: special-app
  from:
    - ref:
        apiVersion: sources.knative.dev/v1
        kind: PingSource
        name: my-source
        namespace: another-namespace
    - sub: system:serviceaccount:default:trusted-app
    - sub: "system:serviceaccount:default:other-*"
  filters:
    - cesql: "type IN ('order.created', 'order.updated', 'order.canceled')"
    - exact:
        type: com.github.push

指定 EventPolicy 適用於哪些對象

.spec.to 區段指定允許事件發送的位置。此欄位為選填;如果留空,則此政策適用於命名空間內的所有資源。透過在 .spec.to 中指定多個目標,可透過將相同的規則應用於多個目標來擴大 EventPolicy 的範圍。

有兩種方法可以定義這些目標

  1. to.ref:
    • 定義:直接參考特定資源。
    • 範例:在上面的 EventPolicy 中,直接參考 my-broker Broker。這表示 EventPolicy 適用於此特定的 Broker
    • 使用案例:當您想要依名稱保護特定資源時,請使用 to.ref
      to:
        - ref:
            apiVersion: eventing.knative.dev/v1
            kind: Broker
            name: my-broker
      
  2. to.selector:

    • 定義:使用標籤選擇器來比對特定類型的多個資源。
    • 範例EventPolicy 包括一個標籤與 app: special-app 比對的 Broker。這表示 EventPolicy 適用於所有具有這些標籤的 Brokers
    • 使用案例:當您希望 EventPolicy 適用於一組共用通用標籤的資源時,請使用 to.selector
    to:
      - selector:
          apiVersion: eventing.knative.dev/v1
          kind: Broker
          matchLabels:
            app: special-app
    

指定允許誰發送事件

.spec.from 區段指定允許將事件發送到 .spec.to 中定義的目標。有兩種方法可以定義這些來源

  1. from.ref:

    • 定義:直接參考特定的事件來源資源。
    • 範例:參考 another-namespace 中的 my-source PingSource,表示此特定來源被允許發送事件。
    • 使用案例:當您想要授權特定事件來源時,請使用 from.ref
      from:
        - ref:
            apiVersion: sources.knative.dev/v1
            kind: PingSource
            name: my-source
            namespace: another-namespace
      
  2. from.sub:

    • 定義:指定允許發送事件的主體(服務帳戶名稱)。它可以包含萬用字元模式作為後綴 (*) 以進行更廣泛的匹配。
    • 範例EventPolicy 允許來自預設命名空間中的 trusted-app 服務帳戶的事件,以及預設命名空間中任何以 other- 開頭的服務帳戶的事件。
    • 使用案例:使用 from.sub 來允許特定使用者或服務帳戶,或應用萬用字元模式以獲得更大的彈性。
      from:
        - sub: system:serviceaccount:default:trusted-app
        - sub: "system:serviceaccount:default:other-*"
      

進階 CloudEvent 篩選條件

.spec.filters 區段是選填,並指定事件本身必須滿足的額外條件才允許。

  • 範例:只允許 type 等於 com.github.push 且符合特定 CESQL 表達式的 CloudEvent。
  • 使用案例:當您想要對允許的 CloudEvent 有更細緻的條件時,請使用 filters
    from:
      filters:
        - cesql: "type IN ('order.created', 'order.updated', 'order.canceled')"
        - exact:
            type: com.github.push
    

如果指定了篩選器,則事件必須符合 EventPolicy所有指定篩選器(除了其 .spec.from 之外)才能被接受。.spec.filters 接受與 Triggers 相同的篩選器方言。

注意

除了 .spec.from 之外,還會應用篩選器。這表示,一旦 EventPolicy 指定了 .spec.filters,它們必須與請求以及 .spec.from 相符(AND 運算)。只有這樣,EventPolicy 才會允許該請求。

.spec 欄位摘要:

  • to.ref 指向特定的資源。
  • to.selector 根據標籤指向一組資源。
  • from.ref 授權特定的事件來源資源。
  • from.sub 授權特定的使用者、服務帳戶或帳戶模式。
  • .spec.filters 允許定義進階的 CloudEvent 篩選條件。

EventPolicy 狀態

EventPolicy 的狀態提供有關已解析來源和就緒狀態的資訊。

status:
  from:
    - system:serviceaccount:default:my-source-oidc-sources.knative.dev-pingsource
    - system:serviceaccount:default:trusted-app
    - "system:serviceaccount:default:other-*"
  conditions:
    - type: Ready
      status: "True"
    - type: SubjectsResolved
      status: "True"

將 EventPolicy 應用到資源

事件消費者(例如 Broker)將在其狀態中列出適用的 EventPolicy。

apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: my-broker
spec:
  ...
status:
  ...
  policies:
    - name: my-event-policy
      apiVersion: v1alpha1
  conditions:
    - type: Ready
      status: "True"
    - type: EventPoliciesReady
      status: "True"

EventPoliciesReady 條件指示資源的所有適用 EventPolicy 是否已就緒且已成功應用。

拒絕行為

如果請求未通過任何適用的 EventPolicy,它將被拒絕,並返回 403 Forbidden HTTP 狀態碼,以確保未經授權的事件傳遞被阻止。如果多個政策適用於同一個資源,只要事件符合至少一個適用的 EventPolicy,該事件就會被傳遞。這確保即使實施了嚴格的政策,符合任何政策標準的有效事件仍然可以被處理。

範例

在以下範例中,我們將完整示範如何為資源配置授權。在這個範例中,我們想要保護 namespace-1 中的 Broker (broker),只允許來自位於不同命名空間 (namespace-2) 中的 PingSource (pingsource-2) 的請求。

Example Overview

首先,我們建立命名空間、Broker 和 PingSource。

apiVersion: v1
kind: Namespace
metadata:
  name: namespace-1
---
apiVersion: v1
kind: Namespace
metadata:
  name: namespace-2
---
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: broker
  namespace: namespace-1
---
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
  name: pingsource-1
  namespace: namespace-1
spec:
  data: '{"message": "Hi from pingsource-1 from namespace-1"}'
  schedule: '*/1 * * * *'
  sink:
    ref:
      apiVersion: eventing.knative.dev/v1
      kind: Broker
      name: broker
      namespace: namespace-1
---
apiVersion: sources.knative.dev/v1
kind: PingSource
metadata:
  name: pingsource-2
  namespace: namespace-2
spec:
  data: '{"message": "Hi from pingsource-2 from namespace-2"}'
  schedule: '*/1 * * * *'
  sink:
    ref:
      apiVersion: eventing.knative.dev/v1
      kind: Broker
      name: broker
      namespace: namespace-1

為了進行偵錯,我們還建立了一個 event-display Kservice 和 Trigger。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: event-display
  namespace: namespace-1
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/min-scale: "1"
    spec:
      containers:
      - image: gcr.io/knative-releases/knative.dev/eventing/cmd/event_display
---
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: trigger
  namespace: namespace-1
spec:
  broker: broker
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: event-display

只要 OIDC 停用且沒有 EventPolicy,我們應該會在 event-display kservice 中看到來自兩個 PingSource 的事件。

$ kubectl -n namespace-1 logs event-display-00001-deployment-56cd8dd644-64xl2
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-1/pingsources/pingsource-1
  id: 79d7a363-798d-40e2-b95c-6e007c81b05b
  time: 2024-08-28T11:33:00.168602384Z
Extensions,
  knativearrivaltime: 2024-08-28T11:33:00.194124454Z
Data,
  {"message": "Hi from pingsource-1 from namespace-1"}
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-2/pingsources/pingsource-2
  id: 94cfefc6-57aa-471c-9ce5-1d8c61370c7e
  time: 2024-08-28T11:33:00.287533878Z
Extensions,
  knativearrivaltime: 2024-08-28T11:33:00.296630315Z
Data,
  {"message": "Hi from pingsource-2 from namespace-2"}

現在啟用 OIDC。

$ kubectl -n knative-eventing patch cm config-features --type merge --patch '{"data":{"authentication-oidc":"enabled"}}'

並建立以下 EventPolicy。

apiVersion: eventing.knative.dev/v1alpha1
kind: EventPolicy
metadata:
  name: event-policy
  namespace: namespace-1
spec:
  to:
    - ref:
        apiVersion: eventing.knative.dev/v1
        kind: Broker
        name: broker
  from:
    - ref:
        apiVersion: sources.knative.dev/v1
        kind: PingSource
        name: pingsource-2
        namespace: namespace-2

之後,您可以在 Broker 的狀態中看到此 EventPolicy 已應用於該 Broker。

$ kubectl -n namespace-1 get broker broker -o yaml                                                                      
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: broker
  namespace: namespace-1
  ...
spec:
  ...
status:
  ...
  conditions:
  ...
  - lastTransitionTime: "2024-08-28T11:53:48Z"
    status: "True"
    type: EventPoliciesReady
  - lastTransitionTime: "2024-08-28T11:26:16Z"
    status: "True"
    type: Ready

  policies:
  - apiVersion: eventing.knative.dev/v1alpha1
    name: event-policy

而在 event-display 中,您應該只會看到來自 pingsource-2 的事件,因為我們在 EventPolicy event-policy 中引用了這個來源,允許它向 Broker broker 發送事件。

$ kubectl -n namespace-1 logs event-display-00001-deployment-56cd8dd644-64xl2
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-2/pingsources/pingsource-2
  id: c0b4f5f2-5f95-4c0b-a3c6-6f61b6581a4b
  time: 2024-08-28T11:56:00.200782358Z
Extensions,
  knativearrivaltime: 2024-08-28T11:56:00.20834826Z
Data,
  {"message": "Hi from pingsource-2 from namespace-2"}
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-2/pingsources/pingsource-2
  id: 6ab79fb0-2cf6-42a0-a43e-6bcd172558e5
  time: 2024-08-28T11:57:00.075390777Z
Extensions,
  knativearrivaltime: 2024-08-28T11:57:00.096497595Z
Data,
  {"message": "Hi from pingsource-2 from namespace-2"}

當我們現在再次移除 EventPolicy 並保持 OIDC 停用時,Broker 將會回退到預設的授權模式,即 allow-same-namespace

$ kubectl -n namespace-1 delete eventpolicy event-policy

這也應該反映在 Broker 的狀態中。

$ kubectl -n namespace-1 get broker broker -o yaml           
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
  name: broker
  namespace: namespace-1
  ...
spec:
  ...
status:
  ...
  conditions:
  ...
  - lastTransitionTime: "2024-08-28T12:00:00Z"
    message: Default authz mode is "Allow-Same-Namespace
    reason: DefaultAuthorizationMode
    status: "True"
    type: EventPoliciesReady

  - lastTransitionTime: "2024-08-28T11:26:16Z"
    status: "True"
    type: Ready

我們應該只在 event-display 中看到來自 pingsource-1 的事件,因為 pingsource-1broker 位於相同的命名空間中。

$ kubectl -n namespace-1 logs event-display-00001-deployment-56cd8dd644-64xl2
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-1/pingsources/pingsource-1
  id: cd173aef-373a-4f2b-915e-43c138ac0602
  time: 2024-08-28T12:01:00.2504715Z
Extensions,
  knativearrivaltime: 2024-08-28T12:01:00.276151088Z
Data,
  {"message": "Hi from pingsource-1 from namespace-1"}
☁️  cloudevents.Event
Context Attributes,
  specversion: 1.0
  type: dev.knative.sources.ping
  source: /apis/v1/namespaces/namespace-1/pingsources/pingsource-1
  id: 22665003-fe81-4203-8896-89594077ae6b
  time: 2024-08-28T12:02:00.121025501Z
Extensions,
  knativearrivaltime: 2024-08-28T12:02:00.13378992Z
Data,
  {"message": "Hi from pingsource-1 from namespace-1"}

摘要

Knative Eventing 中的 EventPolicy 資源提供了一種強大的方式來安全地控制事件傳遞。透過定義哪些來源可以向特定的消費者發送事件,使用者可以確保只有經過授權的實體在其事件驅動架構中進行互動。

我們使用分析和 Cookie 來了解網站流量。您使用我們網站的相關資訊會為了此目的與 Google 分享。了解更多。