# Privacy and data handling

> What Oktul Code Studio stores, what leaves your Atlassian site, where it goes and why. Scripts reach only the hosts your administrator approves.
>
> Documentation for Oktul Code Studio, for Jira Cloud and Confluence Cloud, by Oktul: https://oktul.com/docs/plugins/code-studio/privacy/

**Version 1.0. It takes effect when Oktul Code Studio for Jira or Oktul Code Studio for Confluence is published on the Atlassian Marketplace.**

## 1. Scope

1.1 This notice describes the processing of personal data by Oktul Code Studio for Jira and Oktul
Code Studio for Confluence (each the “Application”), two applications built from one source that
process data in the same way. It forms part of the [application licence](https://oktul.com/legal/app-terms/) and is
read with the [data processing addendum](https://oktul.com/legal/dpa/) (the “Addendum”). Terms defined in the licence
have the same meaning here.

1.2 It does not cover oktul.com or the personal data Oktul processes as a company, which are
described in Oktul’s [privacy policy](https://oktul.com/legal/privacy/).

1.3 The Application runs scripts the customer writes. What a script reads, sends and keeps is
decided by the customer. The Application sends data outside the Atlassian platform to the
destinations in clause 5, which include any host the customer’s administrator approves.

1.4 Scripts, their variables and the credentials of their connections are Customer Data. Oktul
operates no infrastructure in the data path, so it does not read, review or keep a copy of any of
them.

## 2. Roles and contact

2.1 For Customer Data processed by the Application, the customer is the controller and Oktul
OÜ is the processor within the meaning of Regulation (EU) 2016/679 (the “GDPR”). Oktul
processes it only to provide the Application, on the customer’s documented instructions, as
set out in the Addendum.

2.2 Oktul, and not Atlassian, is responsible for the privacy, security and integrity of the
personal data the Application processes.

2.3 Atlassian Pty Ltd hosts the Application on the Forge platform on Oktul’s behalf and is
Oktul’s sub-processor for that hosting, under the Forge Data Processing Addendum and the
standard contractual clauses it incorporates. The Application has no other sub-processor. Rovo, the
AI the Application’s agents run in, is Atlassian’s service, used under the customer’s own agreement
with Atlassian.

2.4 For the licence record Atlassian provides when the Application is installed or ordered,
and for support correspondence, Oktul is the controller. Oktul’s privacy policy governs that
processing.

2.5 Contact details:

- **Processor:** Oktul OÜ, registry code 17589681, Seebi tn 1-703, 11316 Tallinn, Harjumaa,
  Estonia
- **Data protection requests and legal notices:** legal@oktul.com
- **Support and vulnerability reports:** the [Oktul Help Center](https://oktul.atlassian.net/servicedesk/customer/portals)
  or support@oktul.com

## 3. Data processed

3.1 The Application writes the following personal data of its own accord:

(a) the Atlassian account id of who created, saved, started, stopped or may see a script, a run, a
space or any other record, with no name, email address or profile stored with it;

(b) for a listener’s run, the user objects Jira or Confluence return for the account that caused the
event and for the people named on the work item or page the event names: the account id, display
name, avatar addresses, time zone and locale, and an email address where the person’s profile
visibility shows it. They are kept with the run while it is unfinished and deleted when it ends;

(c) the account name a Git provider returns for the token of a connected repository, which names
the connection, and the user name a connection to a Git host signs in with.

3.2 A script’s log, its result, the changes it lists, the event it was handed and what it keeps in
`store` are the customer’s content, and can contain anything the script reads, personal data
included. The Application does not inspect them.

3.3 Connection credentials, secret script variables and repository tokens are kept in Forge’s
encrypted secret store. None reaches a browser. A secret variable reaches the script and is
blanked out of every log line, result, error and listed change. The Application does not accept
an Atlassian account’s API token or password.

3.4 The Application keeps two kinds of log:

| | Forge logs | Runs and the audit log |
|---|---|---|
| Read by | Oktul, to diagnose a fault | The customer’s users, in the console |
| Account ids | No | Yes |
| Script code, output and content | No | Yes, a run’s own |
| Credentials | No | No |

A test holds every Forge logging call in the source to literal text.

3.5 A run acts as the Application or, through Forge’s offline user impersonation, as the person
who started it, as stored configuration decides. A Rovo agent reads the site as the person talking
to it.

3.6 The Application carries out no automated decision-making or profiling within the meaning of
Article 22 of the GDPR. A customer’s script may; the customer decides what it does.

## 4. Where the data is stored

4.1 Data the Application stores is stored on the Atlassian platform, in the customer’s site:

| Data | Where it is stored |
|---|---|
| Scripts, revisions, spaces, triggers, connections without their secrets, variables, settings, runs, logs and changes | Forge storage |
| Credentials, secret variable values and repository tokens | Forge encrypted secret store |
| A scripted field’s value | The Jira work item |

4.2 The location of data on the Atlassian platform is determined by Atlassian. Where the
customer has configured data residency, Atlassian stores the Application’s Forge storage in the
same location as the customer’s data for the required product.

## 5. Recipients and transfers

5.1 The Application sends data to the following destinations and no others. The first five are
declared in its Forge manifest. Adding one requires a new version that each administrator must
approve.

| Destination | Data received | Purpose |
|---|---|---|
| GitHub, `api.github.com` | A connected space’s scripts, and the token the customer gave | Keeping a space in step with a GitHub repository, when the customer connects one |
| Bitbucket Cloud, `api.bitbucket.org` | The same | The same, for a Bitbucket Cloud repository |
| GitLab, `gitlab.com` | The same | The same, for a GitLab.com repository |
| Atlassian’s API gateway, `api.atlassian.com` | What a script or a connection sends to another Atlassian site or to Atlassian Administration | Scripts that reach another Atlassian site or the organisation APIs. A request to the customer’s own site is routed through Forge instead |
| Atlassian’s authorisation server, `auth.atlassian.com` | A service account’s client id and secret | Exchanging them for a token |
| A host the customer’s administrator approves, a self-managed GitLab or another Git host included | What the customer’s scripts and connections send to it, and a connected space’s scripts with the token the customer gave | Whatever the customer’s scripts do. Sent only after the administrator approves the host in Atlassian’s dialog |

5.2 A repository and an approved host are reached under the customer’s own account and agreement
with their provider, and are not Oktul’s sub-processors.

5.3 When an organisation admin connects the Application to Atlassian’s Teamwork Graph, each
script’s name, description, folder path and newest draft, the account ids of who created and
changed it, and the account ids of the members of the groups that may see it, go to the Teamwork
Graph, which is Atlassian’s, so that Rovo Search and Rovo Chat find scripts for the people who may
see them. The data stays inside Atlassian. Disconnecting deletes it. See
[Teamwork Graph connector](../teamwork-graph/).

5.4 When the customer’s administrator turns on the Application’s tools for external AI assistants
in Atlassian Administration, a person may connect an assistant of their choice, such as Claude, to
them, signed in with their own Atlassian account. What the assistant reads through those tools, which
is only what that person may read in the Application, goes to the assistant’s provider under the
person’s or the customer’s own agreement with that provider, which is not Oktul’s sub-processor.
The Application sends nothing to an assistant by itself.

5.5 The console shows co-editors’ Atlassian profile pictures, which the person’s browser loads from
Atlassian’s avatar service. The Application sends nothing there.

5.6 The Application uses no analytics, telemetry, error-reporting service or third-party script.
No Oktul server or database is in the data path.

5.7 The customer controls the hosts in the last row: none receives anything until approved, and an
approval can be withdrawn in Atlassian Administration. The five declared hosts receive data only when
the customer connects a repository or writes a script or connection that uses them.

5.8 Atlassian’s sub-processors are listed at
[atlassian.com/legal/sub-processors](https://www.atlassian.com/legal/sub-processors).

## 6. Permissions

6.1 The Application requests the following scopes. A script may call any documented Jira, Jira
Service Management, Assets or Confluence REST operation, so the Application holds the scopes those
operations need. Oktul Code Studio for Confluence holds the same scopes less the three
`object:jira` scopes.

| Scope | Purpose |
|---|---|
| `report:personal-data` | Report the Atlassian account ids Code Studio stores to Atlassian once a week, and erase an account Atlassian reports closed |
| `read:app-data:jira` | Read the app's own Jira data: scripted field values and dynamic form registrations, which Jira serves only to the app that owns them |
| `write:app-data:jira` | Write a scripted field's value and register dynamic forms, which Jira accepts only from the app that owns them |
| `read:object:jira` | Writing, reading and deleting the scripts the Teamwork Graph connector publishes for Rovo Search and Rovo Chat, after an organisation admin connects it. Jira app only |
| `write:object:jira` | Writing, reading and deleting the scripts the Teamwork Graph connector publishes for Rovo Search and Rovo Chat, after an organisation admin connects it. Jira app only |
| `delete:object:jira` | Writing, reading and deleting the scripts the Teamwork Graph connector publishes for Rovo Search and Rovo Chat, after an organisation admin connects it. Jira app only |
| `manage:jira-configuration` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:jira-work` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `write:jira-work` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `manage:jira-project` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:user:jira` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:issue-details:jira` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:jira-user` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:permission:jira` | Let a script call the Jira REST operations this scope covers, as the app or as the person who started the run |
| `read:board-scope.admin:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `write:sprint:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `write:board-scope:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `read:sprint:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `write:epic:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `read:board-scope:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `delete:sprint:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `write:board-scope.admin:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `read:epic:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `read:issue:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `delete:board-scope.admin:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `write:issue:jira-software` | Let a script call the Jira Software (agile) REST operations this scope covers |
| `manage:servicedesk-customer` | Let a script call the Jira Service Management REST operations this scope covers |
| `read:servicedesk-request` | Let a script call the Jira Service Management REST operations this scope covers |
| `write:servicedesk-request` | Let a script call the Jira Service Management REST operations this scope covers |
| `read:knowledgebase:jira-service-management` | Let a script call the Jira Service Management REST operations this scope covers |
| `read:requesttype:jira-service-management` | Let a script call the Jira Service Management REST operations this scope covers |
| `import:import-configuration:cmdb` | Let a script call the Assets REST operations this scope covers |
| `read:cmdb-object:jira` | Let a script call the Assets REST operations this scope covers |
| `write:cmdb-schema:jira` | Let a script call the Assets REST operations this scope covers |
| `write:cmdb-type:jira` | Let a script call the Assets REST operations this scope covers |
| `read:cmdb-type:jira` | Let a script call the Assets REST operations this scope covers |
| `read:cmdb-schema:jira` | Let a script call the Assets REST operations this scope covers |
| `write:cmdb-object:jira` | Let a script call the Assets REST operations this scope covers |
| `write:cmdb-attribute:jira` | Let a script call the Assets REST operations this scope covers |
| `read:cmdb-attribute:jira` | Let a script call the Assets REST operations this scope covers |
| `delete:cmdb-attribute:jira` | Let a script call the Assets REST operations this scope covers |
| `delete:cmdb-object:jira` | Let a script call the Assets REST operations this scope covers |
| `delete:cmdb-schema:jira` | Let a script call the Assets REST operations this scope covers |
| `delete:cmdb-type:jira` | Let a script call the Assets REST operations this scope covers |
| `write:confluence-content` | Let a script call the Confluence REST API v1 operations this scope covers |
| `write:confluence-space` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-content.summary` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-space.summary` | Let a script call the Confluence REST API v1 operations this scope covers |
| `write:confluence-groups` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-content.all` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-content.permission` | Let a script call the Confluence REST API v1 operations this scope covers |
| `manage:confluence-configuration` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-groups` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:confluence-user` | Let a script call the Confluence REST API v1 operations this scope covers |
| `search:confluence` | Let a script call the Confluence REST API v1 operations this scope covers |
| `read:page:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:comment:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:content-details:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:attachment:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:content.metadata:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:space:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:custom-content:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:configuration:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:page:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:hierarchical-content:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:whiteboard:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:database:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:configuration:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:folder:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:embed:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:space.permission:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:group:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:comment:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:audit-log:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:user.property:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:user:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:whiteboard:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:database:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:user.property:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `delete:page:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:task:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `delete:comment:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:space.permission:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:custom-content:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `delete:folder:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:embed:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `read:label:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:space:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `delete:custom-content:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:task:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `write:folder:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `delete:attachment:confluence` | Let a script call the Confluence REST API v2 operations this scope covers |
| `storage:app` | Store scripts, runs, logs, settings and every other record in the site's Forge storage |

6.2 Every product scope except the Application’s own data scopes is marked for offline user
impersonation, so a run can act as the person who started it, for the reason in clause 3.5. The
Application holds no email address scope.

## 7. Limitations of access control

7.1 A run that acts as the Application reads and writes whatever the Application’s scopes reach,
which can be more than the person who wrote or started the script may see. Only administrators
decide that a script runs as the Application.

7.2 A secret variable is visible to the script that reads it. A script that sends its value to a
host the customer approved sends it there.

7.3 A dynamic form hides fields on screen only. Jira still saves a hidden field.

## 8. Retention

8.1 Runs, their logs and changes are kept for the run retention the customer’s administrator
sets, 1 to 90 days, then expire. A run’s inputs, with the user objects in clause 3.1(b), are
deleted when the run ends, and expire with the run retention if it never does. Data a script keeps in `store` is kept until the
script deletes it or its time to live ends.

8.2 A script keeps its 20 newest revisions and none older than a year, never its draft or a
revision that was ever published. Other records are kept until they are deleted or the
Application is uninstalled.

8.3 The Application takes part in Atlassian’s personal data reporting. Once a week it reports the
account ids in its records and in unfinished runs’ inputs to Atlassian, 90 to a request, each with
the time it was first stored. An account Atlassian reports closed is erased from every record: a
single field becomes `erased-account`, an access list drops the id, a stop request is deleted, and
its user object in a run’s inputs is reduced to `erased-account`. An account Atlassian reports
updated keeps only its id in a run’s inputs. The report runs whether or not the licence is
active.

8.4 What Atlassian keeps after the Application is uninstalled is stated in clause 9.

## 9. Data portability and switching

Code Studio sends data outside the Atlassian platform to be processed, and stores everything you keep in your own site. Every service that receives data is listed below with what it keeps, including any copy Oktul holds.

| Data | Where it is | How to export it |
|---|---|---|
| Scripts with their revisions, spaces, listeners, schedules, API triggers, connections, variables, scripted fields, dynamic forms and settings | Forge storage in your site; credentials in its secret store | Export as zip on the administration page: every script as a file and every other record as JSON. Secrets only sealed with a passphrase |
| Runs, their logs and their changes | Forge storage in your site, for the run retention you set | Read in the console. Not part of the export |
| Scripted field values | The Jira work items that hold them | Jira's own export and the Jira REST API, as for any custom field |

**Services outside the Atlassian platform**

| Service | Receives | Keeps | Under whose contract |
|---|---|---|---|
| Your repository provider: GitHub, Bitbucket Cloud, GitLab or another Git host you connect | The scripts of each space you connect to a repository | The commits, under your account | Yours |
| Hosts your administrator approves | What your scripts and connections send | Decided by you and that provider | Yours |

**After uninstallation.** Scripted field values stay on their work items. According to Atlassian’s documentation, Forge storage is relinked if the app is reinstalled within 21 days, and Atlassian then deletes it under its data retention policy.

Oktul charges no fee for switching to another product or for exporting data. [Clause 11 of the application licence](https://oktul.com/legal/app-terms/#switching) sets out the terms.

## 10. Rights of data subjects

10.1 Data subjects have the rights of access, rectification, erasure, restriction of
processing, data portability and objection under Articles 15 to 21 of the GDPR. For Customer
Data, the controller is the customer, and requests are made to the customer.

10.2 Oktul assists the customer with such requests free of charge, as clause 7.1 of the
Addendum provides. Requests concerning data for which Oktul is the controller are sent to
legal@oktul.com and answered within one month, extendable by two further months under Article
12(3) of the GDPR.

10.3 A data subject may lodge a complaint with the Estonian Data Protection Inspectorate
(Andmekaitse Inspektsioon, Tatari 39, 10134 Tallinn, info@aki.ee) or with the supervisory
authority of their habitual residence, place of work or place of the alleged infringement.

## 11. Security

11.1 According to Atlassian’s documentation, Forge provides tenant isolation and encryption in
transit and at rest. Oktul operates no infrastructure in the data path and holds no credential
for the customer’s site. Oktul’s own measures are set out in clause 5 of the Addendum, and the
Application’s controls on its [security](../security/) page.

11.2 The sandbox mode reports what a script would change against the site as it was. It does not
guarantee that a later production run makes the same changes.

11.3 Oktul holds no audited security certification. The Application is listed in the Cloud
Security Alliance STAR Registry at Level 1, a self-assessment of 138 CAIQ Lite questions, which
is published in full on the [security assessment](../caiq/) page. A self-assessment is not an
independent audit.

## 12. Vulnerability reports and security incidents

12.1 A vulnerability is reported through the Oktul Help Center or to support@oktul.com, where
it receives a reference. Oktul responds within 24 hours, Monday to Friday, and credits the
reporter by name unless asked not to. Oktul does not pay bounties. Research in good faith is
covered by clause 8.5 of the application licence. Security testing of a Forge application is
testing of the Atlassian platform and must comply with Atlassian’s policies.

12.2 Oktul remediates vulnerabilities within the following periods, measured by CVSS score. The
periods under Atlassian’s [Security Bug Fix Policy](https://developer.atlassian.com/platform/marketplace/security-bugfix-policy/)
for cloud apps also apply, and the shorter period governs.

| Severity | Oktul | Atlassian’s requirement |
|---|---|---|
| Critical, CVSS 9.0 or higher | 7 calendar days | 10 days |
| High, CVSS 7.0 to 8.9 | 14 calendar days | 4 weeks |
| Medium, CVSS 4.0 to 6.9 | 28 calendar days | 12 weeks |
| Low, CVSS below 4.0 | 56 calendar days | 25 weeks |

12.3 Oktul notifies the customer of a personal data breach affecting Customer Data without
undue delay and in any event within 24 hours, as clause 7.3 of the Addendum provides.

## 13. Changes to this notice

13.1 The version and effective date at the top of this page identify the version in force. A
change is recorded in the [release notes](../release-notes/). A change to the data processed,
its recipients or who can access it is stated there, and a new destination is announced before
the version that introduces it. Oktul notifies the technical contacts of installations and
Atlassian of a material change.
