Secret Scrubber

Security and data handling

Where data goes, what is kept, and what has and has not been verified.

Evidence key. confirmed on a test site seen working on a test site. automated tests covered by automated tests only. in testing still being tested. No independent audit, penetration test or bug bounty exists yet.

Data flow

  1. A platform event (an issue update or a comment; a new attachment triggers an issue update about 2 seconds later) starts a trigger function. It lists the issue's attachments and queues {issue key, attachment id}. confirmed on a test site
  2. A queue worker downloads the attachment through the platform REST API, as the app, into function memory. confirmed on a test site
  3. The sanitizer runs in memory. automated tests
  4. With dry-run on (the default) nothing is changed and an audit row is written. automated tests
  5. With dry-run off and findings present, the app uploads sanitized_<name>, edits comments and the description, re-reads to verify, writes the audit row, then deletes the original. confirmed on a test site
  6. File content and matched values are never written to storage or logs. Only counts, rule ids and ids are. automated tests

No external network calls

Declared design

  • The manifest declares no external fetch backends, and a test fails if one is added. automated tests
  • There are no remotes and no custom UI. The admin UI uses the platform's own UI kit. automated tests
  • The app source has no analytics, telemetry or CDN calls. The log module is the only output channel and allows only named fields. automated tests
  • Third-party libraries that Forge bundles for the UI are listed in the project's dependency audit. automated tests

Not yet verified

The admin page's network requests have not been inspected in a browser, so the claim above rests on the manifest and the source, not on a traffic check. in testing

What is stored, where, for how long

DataWhereContentRetention
Audit logForge SQL, table audit_logTime, issue key, attachment id, file name (or its SHA-256 prefix if hashing is on), file type, status, redaction count, rule ids with counts, swap state, error code. No values. automated testsDefault 12 months, configurable 1 to 120. A daily job deletes older rows. automated tests
SettingsForge key-value storageDry-run, size limit, extensions, email mode, allowlists, cookie-name allowlist, retention. automated testsUntil changed or uninstall
HMAC secretForge key-value storage (secret)One random value per install, the key for redaction labels. automated testsUntil uninstall
Locks and swap progressForge key-value storage with expiryIds and phase names. automated testsLocks 15 minutes, swap state 3 days
Leak audit and backlog progressForge key-value storageCounters, issue keys, attachment ids, up to 200 failure records with error codes. automated testsReplaced by the next run. Cancel flags 7 days.
LogsForge logsIssue key, attachment id, counts, rule ids, status, error codes. automated testsPer platform

Attachment bytes and file contents exist only in function memory during one job. automated tests The vendor has no server and no copy of this data.

Redaction label design

Exposure window

The original is visible until the swap finishes

The original file is uploaded before the app can sanitize it. Until the swap completes, search or other indexing can see it. The app shortens this window. It cannot remove it. confirmed on a test site

Typically seconds; longer for large files or a slow site. No maximum is promised. Two different measurements exist, on a development site:

  • Whole swap, small files: 5.6 to 6.7 seconds (mean about 6.0 seconds; 5 uploads of a small .log), from the attachment's creation to the audit row. The audit row is written just before the original is deleted. confirmed on a test site
  • Start delay, earlier measurement: about 26 seconds from upload to the first job on a cold start, and about 11 seconds when warm. This measures when processing starts, not when the swap ends. confirmed on a test site

Not measured: large files, and the time until search can find the original.

Failure behavior

Deletion is permanent

Deleted originals cannot be restored. There is no undo. confirmed on a test site

Licensing

Scopes

The app requests three scopes. Each is the minimum for the function listed. automated tests

ScopeWhyEvidence
read:jira-workRead attachments and their content, descriptions and comments. Search issues for the Leak audit. List attachments for the permission check. Receive events.Download and description reads worked on a test site. confirmed on a test site
write:jira-workUpload the sanitized attachment. Edit comments and descriptions to repoint media. Delete the original.A full swap worked on a test site with only these scopes plus project permissions. confirmed on a test site
storage:appKey-value storage for settings, the HMAC secret, locks, swap progress, scan and backlog progress.Settings and locks worked on a test site. confirmed on a test site

Not requested: no manage:jira-configuration, no admin or impersonation scopes, no external fetch permission. Forge SQL is declared as a module and needs no scope. Licensing needs no scope. automated tests

Scopes are added only when a feature needs them. Each future scope change has to be justified in the project's decision log first.

Project permissions

The app acts as itself, the app user. In every project it should handle, the documentation lists these project permissions (not scopes):

In a service project the app user must also be able to see and edit internal comments. An internal comment was swapped and edited by the app on a test site, and it stayed internal. confirmed on a test site

A missing permission has not been reproduced

On the test site, removing one grant from "Delete all attachments" did not stop the app, and the Permission check still reported nothing missing. So a missing-permission failure has not been reproduced. Do not rely on removing a permission to stop the app. Dry-run is the control that stops all changes. confirmed on a test site

The admin page has a read-only Permission check. It ran on the test project and reported nothing missing. confirmed on a test site The Permission check listing a permission that is really missing has not been seen. in testing

Dependencies

A dependency audit on 2026-11-07 found 15 advisories (8 high, 7 moderate). All are inside Atlassian Forge packages and their children. The app does not import the affected packages directly. The finding is disclosed in the project's dependency audit. Whether the Marketplace review accepts it is not confirmed. automated tests

Not yet in place

None of these exist yet

No security certification, no compliance claim, no independent audit report and no penetration test exists yet. There is no bug bounty.

To report a vulnerability, write to [email protected]. See the vulnerability disclosure policy.