Skip to content

feat(config): session correlation header injection configuration#197

Merged
SasSwart merged 10 commits into
mainfrom
sasswart/feat-config-session-correlation-header-injection
May 7, 2026
Merged

feat(config): session correlation header injection configuration#197
SasSwart merged 10 commits into
mainfrom
sasswart/feat-config-session-correlation-header-injection

Conversation

@SasSwart
Copy link
Copy Markdown
Contributor

@SasSwart SasSwart commented Apr 30, 2026

PR Map

  1. feat(audit): session ID generation, sequence counter, and BoundaryLog wiring #196
  2. 👉🏼 feat(config): session correlation header injection configuration #197
  3. feat(proxy): inject session ID and sequence number headers on matching requests #198

RFC: Bridge ↔ Boundaries Correlation

Add YAML and CLI configuration surface for session correlation header injection per FR 2 of the RFC.

Depends on #196.

Changes

  • config/session_correlation.go: New file. Defines SessionCorrelationConfig, InjectTarget, ParseInjectTarget (with duplicate-key detection), ValidateSessionCorrelation, fixed header name constants (SessionIDHeaderName, SequenceNumberHeaderName), and DefaultInjectTargetFromEnv — a helper that derives a default inject target from CODER_AGENT_URL when no explicit targets are configured.
  • config/session_correlation_test.go: New file. Table-driven tests for ParseInjectTarget (including duplicate-key rejection), ValidateSessionCorrelation, the end-to-end NewAppConfigFromCliConfig session correlation path (with controlled environ), DefaultInjectTargetFromEnv, CLI+YAML target merging (TestBuildSessionCorrelation_TargetMerge), and the CODER_AGENT_URL fallback path (TestBuildSessionCorrelation_AgentURLFallback).
  • config/config.go: Wire session correlation fields into CliConfig (three new fields for serpent bindings: SessionCorrelationEnabled, InjectSessionIDTarget, InjectSessionIDTargets) and AppConfig (new SessionCorrelation field). NewAppConfigFromCliConfig now accepts an environ []string parameter so the CODER_AGENT_URL fallback is testable without relying on the host environment. Add buildSessionCorrelation helper that merges YAML+CLI inject targets, falls back to a target derived from CODER_AGENT_URL when none are configured and session correlation is enabled, and validates the result.
  • cli/cli.go: Register three new serpent options, pass os.Environ() to NewAppConfigFromCliConfig, and add usage examples including a zero-config workspace example.

New CLI flags

Flag Env YAML Default Description
--enable-session-correlation BOUNDARY_SESSION_CORRELATION_ENABLED session_correlation_enabled false Toggle; when enabled with no explicit targets, the inject target is auto-derived from CODER_AGENT_URL (set automatically in Coder workspaces)
--session-id-inject-target BOUNDARY_SESSION_ID_INJECT_TARGET Repeatable inject target (one target per flag invocation; env accepts one value; use YAML for multiple). Format: domain=<host> [path=<glob>]
session_id_inject_targets YAML-only list of inject targets

Header names are fixed constants (X-Coder-Agent-Firewall-Session-Id, X-Coder-Agent-Firewall-Sequence-Number) matching what Coder AI Gateway expects — they are not user-configurable.

Config validation ensures that when correlation is enabled at least one inject target is present (either explicit or auto-derived from CODER_AGENT_URL). Parsing validates the domain=... path=... key-value format, rejects unknown keys, and rejects duplicate keys within a single target string.

This commit adds config and validation only; runtime injection is wired in a follow-up PR.

Note

This PR was authored by Coder Agents.

Add YAML and CLI configuration surface for session correlation header
injection per the Bridge/Boundaries Correlation RFC (FR 2).

New configuration options:

- --enable-session-correlation / session_correlation_enabled: top-level
  toggle to disable injection entirely for deployments without AI Bridge
  in front.
- --inject-session-id-on / session_id_inject_targets (YAML): repeatable
  list of inject targets in "domain=<host> [path=<glob>]" format.
- --session-id-header-name / session_id_header_name: configurable header
  name (default X-Coder-Agent-Firewall-Session-Id).
- --sequence-number-header-name / sequence_number_header_name:
  configurable header name (default X-Coder-Agent-Firewall-Sequence-Number).

Config validation ensures that when correlation is enabled at least one
inject target is present and header names are non-empty. Parsing
validates the domain=... path=... key-value format and rejects unknown
keys.

This commit adds config and validation only; runtime injection is wired
in a follow-up PR.
@SasSwart SasSwart force-pushed the sasswart/feat-config-session-correlation-header-injection branch from c08f291 to 3ea7428 Compare May 5, 2026 09:20
@SasSwart SasSwart self-assigned this May 5, 2026
@SasSwart SasSwart marked this pull request as ready for review May 5, 2026 10:36
Comment thread cli/cli.go
Comment thread cli/cli.go
Comment thread config/config.go Outdated
Comment thread config/config.go
Comment thread config/session_correlation.go
Comment thread config/session_correlation.go
Comment thread config/config.go Outdated
Comment thread config/session_correlation_test.go
SasSwart added 4 commits May 7, 2026 09:11
…variables

