Skip to content

feat(proxy): allow SSE support for proxy#168

Closed
adilsitos wants to merge 9 commits intomainfrom
adilsitos/feat/ENG-4525
Closed

feat(proxy): allow SSE support for proxy#168
adilsitos wants to merge 9 commits intomainfrom
adilsitos/feat/ENG-4525

Conversation

@adilsitos
Copy link
Copy Markdown

Description 📣

Allow support to update secrets using SSE (server sent events)

Type ✨

  • Bug fix
  • New feature
  • Improvement
  • Breaking change
  • Documentation

Tests 🛠️

  • Created a new secret management project
  • Create a universal identity machine policy
  • Start the proxy pointing to the server (default port is 8080)
  • Create some secrets using the interface
  • Try to fetch using the API (check the bash code below)
  • Update the secret using the interface
  • Check the SSE connection was opened (check the logs)
  • Try to fetch it again (using the API)
  • Check the request was cached.
curl --location 'http://localhost:8081/api/v4/secrets/test?type=shared&projectId=66b56e25-7db3-49c3-8014-f96407852d54&environment=prod' \
--header 'Authorization: Bearer tokwn'

@adilsitos adilsitos force-pushed the adilsitos/feat/ENG-4525 branch from aef3f54 to b8c534a Compare March 31, 2026 22:10
@linear
Copy link
Copy Markdown

linear bot commented Mar 31, 2026

@adilsitos adilsitos force-pushed the adilsitos/feat/ENG-4525 branch 3 times, most recently from a015759 to 10a2ab1 Compare March 31, 2026 22:14
devin-ai-integration bot and others added 9 commits March 31, 2026 19:14
…us events

Co-Authored-By: arsh <arshsb1998@gmail.com>
…login event capture

Co-Authored-By: arsh <arshsb1998@gmail.com>
…/Alias events are flushed

Co-Authored-By: arsh <arshsb1998@gmail.com>
Previously, GetDistinctId returned errors from machineid.ID() even when
a valid email-based distinctId was available from the config file. This
caused CaptureEvent to early-return and never flush enqueued Identify/
Alias events. Now non-critical errors are logged at debug level and only
a missing distinctId produces an error.

Co-Authored-By: arsh <arshsb1998@gmail.com>
@adilsitos adilsitos force-pushed the adilsitos/feat/ENG-4525 branch from 10a2ab1 to ba3ab79 Compare March 31, 2026 22:15
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 31, 2026

Greptile Summary

This PR adds two distinct features: (1) SSE-based cache invalidation for the proxy — when --use-sse is enabled, the proxy subscribes to Infisical's project event stream and proactively purges/refetches secrets on mutations instead of relying on the static polling loop; and (2) Web Application (RRWeb) PAM session recording — a new webapp resource type that records browser session replays through a length-prefixed TCP tunnel via the gateway.

