Security and data handling
This page answers the questions security and procurement teams usually ask about a Confluence app. For the legal details see the privacy policy.
At a glance
| Question | Answer |
|---|---|
| Where does the app run? | Only on Atlassian Forge: Forge functions, a Forge queue and Forge SQL. No servers of our own. |
| Does it send data outside Atlassian? | No. The app declares no external connections (no Forge remotes, no egress). |
| Does it store page content or files? | No. Page text and files pass through the app's memory during a copy and are written into the new space; they are not saved by the app. |
| What does it store? | For 30 days after a copy: page titles and IDs, short link notes, a record of the copy and an audit-log line, then all deleted. While installed: monthly totals without names or IDs, template settings and app settings. Details. |
| Personal data | Atlassian account IDs (plus whatever people type into template values, space names or descriptions, and names that appear in page titles), deleted with the job records after 30 days. Reported to Atlassian's personal data reporting service every 7 days; data of closed accounts is erased. Details. |
| Data residency | Supported. All stored data is in Forge hosted storage, which Atlassian keeps in the same location as your Confluence site. |
| Does it log End-User Data? | Only limited error details (see logging). Logs stay in Atlassian. |
| Third parties or sub-processors for app data | None besides Atlassian, which hosts the app. |
| Does it handle passwords, API tokens or other secrets? | No. |
| Does it use AI? | No. |
| Certifications | None. We do not hold SOC 2, ISO 27001 or similar certifications, and we do not take part in Atlassian's Marketplace bug bounty programme at present. |
Architecture
Spacewright is a Forge app. Its screens are built with Atlassian's UI Kit and run inside Confluence. Every action calls a Forge function, which checks the licence and the user's access and then calls Confluence's REST API. Copies run as background jobs on a Forge queue, in slices of up to about 10 minutes. Three scheduled jobs run on Forge: one every hour restarts stalled copies, one every hour deletes data older than 30 days, and one every day checks whether the 7-day personal data report to Atlassian is due. The app's own data is kept in Forge SQL, a database that Atlassian provides separately for each installation.
Data the app stores
| Data | Kept |
|---|---|
| Working data of each job: titles, IDs and positions of the pages, folders, blog posts, whiteboards, databases and smart links found in the source space; attachment names and IDs; links that could not be switched (up to 300 characters each); unfilled placeholders; error messages | 30 days after the job ends (or after its last activity, for a job that never ended), then deleted by an hourly clean-up with Forge SQL deletes |
| Job record: who started it (Atlassian account ID), when, source and new space, options, template values, counts, result; for dry runs the list of items that cannot be copied or would be skipped, with where each one is in the source space | |
| Audit log: one line per finished copy (time, account ID, type, space keys, page count, result) | |
| Monthly totals, made from audit-log lines when they are deleted: month, type, result, number of copies and pages. No account IDs, space keys, titles or content IDs. | While the app is installed |
| Template list and app settings (group IDs, default options) | While the template is on / while the app is installed |
| Progress of the personal data report: time of the last report and, while a report is running, the last account ID reported | Account ID removed when the report finishes |
In Confluence itself the app writes the copied content, a copy report page, template settings as a space property (without any account ID), and a marker property on spaces it creates. These stay under your control and are not removed by the clean-up.
On uninstall, Atlassian soft-deletes the app's stored data and then removes it under its Forge data lifecycle. The app stores nothing outside Atlassian, so nothing remains with us.
Personal data
The only personal data the app stores is Atlassian account IDs: who started a copy (needed to run the copy with that person's permissions) and who appears in the audit log. No names, email addresses or other profile data are stored; screens show names by asking Confluence at display time. Account IDs are deleted with the job records and audit-log lines after 30 days.
Following Atlassian's Forge user privacy guidelines, a scheduled job reports the stored account IDs to Atlassian's personal data reporting API (privacy.reportPersonalData, scope report:personal-data) once every 7 days, at most 90 per request, never the placeholder ID unknown. For each account Atlassian reports as closed, the app deletes that person's job records with their working data and removes the account ID from their audit-log lines. The report runs whether or not the site is licensed.
Data residency
All data the app stores is kept in Forge hosted storage (Forge SQL). Atlassian holds it in the same location as your Confluence site and moves it with the site if your admin changes the data residency location. In-scope End-User Data for residency is everything in the table above.
Access control
- Licence check on every call. Every screen request and every background slice checks the Marketplace licence. Without an active licence the app refuses to work and running copies stop.
- Acts as the user. Screen requests call Confluence as the signed-in user. Background copies call Confluence as the user who started them (Forge user impersonation), so a copy can only read what that person can see and Confluence enforces their permissions when content is created.
- App roles. Site admins may limit the app and template management to groups. The settings page and audit log are for site admins only; this is checked on the server, not only in the screen.
- Restricted content is never copied open. Page restrictions are copied by default, and each restricted page or blog post is restricted as soon as it is created, before its content, attachments or child pages are written. If restriction copying is turned off, or Confluence refuses a restriction, the restricted page and everything inside it are not copied and are listed as not copied. The copy report page is visible only to the person who ran the copy; if Confluence does not allow that, the report counts restricted pages without naming them.
- Jobs are private to the person who started them. Site admins can follow and cancel every job, but for someone else's job they see its status, spaces and counts, not the page titles in it.
- No access for us. We have no account on your site and no way to sign in to it. We do not hold credentials or tokens for your site.
Atlassian permissions (scopes)
The app asks for granular scopes, and only those that Atlassian's REST API documentation lists for the calls it makes. The scopes used by background copies can be used on behalf of the user who started the copy, which is what lets those copies run with that user's permissions; read:, read: and report: cannot.
| Scope | Why it is needed |
|---|---|
read:, write: | List, search and read spaces (including the source space's description, when Space look is ticked), check that a space key is free and what the user may do in a space, create the new space (including copying space permissions from the source when that option is chosen), and read and save space properties: template settings and the marker on spaces Spacewright creates |
read:, write: | Read pages and blog posts with their labels and properties, create and fill in their copies, copy their properties, and write the copy report page |
read: | Read the page tree in order |
read:, write: | Create folders, and read and copy their properties |
read:, readonly:, write: | List and download attachments, and upload the copies |
read: | Required by Confluence's older (v1) API for searching a space for its folders, whiteboards, databases and smart links (Confluence has no other way to list those at the top level of a space), for reading page restrictions, page templates and the current user's permissions, and for uploading attachments |
read:, write: | Add the copied labels |
write: | Give each copied restricted page its restrictions as soon as it is created (on by default), and restrict the copy report page to the person who ran the copy |
read:, write: | Copy the space's page templates |
read:, write: | Copy the space theme and space settings to the new space, only when Space look is ticked (details) |
read:, read: | Check which groups the current user is in (for the access settings), and let site admins pick groups on the settings page |
report: | Report the stored account IDs to Atlassian every 7 days and learn which accounts were closed (see personal data) |
Not requested, because no call needs them: space-permission scopes (copying space permissions is part of creating the space), separate space-property scopes, content-metadata and restriction-read scopes. Not requested on purpose: the site-wide Confluence settings scopes (read:, write:). Copying a space's colours would need them, so Spacewright does not copy colours.
Logging
When an unexpected error happens in a screen request, the app logs the error type, the HTTP status, the error code and, for a Confluence error, the API route with content IDs and query removed (for example /wiki/api/v2/pages/{id}). It does not log Confluence's error text, and any quoted text in other error messages is removed before logging. The app does not log page content, page titles, template values or user details. Error messages stored with a copy and shown on the copy report page give only the HTTP status, never the API path or Confluence's error text. Logs are stored by Atlassian. Atlassian lets the developer read them for your site unless your admin turns off Logs access for the app in Atlassian Administration (Apps → Connected apps).
How we build it
- Database queries pass values as parameters; user input is never pasted into SQL text.
- Input from the screens is checked on the server (space keys, variable names, value lengths, job types).
- Unexpected errors in the screens are shown to users as a general message; the details go only to the log.
- Before each release we run the automated tests and check dependencies for known vulnerabilities, and we use a supported Node.js runtime.
- We follow Atlassian's security requirements for cloud apps and its Security Bug Fix Policy for fix times.
Report a vulnerability
Email security@spacewright.app. Please include the steps to reproduce and the impact you expect. Do not access other customers' data or disrupt the service while testing. We will confirm receipt within 2 business days, keep you informed, and credit you if you wish once the issue is fixed.
Our security.txt file is at /.well-known/security.txt.
If something goes wrong
If we learn of a security incident affecting Spacewright customers, we will notify Atlassian within 48 hours, as Marketplace partners must, and inform affected customers without undue delay with what happened, what data was involved and what we are doing about it.