oc Outlier Crosstab Narrow tools for Jira
Outlieran product Install

Security — Outlier

A security policy for an app with no servers is a short document, and pretending otherwise would be the first thing wrong with it. Outlier runs entirely inside Atlassian's platform. There is no backend, database or network of ours. There is nothing to breach that is not Atlassian's own infrastructure.

This page is about how the app is built and operated. The one source for what is read, stored and kept, and for how long, is the privacy policy. The whole arithmetic is on the method page.

Last reviewed: 2026-10-06.

At a glance

The questionThe short answer
Where it runsInside Atlassian's platform. No backend, database or network of ours
What you can check firstThe manifest, on the consent screen. Below
Where the data livesForge storage on your site, and nowhere else. PINNED data residency
What is read and keptThe privacy policy is the one source
Whose permissionsThe person looking, for every read a person or their rule triggers. The app's own reads are four, named
What it may ask Jira forGranular read scopes and storage:app. Why some look wrong
What the vendor seesApplication logs: counts, names of fields, the ids of a card or board, and the path of a failed request to Jira. Below
What can leave your siteNothing the app sends. Two features let you send something out
Before it shipsTwo gates that fail the build, two steps done by hand
A vulnerabilitysupport@chmut.com or Atlassian; a critical one fixed within 10 days
Who stands behind itOne person. What that means

What you can verify without trusting us

Most security claims about an app have to be taken on faith, because the source is not public. One does not, and it is the one that matters most.

WhatWhere to check itWhat it shows
The Forge manifestThe consent screenNo external host, no egress domain, no Forge remote, no web trigger
Its one relaxationThe same manifestcontent.styles: unsafe-inline, and nothing that loosens scripts or connects
Runs on AtlassianAtlassian's own badge, on the listingAtlassian-hosted compute and storage, measured rather than asked

The manifest

Atlassian shows it to you on the consent screen. It either declares an external host, an egress domain or a Forge remote, or it does not. Outlier declares none of them, and no web trigger. No public endpoint of ours exists to be called.

That is not a promise about our intentions. It is a property the platform enforces, and you can read it before you click install.

The one relaxation

The manifest declares one relaxation, and it is better read here than discovered there: content.styles: unsafe-inline. It permits the inline styles React writes inside the app's own iframe. It does not loosen what scripts may run or what the page may connect to.

Runs on Atlassian

Atlassian's Runs on Atlassian badge certifies a narrower thing than it sounds like. Outlier carries it, under Trust signals on the listing.

Everything else on this page is a claim about work we do. It is written to be specific enough to be argued with.

Where the data lives

Forge storage, and nowhere else.

QuestionAnswer
Which realmYour site's. Storage follows it automatically
Data residency statusPINNED, without any configuration on your part
Shared between customersNo. Storage belongs to your installation; nothing is shared between one site and another
Where an invocation runsAtlassian's to decide. Forge may occasionally run one elsewhere, always inside Atlassian

Storage residency and compute location are not the same guarantee, and a review will ask. Atlassian's own documentation says Forge may occasionally execute an invocation from a location other than the host product's. So the data resides where your site does, while an invocation may sometimes run elsewhere. Nothing leaves Atlassian, so what could run elsewhere is Atlassian's infrastructure rather than a vendor's.

What is read, and what is kept

What the app reads, what it keeps and for how long is set out once, in the privacy policy: what the app reads and what the app stores. This section lists the controls that hold those facts true.

ControlWhat it does
One boundary for both readsThe text and the names a changelog carries are dropped in the one function both read paths share, before anything is derived and before anything is written
A guard on every writeA field named for a person is refused by name, at any depth
Deletion on uninstallA preUninstall handler deletes the app's own rows, the most revealing first

Jira's changelog endpoint takes no field filter, so that text and those names do arrive, and are dropped at that boundary. What is used and what is dropped is set out in full in the privacy policy.

The guard reads names, not values

There is no field named for a person anywhere in the schema. Every write is refused by name, at any depth, if one appears. The guard reads field names rather than values. That is why the claim is about what the app asks for, and not only about what the guard catches.

