OpenFn / OpenFn/apollo

Job code reaches Sentry by three routes that include_local_variables does not cover

Open
#654 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Jupyter Notebook
Stars
5
Forks
10
Avg merge
2d 20h
Merged PRs (30d)
17

Description

Job code and workflow YAML can reach Sentry, and two of the routes also reach the client over SSE. All of this predates #446; the branch for that issue closes the frame-locals route and nothing else, so I am splitting the rest out rather than growing that PR further.

The frame-locals route is closed on the #446 branch by setting include_local_variables=False in services/entry.py. That one covers stack frames, including the __cause__/__context__ chain, so a handler that re-raises no longer ships the original frame. What it does not cover is anything explicitly attached to an event or logged as text.

Three routes remain. The first is sentry_sdk.set_context("request_data", ...) at services/workflow_chat/workflow_chat.py:1104 and services/job_chat/job_chat.py:748. The payload goes in whole, mask_secrets matches key-shaped values and has no notion of job code, and the context sits on the isolation scope, so one chat request attaches its workflow to every later event in that process. The second is code_edit_context.llm_edit_answer at services/job_chat/job_chat.py:612, which is the model's code answer. The third is LoggingIntegration, which is a default integration that auto_enabling_integrations=False does not switch off, so it picks up the full-prompt log at services/job_chat/prompt.py:536. The set_context and logging routes also reach the caller, because the bridge forwards matching log lines as SSE events (platform/src/bridge.ts:18).

Worth saying out loud in the same place: when a user opts into Langfuse, only the three main() functions pass capture_input=False, so every inner @observe span ships job bodies. That is consent rather than a leak, but nobody reading the code today would know it works that way.

I want to fix these together rather than piecemeal, because the pattern is the same each time and we have now declared this closed six times on the #446 branch alone. The shape of the fix is a single scrubber that knows what job code looks like, applied at before_send rather than at each call site, plus dropping the payload from set_context entirely and logging a digest instead of a prompt.

I will pick this up after #446 merges. Flagging it now so it does not get lost in that review thread.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read services/workflow_chat/workflow_chat.py:1104, services/job_chat/job_chat.py:612 and :748, services/job_chat/prompt.py:536, services/entry.py, and platform/src/bridge.ts; account for the #446 branch before changing shared behavior. Done means the three remaining routes no longer expose job code through Sentry or SSE, context carries no payload, logging uses a digest, and the stated Langfuse consent behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript
Domain
api, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.