HarperFast / HarperFast/studio

[RUM] Secrets operation failures publish Harper's composed error text to Error Tracking

Open
#1,664 0 comments 0 reactions 0 assignees View on GitHub
rum
Dominant language
TypeScript
Stars
5
Forks
4
Avg merge
1d 8h
Merged PRs (30d)
40

Description

`operationErrorMessage` in [`src/integrations/api/instance/secrets/secrets.ts:58`](https://github.com/HarperFast/studio/blob/stage/src/integrations/api/instance/secrets/secrets.ts#L58) lifts Harper's response-body text into a `new Error(...)`:

```ts
function operationErrorMessage(error: unknown): string {
const body = (error as { response?: { data?: { error?: string; message?: string } } })?.response?.data;
return body?.error ?? body?.message ?? String(error);
}
```

Three call sites throw it (`createSecret`, `updateSecret`, `deleteSecret`). Those rejections reach React Query's global handler, which calls `console.error`, and the RUM SDK reports a `console.error` as an error event — so whatever Harper composed for a failed secrets operation is published to Datadog Error Tracking, where it is retained and searchable.

## Why the existing redaction doesn't cover it

`beforeSend` redacts URL- and scp-shaped tokens out of error text, and (as of the fix referenced below) withholds the message of a **relayed** error entirely. That withholding keys on `error.type`, which RUM takes from the thrown value's `name`. These are plain `new Error(...)`, so they arrive as `type: "Error"` and fall outside the rule.

Harper composes those operation errors by interpolation, the same way it composes the deploy failures where this class was first found — so the text can carry a name, path, or identifier the customer supplied, in whatever shape they supplied it. Free text with spaces is not URL-shaped and no bounded redaction rule spans it.

## Suggested direction

Give the relay a type the filter can see, rather than adding another message-shape rule: throw a named error class (mirroring `SSEOperationError`) from `operationErrorMessage`'s call sites and add it to `RELAYED_ERROR_TYPES`. That reuses the mechanism already in place and keeps the "is this text ours?" decision at the throw site, where it is known.

## Scale

Zero events in the last 7 days of production RUM — the path fires only when a secrets operation fails. It is filed as a latent exposure found while fixing the same class on the deploy path, not as an active leak.

## Related

- Fixed on the SSE deploy path by the PR linked below.
- Found by the cross-model pre-push review of that PR, which flagged it as a pre-existing sibling outside the diff.

Contributor guide

Open the contributing guide

Research direction

Start at src/integrations/api/instance/secrets/secrets.ts:58 and trace the createSecret, updateSecret, and deleteSecret call sites into the RUM beforeSend filtering and RELAYED_ERROR_TYPES configuration. Compare the existing SSEOperationError handling, then verify that failed secrets-operation text is classified as relayed and no longer published as an error event.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
observability-sre, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.