Deletion has a deadline

The preUninstall handler deletes the app's rows rather than leaving them to the twenty-eight days Forge would otherwise hold them. It has a deadline it may not meet.

"We deleted everything" and "we deleted what we could in the time we were given" are different claims. Only the second can be made honestly by a function with a budget.

An administrator has no button for deleting one card's data on its own. What exists is uninstalling, and the app's own forgetting of a board nothing reads. The privacy policy gives both clocks.

Whose eyes the data is read with

Every read of Jira that a person or their Automation rule triggers is made as that person.

ReadMade as
The card, the configuration screens and the admin pageYou
The Automation stepThe person whose rule it is
The hourly collection, which has no user to act asThe app
The one-off walk of a board's history, when a card is first configuredThe app, for the same reason
After a board is forgotten, which tickets the boards left still holdThe app, for the same reason
The inventory of cards this installation holdsThe app. The one exception

The app reads as itself in four places: the hourly collection, the one-off walk, the check after a board is forgotten, and the inventory of cards. The first three have no user to act as. The fourth has no board to check against, and is the one exception.

Everywhere else, before stored data is shown to anyone, the app asks Jira for the board's configuration as the reader. A refusal becomes a named "you cannot see this board" state rather than a number.

The one exception

There is one exception, and naming it is cheaper than having it found. The inventory of cards this installation holds is read as the app. The question, which cards exist here, has no board to check against.

The scopes that look wrong

The app asks for granular scopes rather than the single classic read:jira-work scope. The list is longer to read, and that is the point: the classic scope would grant comments, attachments and worklogs the app never touches.

A few entries look wrong for a product that reads nothing about people: read:user, read:group, read:avatar, read:audit-log. Jira requires each endpoint's scopes as a complete set, and four endpoints between them account for every entry that looks wrong.

EndpointScopes in its setThe entries that look wrong
Reading one field of a saved filternineread:user and read:group among them
Searching the work in flightfiveread:audit-log, one of them
Counting the same searchA different set from the search'sread:field, read:field.default-value and read:field.option, none of which the search itself asks for
Asking a board how its columns are arranged-read:board-scope.admin, the only scope Atlassian publishes for that endpoint

The app reads no user, no group, no avatar and no audit log, administers no board, and writes nothing anywhere.

What is checked before anything ships

Two of these are gates that fail the build. Two are steps somebody performs, and they are marked as such. A check somebody remembers to run is not a control, and calling it one would be the same overstatement this page is trying to avoid.

CheckKindDetail
Dependencies are scanned with npm audit on every merge to main and again on every release: everything the gadget installs, and the app's production dependencies. The app's build tools, which never ship, are not scannedGateThe build fails at moderate severity or above, and a release that fails it offers no deploy. npm run check runs the same audit first, before every push
The manifest's scopes are held to what the app's endpoints acceptGateIn both directions: an endpoint missing a scope fails, and so does a scope no endpoint needs. The build also holds every read a person triggers to the acting user
The vendored scope table is re-checked against Atlassian's published API descriptionsStepBy hand, before scopes are changed, the only time its answer matters
The built bundles are read before a release, not only the sourceStepNo network call of ours, no markup built from strings, no eval

The scope check and the acting-user check were both verified by mutation: deliberately breaking them to confirm the build goes red. A green test is not evidence that a test catches anything.

What the vendor can see

Application logs, and nothing else.

LogsWhat that covers
CarryCounts, durations, the shapes of endpoints called and the names of fields
Never carryTicket content, a query or a person
IdsTen of the app's thirty-three logging statements print a card's id or its board id
A failed requestLogged with the path it asked, ids included

What can leave your site, and who decides

The app sends nothing out of Atlassian. Two features let you send something out, and both are yours to switch on.

FeatureWho switches it onWhere it goes
The Automation stepWhoever writes the ruleWherever that rule sends it, with that rule's credentials
Ask Rovo whySomebody pressing it, where your site has RovoYour Rovo, in your instance, on your credits

The Automation step

