Privacy and data handling
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 and is read with the data processing addendum (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.
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 (opens in a new tab) 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.
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 (opens in a new tab).
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 |
| 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 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 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 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 (opens in a new tab) 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. 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.