Privacy policy — Crosstab
This page is written from the architecture, not from a template. The source is not public, so the claim is narrower than it sounds. What you can check is the app's Forge manifest. Atlassian shows it to you before you install. A manifest either declares an external host or does not, and this one does not.
Last reviewed: 1 November 2026. This is version 4. The app has not changed since version 3; this site has. It has a support form now, and this edition says what the form sends and the check that runs before it does: The support form. A change to what is collected, what is kept, how long, or who else sees it takes the next version number; a correction that touches none of those moves this date and the digest at the foot of the page instead.
At a glance
- Your Jira sitethe issues your settings select, their fields, and their history where an axis needs it. Read as the person looking at the gadget, while they look, or as whoever switched on a schedule.
- Crosstab, inside Atlassianadds them up in a Forge function and draws them in your browser. What it keeps goes into the app's storage on Atlassian. Once a week, on a site with an active licence, it sends Atlassian the account ids it stores, and forgets any account Atlassian says is closed.
- The vendorcounts per minute and short lines in a log, of sizes, status codes and fixed phrases, through Atlassian's developer console. Your administrator can switch both off.
- Anywhere elsenothing. The manifest declares no external host.
Every record the app keeps, and how long it lives, is in one table under Retention. Once the app is uninstalled, Atlassian keeps the app storage that holds all of it for 28 days, then deletes it. After uninstalling says what can be restored in that time.
Contact: support@chmut.com.
Who this covers
Crosstab is a Jira dashboard gadget built on Atlassian Forge. It is to be distributed through the Atlassian Marketplace. It runs inside Atlassian's infrastructure. It has no servers, no database and no backend of its own.
| Who | Their part |
|---|---|
| Your organisation | Controller for the issue data the app reads. It is your Jira site, your data and your agreement with Atlassian. A request about that data goes to it |
| The vendor, Oleksandr Chmut, trading as oc | Processor for that data, on your instruction; controller for a support message, the licence contact details Atlassian passes on, and visits to these pages |
| Atlassian | Sub-processor: hosts the code, the storage, the data the app reads, and the counters and log the vendor sees |
| Cloudflare | Hosts these pages and counts visits to them, without cookies; runs the check on the support form and keeps a message sent through it for 30 days; sees none of the app's data |
| Apple | Hosts the support mailbox on iCloud; sees none of the app's data |
For the issue data, Crosstab is a processor. Its code runs on Atlassian's platform, and what it reads does not leave Atlassian.
For a support message, the controller is Oleksandr Chmut. That is a sole trader registered in Ukraine, trading as oc, and the vendor the Marketplace listing names. That covers the message, the address it came from, and whatever the sender chose to put in it.
For a visit to this page, the controller is the vendor too. A static host serves the page. The request that fetched it is a request to a server somewhere.
What the app reads
Only what the grid and its settings need. Only while somebody is using a gadget or the administration page, with one exception: Keep automatically. Nothing is sent outside Atlassian. What the vendor can see inside Atlassian, and how your administrator switches it off, is under What the vendor sees.
When Jira is read
| Moment | Read as |
|---|---|
| A dashboard carrying the gadget is opened, or refreshed from the gadget's menu | The person looking |
| The gadget's settings form is open | The person looking |
| The grid is opened at page width | The person looking |
| Someone presses Read again, Finish this read or Try again | The person looking |
| Keep automatically is on: every week on the chosen day, on the 1st of each month, or when a sprint closes - each then, or as soon after as Jira allows | The person who switched it on |
- Closing the dashboard stops the reading entirely, apart from Keep automatically. Switching that off stops it too.
- A grid kept automatically goes into its owner's own history, as their own press of Keep this would. It is read by their account id, with their permissions and nobody else's, as everywhere else.
- Within five minutes of a read that finished, or stopped at the gadget's ceiling, a reload or Read again is answered with the grid already read. After them too, where two counts from Jira say nothing in it has moved. See the five-minute copy.
- Several Crosstab gadgets on one dashboard asking the same question share one read. A script on the dashboard makes it as the person looking. It hands the result to each gadget in that person's browser. It is the same read a gadget makes on its own, and it stores nothing more.
What is read
| What | When | Why |
|---|---|---|
| The issues your settings select, through the saved filter you chose or the search you wrote | Every read | The grid |
| The two axis fields, the numeric field and the issue type | Every read | The grid |
| Status | An axis is status or board column | The grid |
| Status category and resolution date | A read writes the totals of old finished work | To put each issue in the period it was resolved in |
| When each issue was created | The Sprint scope axis | The axis |
| The summary of an issue's parent, usually its epic | An axis is Parent | It is the label each parent carries on that axis |
| The issues' change history | The Sprint scope axis and Crosstab Sprints | When an issue joined a sprint is recorded nowhere else |
| The reader's time zone, from their own Jira profile | An axis is a date with a time in it; a figure runs from a date with no time on it up to now; a render may use their totals of old finished work; a grid already read is checked with Jira's two counts; the metric is time logged in a month | Jira shows and searches dates in this zone for this reader, so months on the grid are cut in it. It is stored with a kept grid where an axis has a time in it, and in finished work, as totals |
| The reader's display name | They publish a grid | The sentence over the published grid that says whose view it is. The name is not stored; their account id is |
| The publisher's display name, by their account id | A published grid is drawn | The same sentence |
| A schedule owner's display name, by their account id | A Jira administrator opens the administration page | The list of the site's schedules: the running ones they may switch off, and the stopped ones they may delete. Asked as the administrator, not stored |
| A saved filter's name, by its id, for each running schedule that reads one | A Jira administrator opens the administration page | The same list. Asked as the administrator, so a filter they cannot open is not named. Jira answers with the whole filter; only the name is used, and nothing is stored |
| Each issue's worklogs: who logged them, when, for how long, and the comment | The metric is time logged in a month | To add up the time logged inside that month. None of them is stored |
| The chosen filter's first hundred issues, with every numeric field the gadget could add up | The settings form, once a filter is chosen | To say which of those fields are filled on that filter, so nobody has to choose a field to find out it draws an empty grid |
Also read, as configuration rather than anybody's data:
- the site's field definitions: what exists, what is numeric, what may be an axis;
- the order a board draws its statuses in, when an axis is status;
- the site's own time-tracking settings, when the settings form is open or the figure is a length of time.
What is used, and what is dropped
- Nothing else on the issue goes into the grid. Free-text fields are not among the fields an axis may be.
- One place ticket text does reach the grid. On the Parent axis, each parent is labelled with its own summary, usually an epic's. Where Jira sends a parent without its summary, the label is the parent's issue key, such as PROJ-142. Either way it is drawn, exported and kept along with the grid, under the parent's id.
- The change history arrives whole. It holds the past values of every field, the assignee's and the description's among them, and who made each change. Only the changes to the sprint, the status and the field being added up are used. None of the history is stored.
- A worklog arrives with its author and its comment. Only when it started and how long it ran are used. No worklog is stored.
- No display name is stored. The account id is the only thing stored about a publisher. The rest of what Jira answers with is dropped where it arrives.
- The settings form gets a count per field, and nothing of the issues. None of it is stored.
Whose permissions
| Grid | Read with the permissions of |
|---|---|
| On a dashboard, and in the settings form | Whoever is looking, so a grid read for them is never wider than their own view of Jira |
| Kept automatically | The person who switched it on, while nobody is looking |
| Published | The publisher, on the press. See a published grid |
What a scheduled read adds, and where to check it
The manifest declares two triggers. You can check them on the consent screen.
| Trigger | What it does |
|---|---|
| Once a day | Puts a run on the app's own queue |
| When a sprint closes | Puts a run on the app's own queue |
The queue's consumer reads one run at a time, for each schedule whose turn it is. If another trigger is ever added, this page says so first, with the date it took effect.
A scheduled read asks Jira what a render asks, plus two requests. A render can make the first one too.
| Request | When | Used from the answer |
|---|---|---|
/myself, the owner's own profile | Once a day for each weekly or monthly schedule, once when a monthly one is switched on, and again whenever a run put off for Jira's hourly allowance comes back | Their time zone only, so "every Monday" is their Monday and "the 1st" their 1st |
GET /filter/{id} | When a sprint closes, for a schedule over a saved filter | Its line of JQL, to pick the sprint's issues out of it |
The built bundle contains no external host. The test suite asserts that, rather than the documentation claiming it.
What the app stores
Most of what the app stores is there because somebody asked for it: a press, or a box left ticked. Two lasting records are written without anybody asking: finished work, as totals and the list of field names. So are two copies used only for a short while. The last grid a person read is used for five minutes. A read that stopped short is used for up to an hour.
The asking is Keep this on the grid, or Keep automatically beside it. That is the same ask, made once for every week, month or sprint. The third way is the box in the gadget's settings offering to keep the first grid it draws. That box is already ticked when a gadget is being set up. So saving the settings as they come keeps the first grid. It is kept for whoever saved the settings, and for nobody else who opens the dashboard. To know who that is, the settings hold that person's Atlassian account id. Jira keeps the settings, and anybody who opens the dashboard can read them. Settings saved by an earlier version of the app keep a first grid for nobody until they are saved again. That first grid is the one grid here kept without a press on the grid.
The box keeps one grid under the settings on screen and then stops. The settings then say which day that one was kept, and stop offering. Change an axis and the gadget draws a different grid with no history of its own. The box is then offered again for that one.
Everything this page says the app writes goes into your own site's app storage. That storage is inside Atlassian's infrastructure and under your agreement with them. None of it leaves it.
Two small notes are the exception: the gadget keeps them in the reader's own browser, in the storage it gives this app's pages. They never leave that browser, and clearing its site data deletes them.
- Which kept grids each gadget was last left showing, so the next load shows the same. It holds two moments, and while they are being drawn again a second copy marks them, so a grid that fails to draw is not tried twice. Its key is a hash of where the gadget sits and of its settings, so a search typed into the settings is not written there.
- That the settings were just saved, so the grid takes focus once it is drawn. Its key names where the gadget sits. It is deleted as soon as the grid is shown.
A kept grid
Written by Keep this, by Keep automatically, or by the settings box.
- In it: this app's own totals, and the choices that produced them. The labels already drawn on the axes, which are things like Bug, In Progress and Payments. Two short hashes, of the filter's JQL and of the board's columns, so a filter edited under the same id is noticed. Where an axis is a date with a time in it, the name of the time zone its months were cut in.
- Not in it: no issue keys, except a parent's on the Parent axis where it stands in for a summary Jira did not send. No field values beyond the labels already drawn on the axes. The filter's JQL and the board's columns are kept only as hashes, not as text.
- Who sees it: only whoever kept it. Its key is a hash of their account id and the choices.
- Lives: until somebody deletes it, or newer grids crowd it out.
- Deleted by: deleting it in the gadget. Or a newer grid, past the caps below. Or uninstalling the app.
Within one set of settings, newer grids crowd old ones out without asking: each set holds its fifty most recent grids. Each person holds up to ten histories, one for each set of settings, and keeping a grid that would start an eleventh asks first.
- Past the fiftieth grid, the cells of the oldest are spent and a single row of it stays. That row is the moment, the axis labels, the totals they came to and the name you typed if you typed one. It lets a line through one cell reach further back than the grids themselves do. It is deleted with the history it belongs to, not on its own.
- At ten histories, keeping a grid that would start an eleventh deletes that person's oldest history, named grids included - but only after Keep this has shown which history that is and that person has pressed Remove and keep this.
- Nothing else deletes a history to make room: the settings box and Keep automatically keep nothing where keeping would delete another history. The ten histories are a cap, and those two take a place in it only where one is free.
- Deleting every grid of a history deletes the history too, with the row each spent grid left behind, and frees its place among the ten.
- A kept grid too large to store is refused rather than trimmed.
A saved setup
- In it: a name, the same choices a kept grid holds, and the account id of whoever saved it. The id is only ever used to let them and nobody else save over it or forget it. The id is never sent back out, not even to them: setups are listed without it.
- Not in it: no figures.
- Saved by an earlier version of the app: a short hash of the id in its place. Only the person who saved it can still save over it or forget it.
- Who sees it: the whole installation.
- Lives: until somebody deletes it, or newer setups by the person who saved it crowd it out.
- Deleted by: deleting it in the gadget, which only whoever saved it can do. Or a newer setup by the same person, past the caps below. Or uninstalling the app.
- When the account that saved it is closed: the setup stays and the account id is deleted from it. Anybody on the site may then save over it or delete it. A setup that holds the short hash instead is not reported, and keeps the hash.
A site holds its fifty most recent setups. One person may have ten of the fifty.
- Past fifty setups, saving another deletes the oldest one the person saving has saved, and the save says which.
- Where none of the fifty is theirs, the save is refused. A setup somebody saved is never deleted to make room for somebody else's.
- Saving an eleventh of one person's deletes their own oldest, and the save says which.
A schedule
For Keep automatically.
- In it: the Atlassian account id of whoever switched it on, so the grid can be read as them while they are not looking. The gadget's saved settings. The day of the week, the 1st of the month or the sprint's close it keeps on, and for the 1st, the date of the first one, as a calendar day. When it was switched on. Which gadget it was switched on from, as the dashboard's and the gadget's ids, so it can follow that gadget's settings. What its last run came to, and when. Where Jira stopped letting the app act as them, when that happened. Where a Jira administrator switched it off, when, and that it was an administrator - not which one.
- Not in it: no name. No time zone either: that is asked of Jira, as the owner, on every run, and once when a monthly one is switched on.
- Lives: until its owner switches it off, or it is deleted after it stops.
- Deleted by: its owner switching it off. A Jira administrator deleting it on the administration page once it has stopped, whether they switched it off or Jira stopped it. Atlassian saying its owner's account is closed. Or uninstalling the app.
| What a last run came to | Also stored |
|---|---|
| Running | - |
| Kept | - |
| Kept without the sprint's name | - |
| Nothing to keep | - |
| Under half the issues of the last grid kept | The two counts |
| Waiting for Jira's hourly allowance | - |
| Failed | The status Jira or storage answered |
Beside it, the schedule keeps one small mark per week, month or sprint it has taken. The mark says when, and what that turn came to.
| A turn that was | Its mark is deleted |
|---|---|
| Put off for Jira | At once |
| Failed | By the platform, after an hour |
| Anything else | By the platform, after ten days, or thirty-five for a month |
The limits:
- A site runs at most twenty schedules, and one person at most three. A stopped one counts towards neither.
- A schedule past either is refused rather than stored. Nothing already stored is deleted to make room.
- A Jira administrator can turn Keep automatically off for the whole site. While it is off, no schedule runs and nobody can switch one on. Nothing is deleted.
- A Jira administrator can switch off one person's schedule, to free a place. For each running schedule the administration page shows them its owner, by the name Jira shows them, the filter's name if they can open that filter, when it keeps, when it was switched on and when it last kept - never its settings, its search or anything it kept. It is kept, stopped, and its owner's gadget says a Jira administrator stopped it. Its owner can switch it on again; nothing it missed while stopped is kept.
- Where Jira will no longer let the app act as its owner, it stops reading. An account deactivated is one such case. It is kept, stopped, so the owner can see why if they come back. Choosing Off deletes it then.
- Changing the gadget's settings moves it to the new settings the next time its owner opens that gadget, with its marks: it is stored under the new settings and no longer under the old ones, and no grid is deleted. A schedule switched on before schedules recorded their gadget is tied to the first gadget its owner opens with the same settings, and follows that gadget from then on. The gadget offers its owner a way to delete schedules under other settings, stopped ones included.
The grids it keeps are kept grids like any other, in that person's history. Each is marked with one word for which schedule kept it. Switched off, the grids it kept stay, like grids kept by hand.
Finished work, as totals
The grid's own totals of the finished work resolved before the current month. They are split by the month, quarter or year it was resolved in. A weekly keep or a render then reads that work again only where Jira says some of it moved.
- Written: without a press, by that person's own reads of a grid and by their schedule's keeps. Held per person: for whoever reads the grid on a dashboard, and for a schedule's owner.
- In it: what a kept grid holds, which is the totals per group and the labels they are under. The name of that person's time zone. Two short hashes, of the filter's JQL and of the board's columns.
- Or, in place of the totals, a mark and when it was written. A mark says there is too little old finished work to be worth keeping, or that the settings name the Rank field. Or it says the totals would not fit, or would not add up. All but the Rank's keep the hashes and the zone beside them. The mark of too little work also keeps the number of issues that read returned.
- Not in it: the issues themselves.
- Key: a hash of that person's account id and the settings.
- Who uses it: only that person's own grids and schedule.
- Never written for somebody not signed in, or for a published grid.
- Lives: each read by that person under those settings replaces it. It is rebuilt from a whole read at least every four weeks. A record not written for thirty-five days is ignored. The platform deletes it after that.
- Deleted by: the platform, thirty-five days after it was last written. Or that person opening a grid with those settings once those days are up. Or uninstalling the app. Switching a schedule off does not delete it.
The list of field names
- In it: the field names that person's own Jira describes to them. It is the same answer Jira would give that person on every render, read once a week instead.
- Not in it: no account id. The key is a hash of one.
- Lives: a week from when it was read from Jira. A week-old record is read again rather than used. Opening the settings form rewrites it. A gadget naming a field the record does not know reads it again.
- Deleted by: the platform, a week after it was read. Or uninstalling the app. Nothing in the gadget deletes it.
The five-minute copy
One thing is written without a press, and used for five minutes: the last grid a person read. Every read of Jira is spent from one hourly allowance. That allowance is shared by every site the app is installed on.
- Written: when somebody signed in to Jira reads a grid to the end, or their read stops at the gadget's ceiling.
- In it: a copy of what the app sent to their screen. That is the same totals, labels and sentences. Two short hashes, of the filter's JQL and of the board's columns. Past the five minutes, when it was last found unchanged.
- Not in it: nothing of the issues behind the grid.
- Not written for a read that stopped short for any other reason, a read stopped at the ceiling that added up time logged in a month, a grid too large to store, or a reader who is not signed in.
- Key: a hash of their account id and the gadget's settings. It is never shown to anybody else: two people can see different issues, so each person's copy is theirs.
- Used: for five minutes, in place of a read of Jira. A reload of that dashboard, or Read again, is answered from the copy. The grid still says when it was read.
- Lives: four weeks from the read it came from, at most.
- Deleted by: that person's next read of the same grid, which deletes or replaces it. A read that stops short for any other reason deletes it too. Otherwise the platform, four weeks after the read.
Past the five minutes, the copy is answered again for five more. That happens only where Jira says in two counts that the search still holds as many issues as the read, and none of them was updated since. For a read the ceiling stopped, that is as many as Jira counted in the search at the time.
It is never answered past the five minutes in these cases:
- a search whose answer can change while no issue does, such as one using now, a relative date such as -1d, or a function such as currentUser();
- the other cases the method lists;
- four weeks after the read.
Crosstab Sprints is copied the same way, under a key of its own. The copy is the bars and sentences it sent to that person's screen. It is used for five minutes and never past them. The platform deletes it after that.
A read that stopped short
One more copy, used for up to an hour: a read that stopped short. A read can stop before the end of the filter. It stops at the gadget's ceiling, at the platform's time limit, or because Jira asked it to slow down. The app then keeps where it stopped and the totals so far. Finish this read can then go on from that page rather than read the same first pages again.
- In it: the running totals per group and the labels they are under. The place in Jira's list to go on from. When the read began, and how many issues it had counted.
- Not in it: not the issues, not their keys, and not the individual values a median would be taken from.
- Not written for a reader who is not signed in, or a read whose totals are too large to store.
- Key: a hash of the person's account id and the gadget's settings. It is only ever continued by that same person under those same settings.
- Used: for an hour from when the read began, and not after. A grid stitched from pages read further apart than that is no longer one picture of the board.
- Lives: a day from the last page read. After the hour it is kept only so that Finish this read can say the read was too old.
- Deleted by: finishing the read. Or that person beginning a new read of the same grid from the first page. Or a press of Finish this read that finds it more than an hour old. That press then reads the grid again from the beginning, and says so. Otherwise the platform, a day after the last page read.
A published grid
Left by Publish this grid for everybody who opens that gadget. There is one per gadget.
- In it: what a kept grid holds. Also when it was published, and the publisher's Atlassian account id. The id tells them apart from everybody else when they take it down. It is also used to ask Jira what to call them when the grid is drawn.
- Not in it: the publisher's name. So the name drawn is the one they have in Jira today. A grid whose publisher Jira no longer knows is drawn without one.
- What it shows: a picture of what the publisher could see. It is read from Jira as them on the press, not taken from their screen. So a reader who opens it sees figures from issues their own permissions may not show them. The name is written over the grid for that reason.
- Lives: until its publisher takes it down or publishes again on the same gadget. Nobody else can publish over it.
- Deleted by: its publisher taking it down or publishing again. Atlassian saying the publisher's account is closed. Or uninstalling the app.
The gadget asks before every publish, except when the publisher's own published grid is the one showing on that gadget.
Only the publisher can replace or take down a published grid. Publishing over somebody else's is refused, and the refusal says who published it and when.
Changing the gadget's settings does not delete it. It is offered only under the settings it was published under.
Publishing is off until a Jira administrator turns it on for the whole site. That is done on the Crosstab page under Apps in Jira's administration. Off, nobody can publish and grids already published are not shown. Nothing is deleted: turning it back on shows them again. Uninstalling the app is what removes them.
The grid carried to a page
For Open at page width, and on a dashboard the count of kept grids and Changes since.
- In it: the gadget's saved settings, which include its filter or the JQL it was set to. Which copy of the gadget it came from, and when. Where the reader came for the list of kept grids, that they did. Where they came for the changes since a kept grid, the moment that grid was kept.
- Not in it: no figures. The page reads Jira again, as the reader.
- Key: a hash of the account id of whoever pressed. One per person.
- Lives: until that person's next press, which replaces it, or a day from the press at most. A day-old one is not used: the page opens as if nothing was pressed.
- Deleted by: that person's next press, which replaces it. Or that person opening the page once the day is up. Otherwise the platform, a day after the press. Or uninstalling the app.
Site-wide records
Four records describe the site, and none of them is about a person.
| Record | In it | Lives |
|---|---|---|
| The site's background allowance, for Keep automatically | How many of Jira's points its schedules have spent in the current hour. Until when they are standing back because Jira refused or warned. Two numbers about the site | Two hours. The platform then deletes both, up to two days late |
| The site's allowance for opened gadgets | How many of Jira's points the gadgets people open have spent this hour, so the site stops at its share. One number for each read, under an id drawn at random for that read that names no person, gadget or filter. Three minutes later it is folded into one number for its minute | Two hours. The platform then deletes it, up to two days late |
| The publishing switch | One setting for the whole site: whether a Jira administrator has turned publishing on | Until an administrator changes it, or the app is uninstalled |
| The Keep automatically switch | One setting for the whole site: whether a Jira administrator has turned Keep automatically off, and the moment it was last turned back on. It does not record who | Until an administrator changes it, or the app is uninstalled |
What the vendor sees
Counts, per minute, and nothing that is in them. The app adds to a handful of counters Atlassian keeps for every Forge app.
| Counter | What it counts |
|---|---|
| Points and issues | How many of Jira's points it spent and how many issues it read, for a render, a publish, the settings form and the background keep |
| Reads and copies | How often a render read Jira. How often it was answered with the grid read in the last five minutes, or with one Jira's counts said had not moved |
| Grids kept and published | How many, by a press or by a schedule. How many a schedule kept again because nothing had moved. How many finished issues a render or a schedule did not read because their totals were kept. How many schedules waited for the hour or kept nothing |
| Jira's allowance | How often Jira said its hourly allowance was running low, and how often a read was cut short because it had run out |
Atlassian files each count under your site. The vendor reads them in Atlassian's developer console, where they are kept for fourteen days. The counters take a number and nothing else. No account id, search, filter, field, name or anything from an issue goes into a counter.
There is also the app's log, kept by Atlassian and read in the same console. A line is written when a read was large or something did not go as planned:
- After a read of a thousand issues or more: how many issues it read and counted, over how many pages and sittings, and what it was planned to cost. Whether and why it stopped short, and how long it took. Whether it read issues' history, and how many fields it asked for.
- When Jira refused a call, or the site's share of the hour was spent: which call it was - the filter, the fields, the search or the sprints - Jira's status code, and how long Jira asked the app to wait. A saved filter is named by its number. Anything else sent in place of the number is written as
invalid. - When a search stopped early or one of its pages failed: why, after how many issues, and Jira's status code.
- When the app's storage did not answer, or a background run could not finish: a fixed phrase saying what was being done, such as "a schedule was not updated", and the status code. Where a record kept changing under a write, the line names its storage key, which is a fixed word or a hash.
- Not in any line: a search, a filter's name, a field's name, an account id, or anything from an issue. Nothing a reader types is written to the log.
| Switch | Turns off |
|---|---|
| Custom metrics access | The counters |
| Logs access | The log |
Your site's administrator can switch both off, where the site's apps are managed. The app works the same with either switched off. The vendor then sees nothing of that site.
Personal data
No axis can be a person. Not assignee, not reporter, not creator, not any user field. This is enforced against the schema of every field your site returns, not against a list of names. So a custom user picker called Reviewers is refused for the same reason Assignee is. So is one that holds several people at once.
The rule enforces the shape of a field. Three things fall outside a shape, and they are set out here rather than left for a reviewer to find.
- A label your organisation chose is text your organisation chose. A component named after a colleague is indistinguishable from any other text. No rule here can tell them apart.
- A select list your organisation wrote is the same case one step further on. A custom Reviewers field whose options are typed-in names is a list of options to any schema, and it can be an axis. The alternative is refusing every custom select list on every site. That is the axis this product exists to offer.
- A search you write is your own words, and a line of JQL can name a person.
reporter = "someone@example.com"is a valid search. It is kept with the grid, because a figure whose population cannot be named is a figure nobody can check. The one place that reaches beyond you is a saved setup, which the whole installation can see. The form says so where the search is typed.
Nothing the app stores names anybody. Three records hold an account id.
| Record | Holds | The name |
|---|---|---|
| A published grid | Its publisher's account id | Read from Jira each time it is drawn, because a figure passed to other people has to say whose view it is |
| A schedule for Keep automatically | The id of whoever switched it on | Not stored |
| A saved setup | The id of whoever saved it | Not stored |
Once a week the app sends Atlassian every account id these three records hold, through the platform's personal data reporting. The report is sent from the app's daily run, which Atlassian starts only on a site with an active licence. On a site without one the ids stay stored and are not reported; the first daily run after the licence returns, once a week has passed since the last report, reports them. Atlassian answers which of those accounts are closed. For a closed account, the app deletes its schedules and takes down the grids it published. Its saved setups stay, with the account id deleted. A report that fails is made again the next day.
Atlassian may also say an account was updated. The app stores only the id, never a name or an email address, so there is nothing to refresh.
The support form
The support page has a form. It is another way to write to support@chmut.com, not a different thing.
- What it sends: the address you type, your name if you type one, and the message. Nothing about you is added to them: not the page that led you to the form, not your IP address. What is kept beside them is the time it arrived and which product's form it came through.
- The check before it sends: Cloudflare Turnstile runs on the support page and on no other page here. It reads signals from the browser and the connection, the IP address among them, to tell a person from a script, and gives the form a token saying which. What Cloudflare does with those signals is set by its own terms for Turnstile.
- The route: the form posts to a Cloudflare Worker at this site's own address. The Worker asks Turnstile whether the token is valid and was issued for this site, passing your IP address along with the token, and nowhere else. It then keeps the message in a Cloudflare D1 database held in the European Union, where support reads it. If it cannot keep it, its log says why and does not name the sender.
- Kept for 30 days, answered or not, and then deleted by a daily sweep. A request to support@chmut.com has it deleted sooner.
- The answer comes from support@chmut.com, whose mailbox is hosted by Apple, on iCloud. From there the exchange is support correspondence like any other, kept as long as that is under Retention.
Sub-processors
| Who | What it does |
|---|---|
| Atlassian | Hosts everything the app does: the code, the storage and the data it reads. Also the counters and log above, which reach the vendor only through Atlassian's developer console |
| Atlassian | Passes the vendor the contact details attached to a paid licence. Your organisation gave them to Atlassian rather than us. This app is paid, so this one applies |
| Cloudflare | Hosts this page and the documentation beside it, as static files on Cloudflare Pages. On the support page it runs the check and keeps the message the form sends for 30 days, in the European Union. For the site and for a message sent through the form, the vendor is the controller; what Cloudflare does with the check's signals is set by its own terms for Turnstile |
| Apple | Hosts the support mailbox, so a message sent to support@chmut.com, and the answer to one sent through the support form, is stored on iCloud. Nothing from your Jira site reaches it |
There is no second processor for the app's data, because there is no second place for anything to be. The pages load no font from a CDN. Besides the support page's check above, Cloudflare Web Analytics is the one thing they load from anywhere else. It is a script the host adds to every page to count visits, with no cookies. It sees the pages and never the gadget. The gadget runs inside Jira and sends nothing here.
Retention
Each record's full lifetime is set out in its own section above. This table is the index.
| Record | Lives until |
|---|---|
| A kept grid | Somebody deletes it, or newer grids crowd it out. Past the fiftieth, one row of its totals stays |
| A saved setup | Somebody deletes it, or newer setups by the person who saved it crowd it out |
| A schedule | Its owner switches it off, a Jira administrator deletes it once it has stopped, or its owner's account is closed |
| Finished work, as totals | The next read replaces it. The platform deletes it thirty-five days after it was last written |
| The list of field names | A week from when it was read from Jira |
| The five-minute copy | That person's next read of the same grid, or four weeks from the read at most |
| A read that stopped short | That person's next read of the same grid, or a day from its last page at most |
| A published grid | Its publisher takes it down or publishes again, or their account is closed |
| The grid carried to a page | That person's next Open at page width, or a day from the press at most |
| Site-wide records | Two hours for the two allowances; the two switches until they are changed |
| The counters the vendor sees | Fourteen days, in Atlassian's console |
| A message sent through the support form | 30 days in the form's database, or sooner on request |
| A message to support | 24 months, or sooner on request |
| The app's storage, once the app is uninstalled | Twenty-eight days. Atlassian then deletes it |
The platform deletes a record once its time is up, on its own schedule. That can be up to two days late. The app does not wait for it: it checks each record's time when it reads it, and never uses one past it.
Earlier versions of the app wrote five of these records with no deadline: finished work, the list of field names, the five-minute copy, a read that stopped short, and the grid carried to a page. The next time the app writes such a record, it writes a deadline with it. A read that finds it past its time deletes it. One that no read reaches again stays until the app's storage is deleted.
Support correspondence is kept long enough to answer a follow-up about the same thing. It is not used for anything else: no marketing, no profiling, no list.
After uninstalling
Once the app is uninstalled, Atlassian keeps its storage for 28 days, then deletes it. The app deletes nothing itself on the way out. Atlassian's Forge storage reference, under Data recovery for apps with hosted storage (developer.atlassian.com/platform/forge/storage-reference), says the storage is kept for 28 days after the app is uninstalled, and that Atlassian can link it to a new installation if asked within 21 days. So if you install it again and write to us within 21 days of uninstalling, your kept grids, saved setups and schedules can come back: Atlassian relinks the old storage when the vendor asks, and the vendor asks only with your consent. Write to support@chmut.com.
Your rights
| Data | Where the request goes |
|---|---|
| The issue data | Your own organisation. It is the controller, and the app holds nothing about you that your Jira site does not already hold |
| A support message | The vendor, who is the controller. Write to the support address above |
Changes
The date this page was last reviewed is at the top. The digest of the exact text is at the foot. So a reader who kept a copy can tell whether they hold the current one. The digest is over the markdown the page is rendered from, which is published beside it. A digest over something nobody outside can hold would be decoration rather than evidence.
The app is listed on the Marketplace, so a reader may have agreed to this edition when they installed it. A change to what is collected, what is kept, how long, or who else sees it takes the next version number, and the edition it replaces stays published with its own digest. A correction that touches none of those moves the review date and the digest, and leaves the version number where it is.
Version 4 adds the support form: what it sends, the check that runs before it does, and the 30 days Cloudflare keeps it for. It also names Apple, which hosted the support mailbox under version 3 as well and was not named there, and says how long a support message is kept, 24 months, where version 3 said only long enough to answer a follow-up. The app has not changed since version 3. Version 3 stays published as privacy-v3.md, with the SHA-256 digest 1518440d9ccb98cbfb5e4c595ac75e0d876fe96642902b4b585465c7e241a93a.
This edition
The file below is the authoritative text. This page renders it and adds navigation and this block, so the page and the file are not byte-identical — it is the file that governs, and the digest is over the file.
Version 4 — privacy.md, 59 KB
9ef372ecccadffcc98e647d44cfa232728620d720bc542cb3ef28867a52554b7
Check it with shasum -a 256 privacy.md once the file is downloaded, which prints the digest above and nothing to compare by eye. On Windows, Get-FileHash privacy.md -Algorithm SHA256 in PowerShell, which prints in capitals — the comparison is case-insensitive. The digest is published by us: it shows the file has not drifted or been altered in transit, and it is not a third-party attestation.