Enhance the NewAppConfigFromCliConfig function to include an additional parameter for environment variables, allowing for more flexible session correlation header injection based on the current environment. Update related tests to validate new functionality.
…ce validation

Updated the description for the session ID inject target flag to clarify usage and provide an example. Added validation in the ParseInjectTarget function to prevent duplicate keys for domain and path in the input. Expanded unit tests to cover cases of duplicate keys.
Implemented new tests to validate the merging behavior of session correlation targets from YAML and CLI configurations. The tests cover various scenarios, including individual sources, merged targets, and preservation of multiple entries from each source.
Copy link
Copy Markdown
Contributor Author

@SasSwart SasSwart left a comment

Choose a reason for hiding this comment

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

Most review feedback tended to. One tricky outstanding comment left.

Comment thread cli/cli.go
Comment thread cli/cli.go
Comment thread config/session_correlation.go
Comment thread config/config.go Outdated
Comment thread config/config.go Outdated
Comment thread config/session_correlation.go
Comment thread config/session_correlation.go
Comment thread config/session_correlation_test.go
Comment thread config/session_correlation.go
…rom configuration

Eliminated the session ID and sequence number header name fields from the CliConfig and SessionCorrelationConfig structures. Updated related functions and tests to reflect these changes, ensuring that session correlation validation and configuration remain intact without explicit header name settings.
@SasSwart SasSwart requested a review from ssncferreira May 7, 2026 11:43
Copy link
Copy Markdown

@ssncferreira ssncferreira left a comment

Choose a reason for hiding this comment

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

LGTM 👍 Thank you for addressing the comments!

Comment on lines +62 to +63
name: "duplicate domain key",
input: "domain=staging.coder.com domain=prod.coder.com",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nice 🤩

@SasSwart SasSwart merged commit df62d5b into main May 7, 2026
5 checks passed
@SasSwart SasSwart deleted the sasswart/feat-config-session-correlation-header-injection branch May 7, 2026 14:04
SasSwart added a commit that referenced this pull request May 7, 2026
…er agreement

Add integration tests that verify the core invariants of session
correlation across the proxy, auditor, and forwarded request headers
working together. These tests fill the gap identified during review
of the session correlation PR stack (#196, #197, #198) where unit
tests verified each component in isolation but did not verify them
in concert.

New test file: proxy/proxy_session_correlation_integration_test.go

Tests added:
- LLMRequestAuditAndHeadersAgree: audit sequence number matches
  the forwarded header value on inject-target requests.
- NonLLMRequestAuditedWithoutHeaders: allowed non-inject-target
  requests are audited but carry no correlation headers.
- DeniedRequestAuditedNeverForwarded: denied requests consume a
  sequence number but are never forwarded.
- MixedRequestsSequenceOrdering: interleaved LLM, non-LLM, and
  denied requests all advance the counter monotonically.
- SequenceGapRevealsAgenticLoop: gap between two LLM sequence
  numbers precisely equals intermediate tool-use requests.
- SpoofedHeadersOverwrittenWithCorrectSequence: client-supplied
  headers are replaced and the audit event still agrees.
- DisabledCorrelationNoHeadersNoPreallocatedSequence: disabled
  correlation means no headers and no pre-allocated sequence.
- ConcurrentRequestsUniqueSequenceNumbers: concurrent requests
  each get a unique, dense sequence number.
// InjectTarget represents a parsed target for session correlation header
// injection. Requests matching the domain (and optional path glob) will
// receive the session ID and sequence number headers.
type InjectTarget struct {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm a bit concerned that --session-id-inject-target(s) syntax similar but not identical to --allow syntax; and that parsing & matching logic isn't reused (see rulesengine pkg).

rulesengine pkg is well documented, so customers will probably rely on it; and it will be confusing that --session-id-inject-target(s) syntax different from it.

SasSwart added a commit that referenced this pull request May 14, 2026
…er agreement

Add integration tests that verify the core invariants of session
correlation across the proxy, auditor, and forwarded request headers
working together. These tests fill the gap identified during review
of the session correlation PR stack (#196, #197, #198) where unit
tests verified each component in isolation but did not verify them
in concert.

New test file: proxy/proxy_session_correlation_integration_test.go

Tests added:
- LLMRequestAuditAndHeadersAgree: audit sequence number matches
  the forwarded header value on inject-target requests.
- NonLLMRequestAuditedWithoutHeaders: allowed non-inject-target
  requests are audited but carry no correlation headers.
- DeniedRequestAuditedNeverForwarded: denied requests consume a
  sequence number but are never forwarded.
- MixedRequestsSequenceOrdering: interleaved LLM, non-LLM, and
  denied requests all advance the counter monotonically.
- SequenceGapRevealsAgenticLoop: gap between two LLM sequence
  numbers precisely equals intermediate tool-use requests.
- SpoofedHeadersOverwrittenWithCorrectSequence: client-supplied
  headers are replaced and the audit event still agrees.
- DisabledCorrelationNoHeadersNoPreallocatedSequence: disabled
  correlation means no headers and no pre-allocated sequence.
- ConcurrentRequestsUniqueSequenceNumbers: concurrent requests
  each get a unique, dense sequence number.
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.

3 participants