The app can answer an Automation rule with this morning's text. What the rule then does with it is the rule's business. If it posts to Slack through a "Send web request" action, that is your rule, your schedule, your channel and your credentials. The app has no destination of its own. It cannot acquire one without a new manifest you would have to consent to.

Ask Rovo why

A button that hands the card's own text to your Rovo, in your instance and on your credits, when somebody presses it; this app deploys no model and calls none. What the question holds and where the answer goes are listed in the privacy policy.

Who can deploy, and what stops them

A Forge deploy reaches every installation with no action by you. That makes a deploy the fastest way to contain an incident, and the deploy credential the most valuable thing to steal.

Every deploy runs in Bitbucket Pipelines, as bitbucket-pipelines.yml in the repository declares it, and only from a release tag.

WhatHow
A releaseA v tag, which the "Tag a release" step cuts from main after the checks there pass. Whatever commit a tag names, the pipeline runs both checks on it again before it offers a deploy
Development, and these pagesDeployed from the tag, each by a step somebody starts
ProductionOnly after development and the sites have deployed the same commit. Every production deploy becomes a new version of the Marketplace listing
Any branch or pull requestNothing deploys
The deploy credentialsSecured variables in Bitbucket, never in the repository. Each belongs to the deployment that uses it, so only that step can read it
The steps that build and testHold no credentials at all
Rolling backRedeploy of the previous release, from Bitbucket's deployment history. The step rebuilds from that release's own commit
What the deploy steps do not run

Each deploy step installs its dependencies with lifecycle scripts disabled, both the app's and the tools'. Running arbitrary install code in the one environment holding a deploy token is the risk that flag exists for.

The Forge CLI and the tool that deploys these pages are pinned to one version each, so a major release cannot change what deploys on the day it ships.

The repository has one account with write access, the vendor's. On this Bitbucket plan a deployment cannot be tied to a branch or a tag by a setting. The pipeline file does that, and only that account can change it.

The vendor's machine keeps an Atlassian token of its own, because reading the app's logs and upgrading an installation need one. It could deploy, but is not used for that.

Reporting a vulnerability

Write to support@chmut.com. Say what you found and how to reproduce it. You do not need a proof of concept for us to take it seriously.

You will get a human reply within 48 hours, on the same working days as any other message to support. That is a commitment about acknowledgement rather than about a fix.

You can also report it to Atlassian. They raise it in their Marketplace Security project, where it arrives with a remediation due date. Either route reaches the same person.

The app is held to these timeframes. They are Atlassian's rather than ours.

SeverityCVSSFixed within
Critical9.0 and above10 days
High7.0 to 8.94 weeks
Medium4.0 to 6.912 weeks
Lowbelow 4.025 weeks

If there is an incident

A documented response plan exists. It is kept with the code rather than in somebody's head. Its commitments, in order of the clock:

WhenWhat happens
Within 24 hours of becoming awareAtlassian is notified, as a P1
At least every six hours, while it is openUpdates go to Atlassian
Within 72 hours of identificationAffected customers are notified

Containment here is unusually direct. A Forge deploy reaches every installation without any action by you. So rolling back to the last good revision is both the fastest response available and a complete one. There is no upgrade for an administrator to apply, and no site left behind on a broken build.

What this page does not claim

A short list, because a security page that only lists strengths is a marketing page.

This page does not claimWhat is true instead
A teamOutlier is built and maintained by one person
Someone watchingThere is no rota, no around-the-clock monitoring and nothing watching the logs for anomalies
Review of a changeThere is no second pair of eyes on a change
DetectionDiscovery of a problem would come from a customer, from Atlassian, or from looking
A rehearsed incident planThe incident response plan is written and has never been exercised
CertificationThe app holds no compliance certifications
External testingIt has not been penetration-tested by an external vendor, and does not run a bug bounty programme
Code scanningDependency scanning is the only automated security scanning in the build. There is no static analysis and no dynamic testing
A year of logsApplication logs live on Atlassian's retention schedule rather than a year of our own. That would make a late-discovered incident harder to reconstruct

None of that is a reason to distrust the app. It is the shape of a small product, and you are entitled to know it before you install one.