Version 1.2.2
Released: May 16, 2026
Marketplace Version: 5.2.0
Maintenance release that updates how the BSO custom fields
(BSO - Approvers and BSO - Status) are
declared and managed by the app. After this update, both fields
are app-managed and locked, preventing accidental modification
or deletion from Jira’s Fields admin UI, and they are now
provisioned automatically on every install with no manual setup
required.
Enhancements
Locked, App-Managed BSO Custom Fields (BSOA-24)
-
The
BSO - Approvers and
BSO - Status custom fields are now declared as
app-managed Forge custom fields. Both fields appear in the
Jira Fields admin UI with a LOCKED indicator, and the Edit
and Delete options are no longer available on them —
preventing accidental modification or deletion that would
disconnect the live plugin state from existing approval data
on issues
-
Both fields are now provisioned automatically when the app
is installed on a Jira site. No admin action is required to
add them, and they are immediately available for use in JQL
filters, issue navigator column display, dashboards, and the
Business Sign-off panel
-
Existing tenants where the BSO fields were previously
created keep their same field identifiers and field
values — the upgrade reclassifies the existing fields
as app-managed without any data migration or admin action
required
-
No user action required — the change takes effect
automatically on upgrade
Code Quality
-
Retired the original
setupCustomFieldContexts
startup helper that ensured a global context on the BSO
fields — this responsibility is now handled by the
Forge platform via the app-managed custom field declaration,
and the equivalent code is no longer needed
-
Added a pre-release verification step that detects any
changes to the app’s manifest permissions block
between releases, surfacing the result in
reports/pre-release-x.y.z/scopes-diff.txt
— gives the release engineer advance notice if a
future release would prompt installed customers to
re-approve permissions
-
Added a
reset:staging-dev npm script that
uninstalls, redeploys, and reinstalls the app on a
designated cold-install verification tenant in a single
command — supports a release checklist step for
catching install-path regressions on a fresh tenant
Test Coverage
-
Backend + frontend test suites green; all checks pass:
TypeScript (backend + frontend), ESLint, Prettier, Vitest,
Forge manifest lint
-
npm audit: clean (root + frontend)
- SonarQube Quality Gate: Passed
-
New manifest scope-change check confirms no new OAuth scopes
or permissions are introduced in this release —
upgrade is silent on installed tenants, no re-approval
prompt
Version 1.2.1
Released: May 16, 2026
Marketplace Version: 5.1.0
Maintenance release focused on performance and reliability.
Panel and dashboard-gadget loads are faster for issues and
accounts with many approvers; the weekly GDPR personal-data
report now runs correctly; and log noise from expected
control-flow conditions has been reduced.
Enhancements
Faster Panel & Gadget Loads for Large Approver Lists
(BSOA-11, BSOA-21)
-
The Business Sign-off panel and both dashboard gadgets
(“My Approval Queue” and “My Approval
Requests”) now load noticeably faster for issues,
projects, and users with large approver lists
-
Workflow post-function “Add Approvers” —
when configured to add a large project role or group
— completes in a fraction of the time previously
required, especially for transitions that add 15+ approvers
at once
-
Gadget auto-refresh is gentler on the platform for power
users who are approvers on many issues, reducing the chance
of intermittent load failures under heavy use
-
Internal cleanup consolidated duplicated approver-loading
logic so all approver-list reads share a single,
well-tested code path
Bug Fixes
GDPR Personal Data Report — Endpoint Routing (BSOA-22)
-
Fixed: The weekly scheduled Personal Data
Report job was failing with an
INVALID_TARGET_URL error, preventing the
report from being delivered to Atlassian’s Personal
Data Reporting service
-
Migrated the report submission to Forge’s official
Privacy API, which handles endpoint routing and request
batching natively
-
GDPR compliance reporting now runs reliably on its weekly
schedule
-
No customer action required — the next scheduled run
after upgrade will complete successfully
Log Hygiene — Issue Panel on Deleted or Inaccessible
Issues (BSOA-23)
-
Fixed: Error-level log entries appeared
when the issue panel attempted to load for a deleted issue
or one the app no longer had permission to read
-
404 responses from Jira are now treated as expected control
flow — the panel simply doesn’t render, with no
error logged
-
Non-404 errors continue to log and surface as before
-
Mirrors the same log-hygiene pattern applied to the
field-sync handler in Rel 1.0.1, closing the equivalent gap
on the panel resolver path
Code Quality
-
Added a shared batched-read helper in the storage service
layer; new unit tests cover empty input, single batch,
batch boundaries, multiple batches, and result-ordering
preservation
-
Refactored
addApproversToStorage (workflow
post-function path) to read the issue index once, write
approver records in parallel batches, and write the index
once — with partial-failure isolation so a single
failed write doesn’t block the rest
-
Consolidated a duplicate approver-loading function inside
the “My Approval Requests” gadget resolver,
replacing it with a call to the canonical service function
(which now inherits the batched-read behavior)
-
Added focused test coverage for the custom-field-sync
service: error paths for field-key resolution failures,
non-OK PUT responses, and diagnostic logging —
bringing service-level branch coverage above the 80% gate
threshold
Test Coverage
-
Backend + frontend test suites green; all checks pass:
TypeScript (backend + frontend), ESLint, Prettier, Vitest,
Forge manifest lint
-
npm audit: 0 vulnerabilities (root + frontend)
-
SonarQube Quality Gate: Passed — Security A,
Reliability A, Maintainability A, 81.3% coverage, 0
security hotspots
Version 1.2.0
Released: May 11, 2026
Marketplace Version: 5.0.0
Enhancement release that closes a long-standing UX gap: the
Business Sign-off panel header is now hidden entirely on
projects where the plugin is disabled, instead of showing an
empty entry in every issue’s sidebar. The change is
platform-wide and applies uniformly to Jira Software, Jira
Service Management, Jira Work Management, and Jira Product
Discovery.
Enhancements
Hide Panel Header When Disabled (BSOA-20)
-
The Business Sign-off panel (header, icon, chevron, and
body) is now fully hidden on projects where the plugin is
disabled — no more empty “Business
Sign-off” entry on every issue in projects that
don’t use sign-off
-
Visibility is evaluated by Jira server-side via a Forge
manifest
displayConditions block, so the panel
never mounts and main-resolver never executes
for disabled projects — saving invocation cost on top
of the UX improvement
-
Works uniformly on Jira Software, Jira Service Management,
Jira Work Management, and Jira Product Discovery —
any project type where
jira:issueContext would
otherwise render
-
Finishing mode is honored — projects
in finishing mode keep the panel visible so in-flight
approvers can complete their decisions; the existing
in-panel status messages handle “no approvers /
finishing” and “issue type not eligible”
cases as before
-
Resolves the v1.0.0 “Known Limitation: Panel
visibility on disabled projects” item
How it works
-
A new Jira project entity property
bso-panel-visible is the source of truth for
the manifest’s display condition
(project.properties['bso-panel-visible'] ==
true)
-
The property is computed from the project’s effective
config:
panelVisible = effective.enabled ||
effective.finishingMode
-
The property is synced automatically:
-
After every successful project-config save
(
updateProjectConfig)
-
After every successful project-config delete
(
deleteProjectConfig)
-
After every global-config save that changes
enabled or finishingMode
— fanned out across all stored project configs in
parallel
-
On project-deleted events (best-effort cleanup
alongside the existing config delete)
-
Property writes are fail-safe: a Jira API
failure logs and returns rather than throwing, so a flaky
property write cannot break the upstream config save
-
Defense in depth: the existing
visible: false status-message path in the
getIssuePanelData resolver is preserved
— a motivated user calling the resolver directly via
dev tools still gets the same “plugin disabled for
this project” response
Required Permissions
This release adds two new granular OAuth scopes that the
project-properties endpoint requires (the classic
write:jira-work scope does not cover this
endpoint):
write:project.property:jira
delete:project.property:jira
When customers upgrade,
Atlassian will prompt site admins to approve the new
permissions
before the upgrade applies. The app cannot write
bso-panel-visible (and therefore cannot hide the
panel) until consent is granted.
Upgrade Notes
One-time backfill required on existing installations.
When this release applies to an existing site, projects that
were previously enabled will lose their panel on the
next issue load — because the
bso-panel-visible property has not yet been
written for those projects. The property is written
automatically the next time an admin saves the project’s
BSO settings.
Recovery is trivial: for each enabled
project, open Project Settings → Business Sign-off
→ click Save. Each save writes the property and the
panel reappears on the next issue load. No data is lost;
this is purely cosmetic state.
Alternatively, a Jira admin can PUT the property directly via
REST for known projects:
PUT /rest/api/3/project/{projectIdOrKey}/properties/bso-panel-visible
Body: true
Already-open issue tabs will pick up the visibility change on
their next refresh — displayConditions is
evaluated by Jira on page load, not live.
Code Quality
-
New service
src/services/panel-visibility-property.ts
— encapsulates the property-write/delete and the
effective.enabled || effective.finishingMode
derivation; 15 dedicated unit tests covering the pure
compute function, sync success and failure paths, and
delete-treats-404-as-success semantics
-
Existing tests (
project-config.test.ts,
global-config.test.ts,
project-deleted.test.ts) updated to assert the
new side-effects: per-save sync, fan-out only on relevant
global-config field changes, project-delete property
cleanup
-
Plan + AI-prompt documentation captured at
docs/features/Rel 1.2.0/BSOA-20-Hide-Panel-Header-When-Disabled-Plan.md
with the implementation findings (correct
jiraExpression form for
jira:issueContext and raw-boolean PUT body
shape) preserved as in-line corrections for future
implementers
-
Admin UI help text added under both the global and
per-project “Enabled” toggles explaining the
“applies on next issue load” refresh behavior,
internationalized via
locales/en-US.json
-
New backlog plan captured at
docs/features/backlog/Frontend-Test-Suite-Noise-Cleanup-Plan.md
documenting stderr noise from third-party libraries
observed during the verification pass (no functional
impact; tracked for a future hygiene pass)
Test Coverage
-
1,180 backend tests + 143 frontend tests (1,323 total)
— added 24 new tests
-
All checks pass: TypeScript (backend + frontend), ESLint,
Prettier, Vitest, Forge manifest lint
-
SonarQube Quality Gate: Passed — 0 new code smells,
coverage on new code increased the overall project
coverage by ~1%
Version 1.1.0
Released: May 9, 2026
Marketplace Version: 4.7.0
Feature release introducing two Jira dashboard gadgets that give
users at-a-glance visibility into their open approval work
— one for approvers (“My Approval Queue”) and
one for requestors (“My Approval Requests”). Also
includes a responsive-design fix for the issue panel in narrow
column views.
New Features
My Approval Queue Dashboard Gadget (BSOA-4)
-
New Jira dashboard gadget surfaces open issues where the user
is currently an approver
-
Configurable approver-status filter: Added, Pending, Approved,
Returned, or All
- Optional per-project filter (or All projects)
-
Configurable display page size: 10, 25, 50, or All
-
Optional auto-refresh interval: Never, 15 minutes, 30 minutes,
1 hour, 2 hours
-
Columns: Type, Key, Summary, Issue Status, My Decision,
Decided (X of Y approvers), Days in current status
-
Help tooltip on the gadget directs users to JQL with the BSO
custom fields for closed-issue or historical reporting
-
Cancel button on the configuration form lets users exit
without saving changes
-
Per-account index
(
bsf:account-issues:{accountId}) backs the
lookup so the gadget always sees every issue the user is/was
an approver on
My Approval Requests Dashboard Gadget (BSOA-5)
-
New Jira dashboard gadget surfaces open issues the user
submitted (reporter or assignee) that have approvers
attached
-
Configurable user axis: Reporter, Assignee, or Either
-
Configurable approval-state filter: Open (Not Started +
Awaiting Decisions), Returned, Approved, or All
- Optional per-project filter (or All projects)
-
Configurable display page size: 10, 25, 50, 100, or All
-
Optional auto-refresh interval: Never, 5 minutes, 15 minutes
-
Columns: Type, Key, Summary, Issue Status, BSO Status,
Decided (X of Y approvers), Days in current status
-
Expandable rows show each approver’s status, decision
date, and days waiting; click the issue key to view full
decision comments in context
-
Issues without any approvers attached are hidden — they
aren’t approval requests
-
Truncation banner appears when the user has more than 500
in-progress issues that match the JQL; the banner directs
users to refine filters
Gadget Configuration Persistence
-
Both gadgets persist their configuration to Forge Storage
keyed by the dashboard gadget’s
localId,
so settings survive dashboard reloads, browser sessions, and
plugin redeploys
-
Configuration form initializes from the persisted values on
edit; defaults fill in only on first configure
Bug Fixes
This release tightens the BSO approval panel’s visual
fidelity: it now reflows correctly in narrow detail columns,
and it surfaces eligibility conflicts on previously-decided
approvers. Backend approval logic, data integrity, and
security guards are unchanged — these fixes close
visual gaps where the panel didn’t fully communicate
backend state.
BSO Panel — Narrow-Column Responsiveness (BSOA-14)
-
Fixed: BSO approval panel content overflowed
the right edge of its container when rendered in narrow Jira
issue detail columns (e.g., resized browser windows,
side-detail slide-out views)
-
The “Add Approver” button, per-approver action
buttons (Remove, Re-notify), and footer buttons (Audit
History, Notify Approvers) were clipped or pushed off-screen
-
Added
shouldWrap to the affected
Inline rows in
src/panel/index.tsx and
src/panel/ApproverRow.tsx so children reflow
onto additional lines when there isn’t enough
horizontal room
-
At wide widths the layout is unchanged — single-line
rendering is preserved with no wasted vertical space
Approver Ineligibility Indicator (BSOA-15)
-
Fixed: Two related visual issues with how
the panel displayed ineligible approvers (SoD violation,
eligibility-rule mismatch, or assignee/reporter conflicts
that tripped after a decision was made):
-
Decided approvers (APPROVED or RETURNED) who later
became ineligible showed only their decision lozenge
with no visible indication of the new conflict
-
Undecided approvers (ADDED or PENDING) who were
ineligible had their status label replaced by an
“Ineligible” lozenge, hiding whether they
were Added or Pending
-
The panel now consistently displays a small
🚫 (no-entry) icon as a trailing
decoration after the status lozenge for all
ineligible approvers — same pattern as the existing
🔒 lock icon
-
Status lozenge (Added / Pending / Approved / Returned) is
now always shown as the primary, with 🚫 and/or
🔒 trailing as decorations
-
Tooltip on the 🚫 icon carries the specific reason
(e.g., “SoD Conflict: Assignee cannot approve work
they are assigned to complete”)
-
Visual order on the row:
[Status] 🚫 🔒 when all three
apply
-
Saves significant horizontal space versus the prior
lozenge — materially improves narrow-column rendering
-
Backend behavior was already correct (decision changes
blocked when
sodViolation is true via the
canDecide flag, with re-validation in
decisions.ts and friendly error messages in
parseErrorMessage); this release closes the
visual gap
Code Quality
-
75 new backend tests covering gadget resolvers, JQL
pagination + truncation detection, decided-count rollups,
“All” sentinel pagination, and gadget
configuration persistence
-
BSOA-5 resolver implements internal JQL pagination (via
Jira’s
nextPageToken) up to a hard cap of
500 issues per request; bounded latency for users with very
large reporter/assignee sets
-
BSOA-4 resolver batches per-project effective-config reads
across the displayed page (was previously fetching per-item)
-
Cancel button added to both gadget configuration forms
-
Auto-refresh keeps the existing table visible while
reloading, instead of blanking to a spinner every interval
-
License-inactive state on both gadgets now uses
error SectionMessage appearance (previously
warning)
-
Backlog plan captured in
docs/features/backlog/Per-Status-Approver-Indexes-Plan.md
for a future BSOA-4 perf optimization (per-status side
indexes for users with very large approver histories)
Gadget Code-Sharing Refactor (BSOA-17)
-
Extracted ~685 lines of duplicated code from the two gadget
pages into shared modules: a generic
useGadgetView hook (state machine, refresh
listener, pagination, dynamic gadget chrome title) and a
generic GadgetConfigForm component
(wrapper-form pattern with project / max results /
refresh-interval selects, plus a render-prop slot for
gadget-specific filter dropdowns)
-
Both gadget pages shrank from ~547 lines to ~270-290 lines
and now consume the shared abstractions
-
Added shared style and utility modules
(
gadgetTableStyles, gadgetUtils)
to deduplicate table chrome and click handlers across the
two table components
-
Frontend test coverage went from 0% to ≥87% on every
gadget-related component, hook, and form (73 new component
tests added)
-
Closed the v1.1.0 SonarQube quality-gate failure: New Code
coverage now 95.5% (gate ≥80%), duplication 0.15% (gate
≤3%), 0 new issues
-
Wired
@vitest/coverage-v8 into the frontend so
its lcov report is now fed to SonarQube alongside the
backend’s (previously the gate only saw backend
coverage)
-
Polish: the “My Approval Requests” gadget no
longer renders decision comments inside the expanded
sub-rows — comments are still visible on the issue
itself when clicked through
Test Coverage
- 1,156 backend tests + 143 frontend tests (1,299 total)
-
All checks pass: TypeScript (backend + frontend), ESLint,
Prettier, Vitest, Forge manifest lint
-
SonarQube Quality Gate: Passed — 95.5% coverage on
new code, 0.15% duplication on new code, 0 new issues, 0
security hotspots (Rating A)
Version 1.0.2
Released: May 6, 2026
Marketplace Version: 4.6.0
Enhancement release that makes license-expiry behavior more
graceful for in-flight approvals, with explicit compliance
carve-outs for GDPR (Data Subject Access Requests) and SOC 2
(audit history export). Issue panel UX is updated to better
communicate license state to end users.
Enhancements
License — Graceful Finishing Mode on Expiry (BSOA-13)
-
When a Business Sign-off license expires, the plugin now
automatically enters finishing mode for affected projects
-
In-flight approval decisions can still be recorded, withdrawn,
or reset, allowing pending approvals to complete cleanly
-
Adding new approvers and other new-work operations remain
restricted until the license is renewed
-
New
requireActiveOrFinishing() license guard
introduced alongside the existing
requireActiveLicense() for finer-grained control
-
Workflow post-function handlers (add, remove, reset, selective
reset, notify, selective notify) now apply the appropriate
license guard based on whether the action creates new work or
progresses in-flight work
Compliance Carve-Outs (BSOA-13)
-
GDPR — Personal Data Reports: The Data
Subject Access Request endpoint
(
getUserDataReport) now functions regardless of
license state, ensuring continuous regulatory compliance
-
SOC 2 — Audit Export: Audit history
export (start and cleanup) now functions regardless of license
state to support customer SOC 2 audits and ongoing compliance
obligations
-
Each compliance carve-out is documented inline with
explanatory comments at the resolver site
Issue Panel UX (BSOA-13)
-
License-expired banner copy updated to clarify the
finishing-mode behavior: existing approvals can still
complete; new approvers blocked
-
Trial-specific banner messaging: trial-ended customers see an
“Upgrade to continue full access” message instead
of the generic “Renew” message intended for
paid-license expiry
-
Decision buttons (Approve, Return, Change Decision) are now
correctly enabled when the project is in finishing mode,
matching the new backend behavior
-
Notify Approvers button respects the same in-flight permission
model
-
License-specific error message added to the decision modal
when an action fails mid-session due to license expiry,
replacing the previous generic error fallback
Code Quality
-
Added 28 new tests covering all four license states (no
license, active trial, active paid, expired) across affected
resolvers and workflow handlers
-
Backlog plans captured in
docs/features/Rel 1.0.5/ for follow-up
improvements (typed LicenseStatus enum,
withLicense() resolver decorator, panel
auto-refresh of license state, modal license-error mapping
coverage)
Test Coverage
- 1,064 backend tests + 72 frontend tests (1,136 total)
- 80.5% line coverage (SonarQube analysis)
-
SonarQube Quality Gate: Passed (Security A, Reliability A,
Maintainability A — 0 security issues, 0 reliability
issues, 0 security hotspots)
Version 1.0.1
Released: May 6, 2026
Marketplace Version: 4.5.0
Maintenance release with three bug fixes addressing edge cases in
notifications, GDPR personal data reporting, and log noise from
deleted issues.
Bug Fixes
Notification Recipients — Empty Recipient Guard (BSOA-1)
-
Fixed: Jira
/notify endpoint
returning HTTP 400 when called with recipients that resolve to
nobody (empty users array, or
{ assignee: true } /
{ reporter: true } when the issue has no
assignee/reporter)
-
Added empty-recipient guard in the core
sendNotification function — silently
returns false when no recipients are defined
-
Added assignee/reporter field checks before sending decision
and outcome notifications in
decisions.ts and
approver.ts
-
No behavior change when recipients are present; notifications
continue to send normally
GDPR Personal Data Report — Path Manipulation Error
(BSOA-2)
-
Fixed: Weekly scheduled personal data report
handler failing with “Disallowing path manipulation
attempt” error
-
Root cause: Forge’s
route tagged template
was rejecting the entire
/app/report-accounts/ path when passed as an
interpolated variable
-
Fix: Replaced the interpolated variable with a literal string
in the
route template
- GDPR personal data reporting now functions correctly
Log Hygiene — Suppress Expected 404s on Deleted Issues
(BSOA-6)
-
Fixed: Noisy
console.warn entries appearing in logs when an
issue is deleted, caused by the field-sync handler racing with
the issue-deleted handler
-
The
syncAllFields function now silently returns
when a 404 JiraApiError is caught, since the
issue no longer exists
- Non-404 errors continue to be logged as warnings
-
No impact on the issue-deleted handler, which already cleans
up correctly
Code Quality
-
Refactored
IssuePanel component to extract
license warning logic, reducing cognitive complexity to meet
SonarQube threshold
-
Added pre-release verification script
(
scripts/pre-release.sh) with 10 automated
checks: TypeScript, ESLint, Prettier, tests with coverage, npm
audit, frontend build, Forge lint, Gitleaks, and optional
SonarQube scan
-
Added
.prettierignore to exclude generated report
files from formatting checks
Test Coverage
- 1,036 backend tests + 72 frontend tests (1,108 total)
- 86.2% coverage on new code
-
SonarQube Quality Gate: Passed (Security A, Reliability A,
Maintainability A)
Version 1.0.0
Released: April 24, 2026
Marketplace Version: 4.4.0
Initial release of Business Sign-off & Approval for Jira Cloud
— a complete rebuild of the Data Center plugin for
Atlassian’s Forge platform. Provides configurable, auditable
approval workflows directly within Jira issues.
Approval Workflow Management
-
Approver management — Add, remove, and
notify approvers on any Jira issue via the Business Sign-off
issue panel
-
Approval decisions — Approvers can
approve, return, or withdraw decisions with optional comments
-
Approval status calculation —
Configurable approval threshold (percentage-based), with
statuses: Not Started, Awaiting Decisions, Approval Passed,
Approval Failed
-
Bulk add approvers — Add multiple
approvers at once with per-user eligibility validation
-
Three-mode notify action — Notify new
approvers only, send reminders to all undecided, or request
full re-review (resets decided approvers)
-
Decision locking — Optionally lock
approved decisions when the issue transitions to a new status,
preventing changes after workflow progression
-
Comment requirements — Configurable per
decision type: require comments on all decisions, approvals
only, returns only, or none
Configurable Rules & Permissions
-
Global configuration — Centralized
admin page with tabbed layout for all plugin settings
-
Project-level overrides — Per-project
configuration with optional overrides for threshold, SoD,
eligibility, comments, and decision locking
-
Approver management permissions —
Control who can add/remove approvers: issue reporter,
assignee, and/or Jira administrators
-
Eligible approver filtering — Restrict
who can be assigned as an approver by project role and/or
group membership (ALL_USERS or SELECTED_USERS mode)
-
Separation of Duties (SoD) — Prevent
the issue assignee and/or reporter from being an approver,
with real-time re-evaluation when fields change
-
Decision authority — Optionally require
Jira Edit Issues permission to record a decision
-
Panel visibility — Show the approval
panel on all standard issue types (excludes subtasks) or
selected issue types only
-
Finishing mode — Non-destructive plugin
disable that preserves existing approvals while preventing new
ones
Workflow Integration
-
Workflow conditions — Block transitions
based on approval status (e.g., require Approval Passed before
closing)
-
Workflow validators — Validate approval
state during transitions with configurable error messages
-
Workflow post-functions — Automatically
add approvers (from users, roles, groups, or custom fields),
remove approvers, reset decisions, and notify approvers on
transitions
-
Selective notify post-function — Notify
only approvers matching specific role/group filters
-
Selective reset post-function — Reset
decisions only for approvers matching specific role/group
filters
-
Notification rate limiting — Prevents
duplicate notifications within the same UTC day
Audit & Compliance
-
Immutable audit trail — SHA-256
integrity-protected history records stored as Jira issue
properties, providing tamper-evident audit evidence
-
Approval history — Append-only audit
log viewable in the issue panel with full decision context
(actor, action, timestamps, comments, SoD status)
-
CSV audit export — Export approval
history to CSV with date range and project filtering, async
background processing with progress tracking
-
Admin audit log — Tracks all
configuration changes (global config, project config, debug
logging toggles) with actor and timestamp
-
Diagnostic logging — Admin-controlled
toggle with auto-expiry (1–8 hours) for production
troubleshooting via the Atlassian Developer Console
Custom Fields & JQL
-
BSO - Approvers — Read-only multi-user
custom field showing current approvers on each issue, synced
automatically from the approval panel
-
BSO - Status — Read-only text custom
field showing the current approval status (Not Started,
Awaiting Decisions, Approval Passed, Approval Failed)
-
JQL support — Filter and search issues
using standard JQL:
-
"BSO - Approvers" = currentUser()
— find issues where you are an approver
-
"BSO - Status" = "Approval
Passed"
— find approved issues
-
Issue property queries for advanced filtering (threshold,
percentage, counts)
Email Notifications
-
Approval requested — Notify approvers
when added or when review is requested
-
Decision notifications — Notify
assignee and/or reporter when decisions are recorded
-
Outcome notifications — Notify assignee
and/or reporter when approval passes or fails
-
Re-review notifications — Notify all
approvers when decisions are reset and re-review is requested
-
Per-project notification settings —
Enable/disable each notification type independently per
project
Data Privacy & GDPR
-
Personal Data Reporting — Weekly
scheduled job reports stored account IDs to Atlassian’s
Personal Data Reporting API
-
Account pseudonymization —
Automatically pseudonymizes approver records, history entries,
admin audit entries, and issue properties when Atlassian
reports an account as closed
-
DSAR support — Admin endpoint generates
a complete personal data report for any account ID
-
No data egress — All data remains
within Atlassian’s Forge infrastructure; no data
transmitted to external services
-
Minimal PII storage — Stores Atlassian
account IDs (opaque identifiers) only; display names and
emails resolved at runtime via Jira APIs
Licensing
-
Atlassian Marketplace licensing —
Standard Marketplace paid app licensing with trial support
-
Graceful degradation — Expired licenses
restrict write operations while preserving read access to
existing approval data
-
License status display — License state
shown in the admin page and issue panel
Platform Details
-
Runtime: Atlassian Forge (Node.js 22.x)
-
Frontend: React 18 (Custom UI) + Forge UI Kit
(issue panel, admin pages)
-
Storage: Forge Storage (key-value) + Jira
issue properties
-
Authentication: Forge app identity
(
asApp()) for all Jira API calls;
asUser() for admin permission verification
-
Scopes:
storage:app,
read:jira-work, write:jira-work,
read:jira-user,
manage:jira-configuration,
write:app-data:jira,
report:personal-data
Test Coverage
- 982 backend tests + 72 frontend tests (1,054 total)
- 88.7% line coverage, 88.2% branch coverage
-
ESLint security scan, npm dependency audit, Gitleaks secrets
scan — all clean
Known Limitations
-
BSO - Approvers field is read-only —
Approvers are managed exclusively through the Business
Sign-off panel. The custom field is for display and JQL
queries only.
-
Panel visibility on disabled projects —
The panel header (“Business Sign-off”) appears
even when the plugin is disabled for a project. The panel body
is empty, but the header cannot be suppressed due to Forge
platform behavior.
-
No custom JQL functions — Forge does
not support custom JQL functions. Use the built-in custom
field JQL and issue property queries instead.
-
Eventual consistency — Forge Storage
has eventual consistency characteristics. In rare cases, rapid
sequential operations may see stale data.
-
Forge cold start — First invocation
after idle may take 500–1000ms longer due to Forge
runtime cold start.
-
Frontend bundle size — The Custom UI
bundle is ~1.1MB (313KB gzipped). This is within Forge limits
but may be optimized in future releases.
Migration from Data Center
This is a new Forge app, not a direct migration
tool. Data Center customers moving to Jira Cloud will need to:
- Install the Forge app from the Atlassian Marketplace
-
Configure global and project settings (settings are not
migrated from DC)
-
Re-add approvers on existing issues (approval data from DC is
not transferred)
A data migration tool is planned for a future release.
← Back to Documentation