Documentation / Kanban+

Automation

Last updated: 6 September 2026

Automation rules react to what happens to your issues: a card entering a column, a new issue appearing, a field changing, a card overstaying its column's time limit. Each rule is a trigger, a set of conditions, and a list of actions.

Rules belong to a board and are edited in Settings → Automation Rules by that board's administrators (or a Jira site admin).

Where rules run

This matters more than it sounds, so it's worth stating plainly. Two things run rules today: the board you have open, and the hourly SLA checker.

In the board, while it's open. When you drag a card between columns, or create an issue from a column's quick-create form, the board evaluates that board's enabled column_enter and issue_created rules straight away and reports the result in its banner. This is the engine that handles everyday work, and it only runs for actions taken inside Kanban+, in a browser tab somebody has open.

The hourly SLA checker. A background job wakes once an hour, finds every board with at least one enabled sla_breach rule, and runs those rules against issues that have overstayed a column's threshold. Nobody has to be watching. See SLA tracking.

The Jira event listener does not currently reach any board. The app subscribes to jira:issue_updated and jira:issue_created, and the server-side engine behind that subscription is written and tested. But the step that works out which boards an incoming issue belongs to compares the issue's project key against the numeric project ids a board stores, and those two never match — so the engine finds no boards and runs nothing. This is a bug, and it is ours to fix. Until it is fixed:

  • Changes made outside Kanban+ trigger no rules. Editing an issue in native Jira, in the backlog, from a REST client or from another app does nothing to your rules.
  • field_changed rules never fire. The event listener is their only engine.
  • column_enter and issue_created rules fire once, in the board — not twice. If you have written rules defensively to survive a double run, that precaution costs you nothing today and will matter again once the listener works.
  • When it does work, it will run only verified rules. The listener has never executed a rule for any board, so — unlike the hourly checker — it does not carry older boards forward on trust. See Permissions below.

The status-entry timestamps that SLA tracking depends on are written by a different listener, which is unaffected and working. That is why the hourly checker still has data to run on.

On a schedule. Besides the hourly checker, three jobs run once a day: a snapshot job, a cross-board dependency scan and a retention prune.

Rules run by the hourly SLA checker act as the app, not as you. Rules that run in the board act as you. Either way the change appears in Jira's own history. Because the app acts on its own authority in the background, it first has to know that a person was entitled to ask for that — which is the next section.

Permissions: verified when you save, enforced when rules run

The background engines have no user session, so the app cannot ask Jira "may this person do this?" at the moment a rule fires. It asks earlier, when the board is saved, and it asks about the person saving.

Whenever a board administrator saves the board's projects, its filter JQL, its columns or its automation rules, Kanban+ works out which Jira permissions the enabled rules need — browse for every board; assign, edit (priority, labels, due date), comment, transition or create (sub-tasks) depending on the actions — and checks, through Jira's own permissions API and using the saving administrator's permissions, that they hold each of them in every project the board covers. It also test-runs the board's filter JQL as that administrator. If anything is missing, the save is refused with a message naming the project, the permission and the rule, and nothing is stored. If it all passes, the board is stamped: who verified, when, which projects, which permissions.

When a background engine is about to act, it reads that stamp and acts only if it still covers the board's current projects and the rule's current actions. Anything else is skipped and written to the audit log as such — the row is marked unverified and every action shows as skipped. So a rule can never make the app do, in a project, something the administrator who saved it could not have done themselves.

Three consequences worth knowing:

  • Rules that change issues need a project scope. A board scoped only by a custom JQL filter, with no projects, cannot be verified — there is no project to check permissions against — so such a board refuses to save a rule that changes issues. Add a project first.
  • The saving administrator's permissions are what count. If a colleague created a rule that assigns issues and you, lacking Assign issues in one of the board's projects, later re-save the columns, the save is refused until you gain the permission or the rule is removed. This is deliberate: every save re-verifies the whole board as the person saving it.
  • Boards saved before this check existed show an "Unverified" notice above their rules, and each rule that changes issues carries an Unverified tag. The hourly SLA checker and the daily scans keep running those boards as before, with one exception: a board that has no project in its scope (a filter JQL only) is paused, and its audit log says so once a day per rule, until a project is added. The Jira event listener, when it runs, will only run verified rules. Click Verify now in the notice (or save projects, filter, columns or rules) to verify — it re-checks the stored configuration as you, without changing it.

Disabled rules are not counted when a board is verified; enabling one is itself a save of the rules, which re-verifies.

What a rule looks like

Rules are built in the UI, but the shape they're stored in explains the vocabulary:

json

{
  "id": "…",
  "name": "Auto-label urgent bugs",
  "enabled": true,
  "trigger": { "type": "column_enter", "columnId": "<board column id>" },
  "conditions": [ { "field": "priority", "op": "is", "value": "Highest" } ],
  "actions":    [ { "type": "add_label", "label": "needs-review" } ]
}

Read as: WHEN the trigger fires, IF every condition passes, DO each action in order.

Triggers

There are four.

TriggerYou also pickFires whenRun by
Issue enters columna board columnyou move a card into that column inside Kanban+the board, while it's open
Issue is createdyou create an issue from a column's quick-create formthe board, while it's open
Field changesa Jira field name, e.g. assignee, priority, statusthat field appears in the update's changelogthe Jira event listener — which does not currently run
SLA threshold breacheda column, and at limit or at warningthe hourly scan finds an issue past that column's thresholdthe hourly SLA checker