The core logic of both features is well-structured, but the PR has several issues that need to be resolved before merging:

  • Encrypted session binary files committed — two session/*.enc test artifacts were accidentally committed and must be removed (and session/ added to .gitignore).
  • Developer-local .claude/settings.json committed — contains hardcoded absolute paths to the author's machine; should be removed and .claude/ added to .gitignore.
  • Debug log left in productionlog.Info().Str(\"event\", ...).Msg(\"DEBUG\") in sse.go logs full event data on every SSE event at info level.
  • getSecretByName creates request without context — the refetch HTTP request in sse.go is not bound to the parent context, which can cause goroutine leaks on shutdown.
  • --client-secret CLI flag — exposes the machine identity secret in shell history and process listings; accepting it via an environment variable would be safer.
  • Commented-out dead code — 80+ lines of commented-out pamWebAppCmd code in pam.go should be removed or tracked as an issue.
  • Regex recompiled per call — the ParseSessionFilename regex should be a package-level variable and validated for ReDoS.

Confidence Score: 2/5

Not safe to merge — encrypted session binaries and a developer-local config file were accidentally committed, and there is a debug log and a context-less HTTP request in the SSE implementation.

Two P0/P1 file inclusion issues (committed session binaries and local settings.json) must be resolved before merge. The debug log and missing context on the refetch request are correctness/reliability issues that also block production readiness. The remaining findings are P2 style/security hygiene items.

session/*.enc (must be removed), .claude/settings.json (must be removed), packages/proxy/sse.go (debug log at line 403, context-less request at line 566)

Important Files Changed

Filename Overview
packages/proxy/sse.go New SSE manager for demand-driven cache invalidation; contains a debug log in production, context-less HTTP request in getSecretByName, and raw event data logged on parse errors.
session/pam_session_59b5e4ba-7b19-46e5-b23f-9dd02ada6182_webapp_expires_1773714945.enc Encrypted PAM session recording binary accidentally committed; must be removed and the session/ directory added to .gitignore.
session/pam_session_721370b7-0906-4671-a2f8-aca51f73f6aa_webapp_expires_1773715668.enc Encrypted PAM session recording binary accidentally committed; must be removed and the session/ directory added to .gitignore.
.claude/settings.json Developer-local Claude config with hardcoded absolute paths to the author's machine; should not be committed to the repository.
packages/cmd/proxy.go Adds --use-sse, --client-id, and --client-secret flags; client secret exposed via CLI flag is a security concern.
packages/proxy/cache.go Adds ExtractSecretNameFromPath, GenerateSSECacheKey, and NewSSESecretCacheFunc; logic looks correct and well-structured.
packages/proxy/resync.go Adds sseEnabled parameter to StartBackgroundLoops to conditionally disable static refresh; clean and correct implementation.
packages/pam/session/uploader.go Adds webapp resource type, RRWeb event upload support, and fixes copy/paste error messages; regex is recompiled on every call.
packages/pam/handlers/webapplication/webapplication.go New handler for RRWeb session recording over a length-prefixed TCP connection; enforces a 10 MB frame size limit, logic looks correct.
packages/cmd/pam.go Adds 80+ lines of commented-out pamWebAppCmd dead code that should be removed or tracked as an issue.
packages/gateway-v2/gateway.go Adds ForwardModePAMRRWebEvents mode and infisical-pam-rrweb-events ALPN protocol; straightforward extension of existing pattern.
packages/pam/session/logger.go Adds RRWebEvent type and LogRRWebEvent method to SessionLogger interface; clean and consistent with existing patterns.
packages/api/model.go Adds UploadRRWebEvent struct for API upload; straightforward and correct.

Comments Outside Diff (5)

  1. session/pam_session_59b5e4ba-7b19-46e5-b23f-9dd02ada6182_webapp_expires_1773714945.enc, line 1 (link)

    P0 Encrypted session recording files committed to the repository

    Two binary PAM session recording .enc files have been accidentally committed to the repo. These are real encrypted session recording artifacts generated while testing the feature. Even though they are encrypted, they should never be committed — they contain session data that could expose information about internal systems or projects used during testing.

    These files need to be removed from the PR and purged from git history. The session/ directory should also be added to .gitignore to prevent future accidental commits.

  2. .claude/settings.json, line 1-14 (link)

    P1 Developer-local config file committed to the repository

    This file hardcodes absolute paths specific to the author's machine (/Users/adilsitos/Documents/infisical/cli/...). It is a developer convenience artifact that should not be part of the repository. It will cause .claude/settings.json to appear as a tracked file in every other contributor's workspace.

    Please remove this file and add .claude/ to .gitignore.

  3. packages/cmd/proxy.go, line 293 (link)

    P1 Machine identity client secret passed as a CLI flag

    The --client-secret flag exposes the machine identity credential in plaintext in several insecure locations:

    1. Shell history~/.bash_history, ~/.zsh_history, etc.
    2. Process listingsps aux output on the same host is visible to all users.
    3. CI/CD logs — any logging framework that records the full argv will capture it.

    Consider accepting the secret via an environment variable (e.g. INFISICAL_SSE_CLIENT_SECRET) instead of, or in addition to, the flag. This is the standard pattern used by most secret-sensitive CLIs.

  4. packages/pam/session/uploader.go, line 59-61 (link)

    P2 Regex recompiled on every ParseSessionFilename call

    regexp.MustCompile is called every time ParseSessionFilename is invoked (potentially very frequently in the upload routine). Since the pattern only depends on compile-time constants, it should be compiled once and stored as a package-level variable.

    Additionally, per project conventions, any new regex usage should be validated at https://devina.io/redos-checker. The (.+) group followed by a literal _ anchor and alternation could exhibit catastrophic backtracking on adversarially crafted filenames — worth verifying.

  5. packages/cmd/pam.go, line 332-413 (link)

    P2 Large block of commented-out code

    Over 80 lines of fully commented-out pamWebAppCmd / pamWebAppAccessCmd code have been added. Dead code like this adds noise and makes it harder to understand the intended surface area of the PR. If this is planned for a future PR, it should be tracked via an issue rather than living as commented-out code in the codebase.

Reviews (1): Last reviewed commit: "feat: change how sse message keys are be..." | Re-trigger Greptile

case <-ctx.Done():
return ctx.Err()
case event, ok := <-events:
log.Info().Str("event", fmt.Sprintf("%+v", event)).Msg("DEBUG")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Debug log left in production code

This "DEBUG" log message at Info level is clearly a development artifact that should be removed before merging. It logs every SSE event (including sensitive event metadata like project ID, environment, and secret key) to stdout at info severity on every single event received.

Suggested change
log.Info().Str("event", fmt.Sprintf("%+v", event)).Msg("DEBUG")
if !ok {

}
secretURL.RawQuery = query.Encode()

req, err := http.NewRequest(http.MethodGet, secretURL.String(), nil)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 HTTP request created without context

getSecretByName creates the request with http.NewRequest instead of http.NewRequestWithContext, meaning it will never be cancelled even when the parent SSE connection context is cancelled (e.g. on shutdown or when the connection is dropped). This request could hang indefinitely, leaking goroutines in error scenarios.

Suggested change
req, err := http.NewRequest(http.MethodGet, secretURL.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, secretURL.String(), nil)

Note: you'll need to pass ctx context.Context into getSecretByName and thread it through from refetchSecretsAfterSSEEvent.

Comment on lines +436 to +437
Str("rawData", currentData.String()).
Msg("Failed to parse SSE event data")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Raw SSE event data logged on parse failure

When JSON parsing of an SSE event fails, the raw data payload is logged at Error level via Str("rawData", currentData.String()). Since SSE event data can include secret values or sensitive metadata, logging the entire raw body risks leaking secrets into log aggregation systems (e.g. Datadog, CloudWatch).

Consider logging only the length or a truncated/redacted version instead.

@adilsitos adilsitos closed this Mar 31, 2026
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.

1 participant