Cardinal Ruler / App data handling

How Cardinal Ruler handles data

It runs inside Atlassian's cloud, and the record it produces is committed to a repository your organisation owns. No configuration, no change record and no personal data is sent to VMotion IT Solutions Ltd.

This page covers the Cardinal Ruler application for Jira Cloud: which data it reads, what it keeps and for how long, what it writes to your repository, and which Jira permissions it asks for and why. The cardinalruler.com website is covered separately, on the privacy and cookies page.

Applies to: Cardinal Ruler for Jira Cloud · Last updated 10 September 2026

Cardinal Ruler stores no data outside Atlassian apps and services, processes it only in Atlassian Forge and in the browser where its screens run, and its log lines carry nothing about the people using it. That last point is true by construction rather than by policy: a log line has no field that could carry it.

Who is responsible for what

Your organisation is the data controller for everything Cardinal Ruler processes. VMotion IT Solutions Ltd is a processor, acting on the instructions carried in the agreement with your organisation.

In practice the processing is narrower than that split suggests. The app runs on Atlassian Forge, inside your own Atlassian tenancy. There is no VMotion endpoint anywhere in the app: the only external address it is permitted to contact is api.bitbucket.org, which serves the repository your organisation nominates. That restriction is declared in the app manifest and enforced by the Forge platform, not by convention.

Where the data sits

The three places data involved in Cardinal Ruler can be found
LocationWhat is thereControlled by
Your Jira site The configuration Cardinal Ruler reads during capture, and the user directory it resolves names from. Read only on the origin site. Your organisation
Atlassian Forge app storage Short-lived caches, unsubmitted review marks, one interface preference, and the repository credential. Listed in full below. Your organisation, in your Atlassian tenancy
Your Git repository The audit record: one folder of plain files per change, committed as the change progresses. Your organisation

Permissions and network access, and why each is needed

Requested Atlassian scopes and the reason for each
PermissionWhy it is needed
read:jira-workReads workflows, statuses and resolutions during capture, and the site's own address.
read:jira-userResolves the display name of the account taking an action, so the record names a person, not an identifier.
read:group:jiraAnswers whether an account belongs to a named group, which is how the Approver and Release Manager roles can be granted by group.
manage:jira-configurationCreates and updates workflows on the target site. Also required to check whether another account holds Jira administration rights, which the role gates depend on.
manage:jira-projectThe Jira screens endpoints require this permission. Used to capture screens and to create them on the target site.
storage:appThe Forge app storage listed above.
api.bitbucket.orgThe single external address the app may contact. Reads and commits the audit repository your organisation nominates.

manage:jira-configuration is the broadest of these, and gets its own paragraph here: in Jira it carries administration rights. Cardinal Ruler asks for it because the workflow writes and the administration check above cannot be done without it, and no narrower scope currently covers them.

Where that is, and how it is protected

Cardinal Ruler runs no infrastructure of its own, so there is nothing to locate outside Atlassian. Forge app storage sits inside Atlassian's platform alongside your site and follows the location that site is pinned to: pin the Atlassian app, and the app storage is pinned with it. The audit record sits in the Bitbucket workspace your organisation nominated, and Bitbucket Cloud does not offer a residency choice at the time of writing, so that repository is held wherever Atlassian hosts the service.

Traffic to the repository goes over HTTPS. The repository credential is held in Forge's encrypted secret storage, not in ordinary app storage, and encryption at rest for app storage is provided by the Forge platform.

Whose personal data, and which fields

Cardinal Ruler records who did what, so the people it names are mostly the administrators who use it: the Author who designs a change, the Approvers who decide on it, and the Release Manager who deploys it.

There is one exception worth stating plainly. Where a captured permission or notification scheme grants to a named account, that account's id and display name are captured with the scheme, so the record can name someone who has never opened Cardinal Ruler. Where a scheme grants to a group or a project role instead, the record carries the group or role, not a list of its members.

Three fields are involved, all read from your own Jira user directory:

  • the Atlassian account id
  • the display name
  • the email address, where Jira exposes one for that account

