Recoup — Security Information

This document describes the security posture of Recoup, the Atlassian Marketplace app. It is intended for security reviewers at customer organisations evaluating Recoup for installation.


Platform

Recoup is built entirely on Atlassian Forge, Atlassian's hosted application platform. Recoup operates no third-party servers and runs no code outside Atlassian's network. No End-User Data is transmitted outside Atlassian's infrastructure.

What this means in practice


Permissions

Recoup requests the following Atlassian permission scopes:

Scope Reason
read:jira-user Enumerate Jira users for the cross-product user list
read:jira-work Read issue activity metadata (assignee, reporter, updated) for last-active timestamps. Never reads issue contents or bodies.
read:group:jira List your Jira access-control groups (so you can map products → groups in Settings) and read a group's member accountIds to determine which mapped groups a user belongs to before reclaiming a seat. Reads group names + member IDs only — never issue, page, or ticket contents.
write:group:jira Add or remove a user from a mapped Jira access-control group when an admin reclaims a seat or clicks Add back. This is the only write capability Recoup has, and it is fully reversible (group remove ↔ group re-add).
manage:jira-configuration Required by Atlassian's own Jira group-membership endpoints. The Forge CLI linter (permission-scope-required) mandates this scope for GET /rest/api/3/group/member and POST /rest/api/3/group/user — the member-read and add-to-group calls used by the reversible reclaim/Add-back feature. Recoup requests it solely to satisfy that endpoint requirement; it adds no destructive capability. Recoup performs no Jira configuration changes — it only adds/removes users from the access-control groups you map in Settings, which is reversible. It does not, and cannot, delete groups, change project/permission schemes, alter workflows, or modify any other Jira configuration.
storage:app Forge KVS — store users, recommendations, settings, and the audit log
report:personal-data Atlassian's personal-data reporting flow — weekly reconciliation of account closure and erasure

Recoup requests only these scopes. The three Jira-group scopes (read:group:jira, write:group:jira, manage:jira-configuration) exist solely for the reversible seat-reclaim feature: Recoup right-sizes paid product access by managing membership in the Jira access-control groups you map to products in Settings — adding/removing a user from a group is fully reversible and never deletes, suspends, or hard-deactivates the account. manage:jira-configuration is the broadest of these and is disclosed explicitly above: it is required by Atlassian's group-membership endpoints, not because Recoup changes Jira configuration — it does not. Recoup requests no Confluence or Jira Product Discovery write scopes at all; those findings are insights-only for now. Recoup collects no Atlassian account credentials — it reads users and activity through Forge's app access (asApp()) and never asks you to supply an API token or password.

Recoup additionally requests outbound network access to exactly one endpoint:

This is the only external endpoint Recoup contacts, and it is Atlassian-operated. All user and activity data is read through Atlassian's product APIs: the scan's Jira REST calls and the Jira group/member reads use the app identity (asApp()), and the reversible group-membership reclaim/Add-back writes run as the signed-in administrator's own identity (asUser()). No End-User Data is transmitted anywhere outside Atlassian's infrastructure.

Authentication

Recoup uses two authentication patterns, both standard:

Forge asApp() (scan + group reads)

Recoup invokes Atlassian APIs as the installed app, using Atlassian's internal token mint. Each request is authenticated by Atlassian's platform layer; Recoup never sees a raw user token. The scan's /rest/api/3/search calls and the Jira group reads (/rest/api/3/group/bulk, /rest/api/3/group/member) use this asApp() path.

Forge asUser() (group membership writes)

Group-membership writes — reclaim (DELETE /rest/api/3/group/user) and Add back (POST /rest/api/3/group/user) — run as the invoking administrator's own Atlassian identity via Forge asUser(). Atlassian's identity platform authorizes these directory changes against that administrator's organization-level rights; the app cannot perform them on its own. If the signed-in user is not an authorized organization administrator, the action fails with a clear message and changes nothing.

No customer-supplied credentials

Recoup does not collect or store any Atlassian account credentials — no user passwords, no user or org-admin API tokens. All Atlassian access uses Forge's built-in app/user authentication (asApp() / asUser()) granted by the scopes you approve at install. There is nothing to paste, rotate, or revoke.

Secret handling

Account actions

Recoup never deletes, suspends, or hard-deactivates accounts. Recoup right-sizes paid product access by managing membership in your Jira access-control groups — you map each product to its access group(s) in Settings, and reclaiming a seat removes the user from the mapped group(s) so Atlassian stops billing that seat. This is fully reversible: Add back re-adds the user to the same group(s). The account, its identity, profile, and SSO are left completely untouched.

Group-membership changes (reclaim and Add back) are performed using the signed-in administrator's own Atlassian identity (asUser), not an autonomous app principal. Recoup cannot change group membership on its own; an authorized organization administrator must initiate every change, and the audit log records who performed it.

Recoup can take three account-level actions on users:

  1. Reclaim access — remove from Jira access group(s) (reversible) — calls DELETE /rest/api/3/group/user?groupId={id}&accountId={id} on the Jira platform REST API via Forge asUser() (the signed-in administrator's own identity), removing the user from the mapped Jira/JSM group(s) for the products they aren't using. Atlassian then stops billing those seats; the account, its identity, and SSO are untouched. Requires:
    • At least one Jira/JSM access group mapped in Settings (you choose the products→groups mapping)
    • The caller cannot reclaim their own access (server-enforced)
    • Server-side safety guards exclude org admins, allowlisted/rule-flagged service accounts, and the caller
    • A reason of ≥ 10 characters (server-enforced, written to the audit log)
    • Add back — the one-click undo — calls POST /rest/api/3/group/user?groupId={id} via Forge asUser() (the same administrator identity) and re-adds the user to the same group(s) immediately. Add back is intentionally unguarded (it is the safe direction).
  2. Mark as service account — does not touch Atlassian; only updates Recoup's local allowlist + flag on the user record. Reversible.

product_mismatch for Confluence, and all jpd_creator_waste findings, are insights-only for now: Recoup is not installed on Confluence (planned for v1.1), and the JPD Creator→Contributor change is a role change rather than a group membership change, so Recoup surfaces the dollar value and points you to admin.atlassian.com to right-size those yourself — it performs no Confluence or JPD access changes. Jira and JSM product_mismatch and inactive-user findings are actionable via the reversible group-membership reclaim above.

Every account action writes an immutable audit record before and after execution, capturing the admin's accountId, target accountId, action type, full before/after state diff, success/failure, and reason. Audit records cannot be edited or deleted from within the app.

Recoup never auto-takes account actions. All actions are admin-initiated; no automation acts on its own.

Service-account detection and dashboard summary

Both run entirely inside the Forge runtime with no external calls and no third-party processing:

Service-account detection

Dashboard summary

Neither feature transmits any data outside Atlassian's infrastructure.


Vulnerability reporting

Security vulnerabilities can be reported to security@taskhooker.com. We commit to acknowledging reports within 5 business days and disclosing patches via the Marketplace "What's new" section.

Recoup is a solo-developer product. We do not currently operate a paid bug bounty programme.


Compliance

Recoup inherits the security and compliance posture of the underlying Atlassian Forge platform. Atlassian Forge is certified under:

Recoup itself does not have independent certifications. The app code is reviewed by Atlassian as part of the Marketplace listing approval process.


Audit & change history

For your records, every code change to Recoup is reflected in the What's new section of the Marketplace listing for each version. The Marketplace partner portal also exposes a full version history for compliance audits.