Skip to content

Commit 602fc04

Browse files
committed
fix: restore X-MaaS-Subscription header for Istio Telemetry
Keep X-MaaS-Subscription header injection for Istio Telemetry's per-subscription latency tracking. Other identity headers (Username, Group, Key-Id) remain removed for defense-in-depth. Istio Telemetry runs in Envoy and cannot access auth.identity context - it can only read request headers. The X-MaaS-Subscription header is server-controlled (injected by Authorino from validated subscription), not client-provided. Updates test to verify X-MaaS-Subscription is present while other identity headers remain absent.
1 parent 8f67bb6 commit 602fc04

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

maas-controller/pkg/controller/maas/maasauthpolicy_controller.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,21 @@ allow {
452452
// User identity, groups, and key IDs are not forwarded to upstream model workloads
453453
// to prevent accidental disclosure in logs or dumps. All identity information remains
454454
// available to TRLP and telemetry via auth.identity and filters.identity below.
455+
// Exception: X-MaaS-Subscription is injected for Istio Telemetry (per-subscription latency tracking).
455456
rule["response"] = map[string]interface{}{
456457
"success": map[string]interface{}{
458+
"headers": map[string]interface{}{
459+
// X-MaaS-Subscription required for Istio Telemetry metrics (per-subscription latency)
460+
// Other identity headers (Username, Group, Key-Id) intentionally omitted to prevent
461+
// disclosure in model workload logs. This is server-controlled (not client-provided).
462+
"X-MaaS-Subscription": map[string]interface{}{
463+
"plain": map[string]interface{}{
464+
"expression": `has(auth.metadata["subscription-info"].name) ? auth.metadata["subscription-info"].name : ""`,
465+
},
466+
"metrics": false,
467+
"priority": int64(0),
468+
},
469+
},
457470
"filters": map[string]interface{}{
458471
"identity": map[string]interface{}{
459472
"json": map[string]interface{}{

maas-controller/pkg/controller/maas/maasauthpolicy_controller_test.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,8 +1063,9 @@ func TestMaaSAuthPolicyReconciler_CacheKeyModelIsolation(t *testing.T) {
10631063
}
10641064

10651065
// TestMaaSAuthPolicyReconciler_NoIdentityHeadersUpstream verifies that identity headers
1066-
// (X-MaaS-Username, X-MaaS-Group, X-MaaS-Key-Id, X-MaaS-Subscription) are NOT injected
1067-
// into requests forwarded to upstream model workloads (defense-in-depth).
1066+
// (X-MaaS-Username, X-MaaS-Group, X-MaaS-Key-Id) are NOT injected into requests forwarded
1067+
// to upstream model workloads (defense-in-depth). Exception: X-MaaS-Subscription IS injected
1068+
// for Istio Telemetry (per-subscription latency tracking).
10681069
// All identity information remains available to TRLP and telemetry via filters.identity.
10691070
func TestMaaSAuthPolicyReconciler_NoIdentityHeadersUpstream(t *testing.T) {
10701071
const (
@@ -1105,21 +1106,27 @@ func TestMaaSAuthPolicyReconciler_NoIdentityHeadersUpstream(t *testing.T) {
11051106
t.Fatalf("Get AuthPolicy %q: %v", authPolicyName, err)
11061107
}
11071108

1108-
// Test 1: Verify response.success.headers does NOT exist (identity headers not forwarded upstream)
1109+
// Test 1: Verify identity headers (except X-MaaS-Subscription) are not forwarded upstream
11091110
t.Run("identity headers not forwarded to upstream", func(t *testing.T) {
11101111
headers, found, err := unstructured.NestedMap(got.Object, "spec", "rules", "response", "success", "headers")
11111112
if err != nil {
11121113
t.Fatalf("Error checking headers: %v", err)
11131114
}
11141115

1115-
// Headers should either not exist or be empty
1116-
if found && len(headers) > 0 {
1117-
// Check that identity headers specifically are not present
1118-
forbiddenHeaders := []string{"X-MaaS-Username", "X-MaaS-Group", "X-MaaS-Key-Id", "X-MaaS-Subscription"}
1119-
for _, header := range forbiddenHeaders {
1120-
if _, exists := headers[header]; exists {
1121-
t.Errorf("Identity header %q should NOT be forwarded to upstream workloads (defense-in-depth)", header)
1122-
}
1116+
if !found {
1117+
t.Fatalf("response.success.headers should exist (X-MaaS-Subscription for Istio)")
1118+
}
1119+
1120+
// Verify X-MaaS-Subscription IS present (required for Istio Telemetry)
1121+
if _, exists := headers["X-MaaS-Subscription"]; !exists {
1122+
t.Errorf("X-MaaS-Subscription header should be present for Istio Telemetry")
1123+
}
1124+
1125+
// Verify identity headers are NOT present (defense-in-depth)
1126+
forbiddenHeaders := []string{"X-MaaS-Username", "X-MaaS-Group", "X-MaaS-Key-Id"}
1127+
for _, header := range forbiddenHeaders {
1128+
if _, exists := headers[header]; exists {
1129+
t.Errorf("Identity header %q should NOT be forwarded to upstream workloads (defense-in-depth)", header)
11231130
}
11241131
}
11251132
})

0 commit comments

Comments
 (0)