Nothing else about a person is recorded. No profile picture, no job title, no location, and no group membership beyond the yes-or-no answer to whether an account belongs to a named group.

What the app keeps in Forge storage

Forge app storage holds working state, not the record. Most of it is a cache derived from your Jira site that expires in a minute. The rest is one interface preference, a reviewer's marks on a review they have not yet submitted, aggregate counts of API calls, and the repository credential in encrypted secret storage.

Contents of Cardinal Ruler's Forge app storage
What is storedKeyed byKept for
Whether an account belongs to a named Jira groupAccount id and group name60 seconds
The list of change requests a person is allowed to seeAccount id60 seconds
Review marks a reviewer has made but not yet submittedAccount id and change idUntil submitted or cleared
Whether the navigation rail is collapsedAccount idUntil changed
The credential for your repositoryNot personal dataHeld in Forge encrypted secret storage until replaced
Counts of Jira API calls and their outcomesCounted per site, with no user identifiersAggregate counters, kept while the app is installed

The 60-second caches exist so that a screen does not re-read the same permission check a dozen times. Each cached value carries its own expiry inside it and is discarded on read once that expiry has passed, so a stale privilege cannot outlive the minute even if the platform is slower to reclaim the key.

What is written to your repository

Each change becomes its own folder of plain files: what was asked for and why, every pre-flight finding and the decision taken on it, the configuration as captured at submit, and the post-deploy check. Each review round commits its own snapshot.

That record names people, deliberately. Evidence that cannot say who approved a change is not evidence.

  • Records carry the account id, display name and, where available, the email address of the person who took each action.
  • Each commit carries a git author line in the standard form, the display name followed by the email address in angle brackets. Where Jira exposes no email address for that account, noreply@cardinal-ruler is written instead.
  • Captured permission and notification schemes include a map from account id to display name, so that the record stays readable years later rather than being a list of opaque identifiers.

Because the repository belongs to your organisation, the retention and deletion of that history is your decision. VMotion holds no copy of it.

Keeping secrets out of the record

Operational detail attached to a change is redacted before it is committed, because a secret committed to a git history is permanent. Any field whose name looks credential-shaped is replaced wholesale, and the remaining values are scanned for known secret shapes: Bitbucket app passwords, Atlassian API tokens, and bare email addresses. Values are scanned first and only then length capped, so truncation cannot produce a string that slips past the patterns. Only scalar values survive the filter: strings, numbers and booleans. Nested objects and arrays are dropped whole.

The repository credential itself is held in Forge's encrypted secret storage. It is never written into a record, a timeline entry or a log line.

What the logs contain

Atlassian shares an app's console log lines with VMotion IT Solutions Ltd, which publishes it, so what those lines may contain is a design constraint rather than a promise. Cardinal Ruler builds them from a fixed set of fields: the operation, an error kind, an HTTP status, retry and timing metadata, and the change and step identifiers. There is no field for free text.

They therefore carry no account ids, no email addresses, no configuration names, no field values, no repository or workspace names, and nothing typed into the app. The evidence trail you read is the change record in your own repository; the console is support telemetry only.

Your organisation can withdraw that log access at any time. The constraint above is what makes it safe to leave in place.

Retention and deletion requests

Uninstalling Cardinal Ruler removes its Forge app storage. The repository is left as it is: it is your audit record, and an app that erased the evidence of what it did on its way out would defeat the point of keeping it.

A request from an individual to see or erase their personal data is addressed to your organisation, as controller. VMotion holds no copy to search, and cannot rewrite the history of a repository it does not own.

Who else is involved

Atlassian, as the platform the app runs on and as the host of the repository service at api.bitbucket.org. There is no other processor.

Nothing inside the app profiles anyone or is sold on, and no analytics or artificial intelligence service receives any data Cardinal Ruler reads.

Questions

A Data Protection Officer is appointed at VMotion IT Solutions Ltd and can be reached at the address shown here when JavaScript is enabled, or through the contact form.

Changes to this page

This page describes the application as it stands on the date above. It is revised whenever the app starts or stops reading, keeping or writing something, and the date is updated with it.