Skip to content

Commit 5265085

Browse files
Enforce authorization on log rules endpoint based on labels from matcher (observatorium#824)
1 parent ebbaf26 commit 5265085

2 files changed

Lines changed: 10 additions & 37 deletions

File tree

api/logs/v1/rules_labels_enforcer.go

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,17 @@ import (
1515

1616
const labelsParam = "labels"
1717

18-
// WithEnforceRulesLabelFilters returns a middleware that enforces that every query
19-
// parameter has a matching matcher returned by authorization endpoint.
20-
func WithEnforceRulesLabelFilters(labelKeys map[string][]string) func(http.Handler) http.Handler {
18+
// WithEnforceRulesAuthorizationLabels returns a middleware that enforces that every query
19+
// matcher returned by authorization endpoint has a matching URL parameter.
20+
func WithEnforceRulesAuthorizationLabels() func(http.Handler) http.Handler {
2121
return func(next http.Handler) http.Handler {
2222
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
23-
tenant, ok := authentication.GetTenant(r.Context())
24-
if !ok {
25-
httperr.PrometheusAPIError(w, "missing tenant id", http.StatusBadRequest)
26-
27-
return
28-
}
29-
30-
keys, ok := labelKeys[tenant]
31-
if !ok || len(keys) == 0 {
32-
next.ServeHTTP(w, r)
33-
34-
return
35-
}
36-
3723
data, ok := authorization.GetData(r.Context())
3824
if !ok {
3925
httperr.PrometheusAPIError(w, "error finding authorization label matcher", http.StatusInternalServerError)
4026

4127
return
4228
}
43-
4429
// Early pass to the next if no authz label enforcement configured.
4530
if data == "" {
4631
next.ServeHTTP(w, r)
@@ -65,26 +50,14 @@ func WithEnforceRulesLabelFilters(labelKeys map[string][]string) func(http.Handl
6550
// If the authorization endpoint provides any matchers, ensure that the URL parameter value
6651
// matches an authorization matcher with the same URL parameter key.
6752
queryParams := r.URL.Query()
68-
for _, key := range keys {
69-
var (
70-
val = queryParams.Get(key)
71-
matched = false
72-
)
73-
74-
for _, matcher := range matchers {
75-
if matcher == nil {
76-
continue
77-
}
78-
79-
if matcher.Name == key && matcher.Matches(val) {
80-
matched = true
81-
break
82-
}
53+
for _, matcher := range matchers {
54+
if matcher == nil {
55+
continue
8356
}
57+
val := queryParams.Get(matcher.Name)
8458

85-
if !matched {
86-
httperr.PrometheusAPIError(w, fmt.Sprintf("unauthorized access for URL parameter %q and value %q", key, val), http.StatusForbidden)
87-
59+
if !matcher.Matches(val) {
60+
httperr.PrometheusAPIError(w, fmt.Sprintf("unauthorized access for URL parameter %q and value %q", matcher.Name, val), http.StatusForbidden)
8861
return
8962
}
9063
}

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ func main() {
750750
logsv1.WithWriteMiddleware(authorization.WithAuthorizers(authorizers, rbac.Write, "logs")),
751751
logsv1.WithRulesLabelFilters(cfg.logs.rulesLabelFilters),
752752
logsv1.WithRulesReadMiddleware(logsv1.WithEnforceTenantAsRuleNamespace()),
753-
logsv1.WithRulesReadMiddleware(logsv1.WithEnforceRulesLabelFilters(cfg.logs.rulesLabelFilters)),
753+
logsv1.WithRulesReadMiddleware(logsv1.WithEnforceRulesAuthorizationLabels()),
754754
logsv1.WithRulesReadMiddleware(logsv1.WithParametersAsLabelsFilterRules(cfg.logs.rulesLabelFilters)),
755755
logsv1.WithRulesWriteMiddleware(logsv1.WithEnforceTenantAsRuleNamespace()),
756756
logsv1.WithRulesWriteMiddleware(logsv1.WithEnforceRuleLabels(cfg.logs.tenantLabel)),

0 commit comments

Comments
 (0)