Knative 事件授權¶
追蹤問題:#7256
概述¶
保護 Knative 事件處理中的事件傳遞對於防止未經授權的存取至關重要。為了對事件傳遞強制執行細粒度的控制,Knative 事件處理引入了 EventPolicy
自訂資源,允許使用者指定哪些實體被授權將事件發送到命名空間中的特定消費者。
先決條件¶
- 事件處理安裝
- 啟用
authentication-oidc
功能。
注意
如 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
的範圍。
有兩種方法可以定義這些目標
to.ref
:- 定義:直接參考特定資源。
- 範例:在上面的
EventPolicy
中,直接參考my-broker
Broker。這表示EventPolicy
適用於此特定的Broker
。 - 使用案例:當您想要依名稱保護特定資源時,請使用
to.ref
。to: - ref: apiVersion: eventing.knative.dev/v1 kind: Broker name: my-broker
-
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
中定義的目標。有兩種方法可以定義這些來源
-
from.ref
:- 定義:直接參考特定的事件來源資源。
- 範例:參考
another-namespace
中的my-source
PingSource
,表示此特定來源被允許發送事件。 - 使用案例:當您想要授權特定事件來源時,請使用
from.ref
。from: - ref: apiVersion: sources.knative.dev/v1 kind: PingSource name: my-source namespace: another-namespace
-
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
) 的請求。
首先,我們建立命名空間、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-1
與 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-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
資源提供了一種強大的方式來安全地控制事件傳遞。透過定義哪些來源可以向特定的消費者發送事件,使用者可以確保只有經過授權的實體在其事件驅動架構中進行互動。