Notes on Field changes: this trigger has no working engine today — see Where rules run above. When it does run, the field name is matched as a plain, case-sensitive string against Jira's changelog: assignee works; Assignee does not.

Notes on SLA threshold breached: the thresholds themselves are set on the column, in the Board tab's column editor — not in Settings. The trigger's at limit / at warning choice selects which of the two to test.

Conditions

Every condition must pass. A rule with no conditions always fires — the editor says so above the list.

FieldOperatorsMatches against
typeis, is notIssue type name
priorityis, is notPriority name
statusis, is notStatus name
assigneeis, is not, is unassignedDisplay name; an empty value means unassigned
labelcontains, does not contain, is emptyEach label, as a substring
summarycontains, does not containSummary text, as a substring
reporteris, is notDisplay name
is_blockedis blocked by (active), is not blockedAt least one open "is blocked by" link
has_open_blockersis, is notIdentical to is_blocked — it's an alias
is_blockingis blocking (active), is not blocking anythingAt least one open outward "blocks" link

Comparisons are case-insensitive.

Two behaviours worth knowing:

  • An unrecognised field or operator passes. That's deliberate — a rule saved by a future version degrades toward firing rather than silently doing nothing. The side effect is that a typo in a condition makes a rule fire more broadly, not less. Use the preview.
  • Server-side blocker conditions see direct blockers only. The board's own blocked badges follow chains transitively; the server-side engines — the hourly SLA checker, and the event listener when it works — look one hop out.

Actions

Eight, executed in the order you list them. One failing action is recorded and the rest still run.

ActionYou supplyWhat happens
Assign toa user, or nobodySets or clears the assignee
Set priorityHighest, High, Medium, Low or LowestSets the priority by name
Set due date+N, -N, or YYYY-MM-DDSets the due date
Add labela labelNo-op if it's already there
Remove labela labelNo-op if it isn't there
Move to statusa status nameLooks up a matching transition available from the issue's current state and applies it
Create subtaska summaryCreates a sub-task in the issue's project
Post commenttextPosts the text as a comment

The details that bite

Set due date has a strict grammar. Only two forms are accepted: a signed relative day count, or an ISO date.

+7
-3
2026-12-31

Anything else — +7d, next week, 2026-1-5 — is silently ignored, and the due date is left alone. The field's helper text says the same thing, but it's a quiet failure — nothing tells you afterwards.

Move to status can skip. Jira transitions are workflow-specific. If the status you named isn't reachable from the issue's current state, the action logs a warning and moves on. Nothing is applied and nothing errors loudly.

Create subtask needs a sub-task issue type. If the project has none, the action is skipped.

Comment text is not templated. This is the one that catches people. Placeholders like {{issueKey}} or {{summary}} are not substituted — the comment posts exactly the characters you typed, braces included. Write comments that read correctly as fixed text.

Actions that no longer exist

Earlier builds could post to Slack, post to Microsoft Teams, and call an outgoing webhook. All three were removed so the app makes no network calls outside Atlassian. Blocker escalation was changed for the same reason and now posts Jira comments instead of notifying an external service.

If a rule was saved with one of the removed action types, it is skipped without an error. If you're carrying rules forward from an old build, open them and check for actions that appear to do nothing.

Preview before you enable

Every rule has a 🔍 Preview button. It fetches up to 200 issues from the board's scope and shows which ones the rule's conditions match, using the same evaluator the server uses — the client and server condition logic are deliberately kept identical, so what you see is what will fire.

Preview evaluates conditions. It does not execute the actions.

Audit log

Only the server-side engines write to the log. A rule run by the hourly SLA checker, or by the event listener once it works, is recorded on the board: timestamp, rule id and name, trigger type, issue key, each action and whether it succeeded, and how long the run took. Open it in Settings → Automation Audit Log.

Runs the app declined are logged too. When an engine skips a rule because the board's permissions were not verified (see Permissions above), the entry is flagged skipped · unverified, every action shows as skipped, and hovering the row tells you why. The hourly checker writes one such entry per rule per day rather than one per hour. The daily snapshot and the daily cross-board scan write an entry of their own kind (daily snapshot, dependency scan) when they skip a board. Entries for rules that ran on a board saved before verification existed are marked legacy.

Rules that run in the board write nothing here. Their results appear in the board's banner at the moment they run and are not kept anywhere. Since the event listener currently matches no boards, in practice the log receives sla_breach entries and nothing else.

Four more things to know:

  • It keeps the last 100 entries per board. Older entries fall off.
  • Concurrent runs can lose an entry. The log is stored as a single record that's read, appended to, and written back — two triggers landing at the same instant can produce one entry instead of two. Actions still run; only the record is lossy.
  • Anyone who can open the Kanban+ page can read it, board administrator or not. It contains rule names — which admins write freely, and which often carry a person's name — and issue keys.
  • Board and site admins can clear it.

Limits

  • There is no loop protection and no rate limit. Nothing in the app notices a rule whose actions re-trigger another rule, or itself. Today a chain can't start on its own, because the only engines are your own click and an hourly job — but the guard doesn't exist, so sketch the chain before you rely on rules that write fields other rules watch.
  • No per-issue cooldown, except for sla_breach triggers, which hold a 24-hour cooldown per rule per issue.
  • Rules are per board, and boards are visible site-wide, so a rule you add affects every issue in that board's project scope — not only issues someone is looking at.
  • Automation writes from the hourly checker are made by the app, so Jira history attributes them to the app rather than a person — but only within the permissions the saving administrator was verified to hold (see Permissions).

Related