Skip to content

feat: configurable HTTP header forwarding to ClickHouse#63

Open
isushkov-akamai wants to merge 3 commits intoAltinity:mainfrom
isushkov-akamai:feature/forward-http-headers-to-ch
Open

feat: configurable HTTP header forwarding to ClickHouse#63
isushkov-akamai wants to merge 3 commits intoAltinity:mainfrom
isushkov-akamai:feature/forward-http-headers-to-ch

Conversation

@isushkov-akamai
Copy link

@isushkov-akamai isushkov-akamai commented Mar 17, 2026

Summary

Adds configurable forwarding of incoming HTTP headers from MCP requests to ClickHouse.
This enables getClientHTTPHeader() in ClickHouse row policies and INVOKER views for
multi-tenant Row-Level Security without per-tenant ClickHouse users.

  • New --forward-http-headers CLI flag / FORWARD_HTTP_HEADERS env var / config file option
  • Supports exact header names (X-Tenant-Id) and trailing wildcards (X-*)
  • Default: empty (no headers forwarded) — opt-in for security
  • Covers all transport paths: OpenAPI, MCP JSON-RPC (HTTP + SSE), dynamic tools
  • STDIO transport unaffected (no HTTP headers available)

Security

  • Opt-in: default is empty — no headers forwarded unless explicitly configured
  • No values logged: debug log shows only header names, never values

@isushkov-akamai isushkov-akamai force-pushed the feature/forward-http-headers-to-ch branch from 8184b6f to f20192a Compare March 17, 2026 17:35
@isushkov-akamai isushkov-akamai marked this pull request as draft March 17, 2026 17:41
@isushkov-akamai isushkov-akamai force-pushed the feature/forward-http-headers-to-ch branch from f20192a to 4efb86a Compare March 17, 2026 17:54
@isushkov-akamai isushkov-akamai marked this pull request as ready for review March 17, 2026 18:26
Copy link
Collaborator

@Slach Slach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review

Good feature, clean approach via context. A few observations:

1. cmd/altinity-mcp/main.go:240-245 — Spaces instead of tabs

The new forward-http-headers flag uses spaces for indentation while the rest of the file uses tabs. Should be consistent.

2. cmd/altinity-mcp/main.go:1003-1006 — Dead code (DefaultForwardHTTPHeaders)

if len(cfg.Server.ForwardHTTPHeaders) == 0 && !cmd.IsSet("forward-http-headers") {
    cfg.Server.ForwardHTTPHeaders = altinitymcp.DefaultForwardHTTPHeaders
}

DefaultForwardHTTPHeaders is declared as var DefaultForwardHTTPHeaders []string — which is nil. This block assigns nil to an already empty slice. It's a no-op, should be removed.

3. pkg/server/server.go"sort" import not in alphabetical order

sort is placed after strconv, should go before it.

4. PR description vs code: "Pattern validation: rejects invalid patterns" — but no validation exists

The PR description states: "Pattern validation: rejects invalid patterns (*Foo, X-*Z)", but there is no pattern validation at config load time. matchesAnyPattern simply won't match such patterns, but the user gets no error on misconfiguration. Either add validation with an error at startup, or remove this claim from the description.

5. PR description vs code: "Immutable context: headers are cloned on store and retrieve" — no clone on retrieve

ForwardedHeadersFromContext returns the map directly without copying. If a caller mutates the map, it affects all subsequent calls. Either clone on retrieve or remove this claim from the description.

6. pkg/server/server.go — Pattern "*" forwards all headers including Authorization and Cookie

Pattern * matches everything (since strings.HasPrefix(anything, "") is always true). This could unintentionally leak sensitive headers to ClickHouse. Consider either adding a blocklist (Authorization, Cookie, Host) or at least emitting a log.Warn when * is configured.

7. No test for CORSAllowHeaders

The CORSAllowHeaders function has no test coverage, and it contains non-trivial wildcard → * logic.

8. No test for GetClickHouseClientWithHeaders

The core function of this PR — merging extraHeaders into chConfig.HttpHeaders — is not tested.

@Slach
Copy link
Collaborator

Slach commented Mar 18, 2026

could you resolve conflicts?

@isushkov-akamai isushkov-akamai force-pushed the feature/forward-http-headers-to-ch branch from 4efb86a to 453c350 Compare March 18, 2026 18:42
@isushkov-akamai
Copy link
Author

could you resolve conflicts?

done

@isushkov-akamai isushkov-akamai requested a review from Slach March 19, 2026 11:49
Copy link
Collaborator

@Slach Slach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо за исправления! Большинство замечаний закрыто. Осталось два нерешённых пункта — см. комментарии к коду.

@Slach
Copy link
Collaborator

Slach commented Mar 19, 2026

unit tests didn't pass

@Slach
Copy link
Collaborator

Slach commented Mar 19, 2026

    server_test.go:2071: 
        	Error Trace:	/home/runner/work/altinity-mcp/altinity-mcp/pkg/server/server_test.go:2071
        	Error:      	Received unexpected error:
        	            	failed to create ClickHouse client from JWE: failed to connect to ClickHouse: connection ping failed: failed to query server hello: failed to query server hello info: sendQuery: Post "http://default@localhost:8123?client_protocol_version=54460&database=default&default_format=Native&max_execution_time=14": dial tcp [::1]:8123: connect: connection refused
        	Test:       	TestGetClickHouseClientWithHeaders_MergesExtraHeaders

use
go test -run -v TestGetClickHouseClientWithHeaders_MergesExtraHeaders ./... to figure out

@isushkov-akamai isushkov-akamai requested a review from Slach March 20, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants