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
- Every function call executes in Atlassian's sandboxed Node 24 runtime
- Every storage write goes to Forge Key Value Store (encrypted at rest, AES-256, Atlassian-managed)
- Every outbound network call is whitelisted in the Forge manifest and proxied through Atlassian
- The app cannot run code on your servers or your users' machines
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:
api.atlassian.com— Atlassian's own platform API, used only for Atlassian's required personal-data reporting flow (report:personal-data), authenticated by Forge with no credentials supplied by you
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
- Recoup collects and stores no Atlassian account credentials — no user passwords, no user or org-admin API tokens. All Atlassian access is via Forge-granted app/user authentication (
asApp()/asUser()), so there is no app-held credential to store, leak, or rotate. - No third-party secret manager is used. There is no AWS Secrets Manager, no GCP KMS, no Hashicorp Vault.
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:
- 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 ForgeasUser()(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 ForgeasUser()(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).
- 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
- Method: deterministic rule-based heuristic over display-name and email-prefix patterns (e.g.
bot,svc,noreply,integration) - Data used:
displayName,email, and the user's product-access list — never leaves the runtime - Purpose: flag likely service / bot / integration accounts so admins don't accidentally remove them from a Jira access group and break an integration; flagged accounts are surfaced for review and excluded from bulk reclaim actions server-side
Dashboard summary
- Method: deterministic composition from aggregate recommendation counts and dollar totals
- Data used: aggregate counts and dollar totals per recommendation category — no individual user data leaves the runtime
- Purpose: generate the dashboard executive 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:
- SOC 2 Type II
- ISO 27001 / 27017 / 27018
- PCI-DSS (for the platform itself; Recoup does not handle payment data)
- GDPR and CCPA compliance commitments
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.