Enforce View Approval Path, definition scope, condition ownership and chat/email action settings on the server
Description
Depends on (merged to dev first): AP-2450 (Web API v2 decisions and decision details, StepAuthorizations, browsableIssueIds), AP-2380 (ReferenceAccess / readableGrants, Rovo StartRules, definition scope checks), AP-2486 (POST forms of the approvals list and Activity). AP-2146 (Teams) and AP-2496 were not waited for: GlobalSettings.isEmailActionsWithoutLoginEffective uses the same rule as AP-2496, and the Teams part of fix 5 follows when AP-2146 merges.
Problem
The UI hides these actions and data, but the server does not check them. A user who sends the request directly gets the data or makes the change.
-
View Approval Path permission. With the app's work item or page permissions on, a user without "View Approval Path" sees no approvals in the work item or page view, but the server returns them to anyone who may see the work item or page:
-
approvals list, including a single approval opened by link, with steps, decisions and comments (
/reference/approvals, GET and, since AP-2486, POST); -
Activity (
/activity/reference, GET and, since AP-2486, POST); -
definitions that can be started there (
/definition/reference); -
latest AI Prompt step run of an approval (
/prompt-step-executions/{approvalId}/{stepId}: error code and message; the result only for the approval's approvers). Decisions in the app view, version checks, the Web API decision details, Web API v2 decisions and Rovo already apply the permission. Affects both apps.
-
-
Reading a definition with
viewOnly(GET /definition/{id}?viewOnly=true) checks no permission. Any user in a project or space session gets that project's or space's and the global definitions (masked) by id, without View Approval Path, "View space settings page" or a definition permission. Affects both apps. -
Definition search (
/definition/search) without a project or space in the session (My overview, My approvals, gadget configuration) trusts thecollection-id/collection-idsof the request without a browse check, and returns every definition of the site when none are sent: id, name and project ids of definitions of any project or space. The Jira workflow configuration list (/workflow/definitions) returns every definition to anyone but a JSM customer. What the filter needs there: global definitions and those of the projects or spaces picked in the project filter, which offers only projects or spaces the user can browse. Affects both apps (workflow list: Jira). -
Conditions of other projects and sites. A definition's start and step conditions are stored by id as sent and loaded by id only, without checking site or project. Condition ids are one sequence shared by all sites. A user who may edit definitions can read, through a start condition, the name, expression, evaluating user and fail message of any condition, of other projects and other customers' sites, and make it decide starts and steps in their project. Rovo starts load definitions the same way. Conditions exist in the Jira app only, but the definition save request is shared by both apps.
-
Decision buttons already sent keep working after the settings are turned off:
-
Slack and Teams buttons refuse a click while "Enable actions without login" is off, but not while "Enable action buttons in notifications" is off;
-
email links check neither setting and work until they expire after 24 hours. Only the step's own approvers can use them, so this is no impersonation. The settings text "The link will be active for 24 hours" is true for email only.
-
Change
-
The four requests of item 1 (both GET and POST forms) are refused ("No access") without View Approval Path on that work item or page, by the rule of the decision request (
canDisplayReferenceView), the same rule Rovo and Web API v2 decisions use throughForgePermissionsService.readableGrants/ReferenceAccess. Portal access for JSM customers and agents and the behaviour with the app's permissions off are unchanged. No extra Atlassian call. -
With
viewOnly,GET /definition/{id}requires View Approval Path in the work item or page view, View space settings page or a definition permission in the space settings view, global admin in the global view.canViewDefinitiondoes not fit as is: View Approval Path counts for every user in the space settings and global views. The project or space scope (404) and masking stay as they are. -
Definition search without a project or space in the session returns global definitions and those of projects or spaces the user can browse, limited to the requested ones when sent (decision 4); global admins: as today. The same applies to
selected-ids./workflow/definitionsfollows decision 5. -
Saving a definition refuses a start or step condition not of the site, or of another project; a global definition may use global conditions only. The error names the id. One query per save checks all ids. Loading definitions and approvals, Rovo starts included, joins conditions within the site only.
-
A Slack or Teams button click and an email link are refused when either setting is off at the moment of the click. Slack and Teams reuse the existing refusals ("Acting on approvals from chat is turned off. Open the approval in Approval Path to decide.", with a link where the message can carry one); the email link page says "Acting on approvals from email is turned off. Open the approval in Approval Path to decide." The settings text matches decision 2.
Decisions taken
-
Definitions already stored with a foreign condition are listed on production for support before release (deploy checklist). On load, conditions of another site are dropped; a same-site condition of another project still loads and is refused on the next save.
-
Slack buttons work while the step is open; settings text "Email links stay active for 24 hours. Slack buttons work until the step is decided." ("Slack and Teams buttons" once AP-2146 merges).
-
View Approval Path is checked on the start definitions list and on every start path (create, Confluence restart, AI step re-run), as in Rovo.
-
One bulk browse check per request, cached per user (60 s); the JSM portal personal view uses the portal's projects.
-
/workflow/definitions: Jira admins get every definition as today; everyone else gets global definitions plus those of projects they can browse (same check as item 3); JSM customers stay refused. Not Jira admins only: team-managed project admins edit their own workflows (the app's workflow rules are declared for team-managed projects), and project admins configure the app's Automation action, which uses the same list.
Fixes included
-
On dev, Slack button clicks had no settings check at all; they are now refused when either setting is off.
-
A start condition that did not load can no longer reach start evaluation.
-
The AI step result in My approvals and the dashboard gadget needs View Approval Path on the approval's own work item or page; global admins as before.
-
The definition form offers only conditions the save accepts (global conditions for a global definition, global plus its own project's for a project definition), follows the Space field in the global view, and marks an already selected condition that is no longer allowed.
-
A condition's usage list no longer shows uses recorded by another site.
-
Web API definition lists leave out a start condition of another site.
-
A request token that does not say whether work item or page permissions are on now counts as permissions on, so it grants no work item or page action. Before, it counted as permissions off and granted all of them (view, start, parametrize, notify approver, delete, archive). A Confluence user the app cannot look up now gets a token with no app permissions instead of one with none of these flags. (Found in review; previously filed as AP-2542, withdrawn.)
-
A step condition of another project on the same site, stored on a definition before this change, is now evaluated when the approval starts, like a start condition; before, the step was removed at start without the condition being checked.
-
An email link decision checks the action settings on the same settings read it decides with.
-
Teams (fix 5) is not part of this change: it follows with the AP-2146 merge.
-
Searching definitions from a work item or page (the start dialog) needs View Approval Path for that work item or page, like the panel.
-
In Confluence, when no user token is available for the viewer, space access falls back to checking the space homepage as the app instead of treating every space as unreadable (at most 25 spaces checked per request; the rest on the next request).
-
Copying a global definition inside a project view creates the copy in that project and offers that project's conditions in the condition picker.
-
With chat actions turned off, Slack also refuses code resends and authenticator code entry. With acting from email turned off, an email decision link no longer sends a decision code.
Out of scope
-
Who may decide through Slack, Teams or email links (approver eligibility is unchanged).
-
Already done in AP-2450 / AP-2380: excluded users refused on group steps on every decision path; definitions of another project or space return 404 and are unmasked only for global or same-project admins; search scoped to the session's project or space;
POST /definition/{id}/duplicatechecks the project or space.
Acceptance criteria
-
With permissions on, a user without View Approval Path on a work item or page gets "No access" from the four requests of item 1, GET and POST; with it, the data as today. Portal and permissions-off behaviour unchanged.
-
With
viewOnly, a user without any of the permissions of fix 2 gets "No access"; with one of them, the masked definition as today. -
In My overview, My approvals and gadget configuration, definition search returns global definitions and those of projects or spaces the user can browse, also when other ids or none are sent. Saved filters show names only for definitions the user may see. Global admins: as today.
-
/workflow/definitionsfollows decision 5. -
Saving with a condition of another site, another project, or a project condition on a global definition is refused, naming the id; own project and global conditions save as today.
-
A definition stored earlier with a condition of another site loads and starts without it, also from Rovo. A condition of another project on the same site still loads and is evaluated (start and step conditions) until the definition is saved again (decision 1).
-
With "Enable action buttons in notifications" or "Enable actions without login" turned off after sending, a Slack button and an email link record no decision and show the refusal (Teams with AP-2146).
-
A token without the work item or page permission flag grants no work item or page action.
Manual tester notes
-
Send the requests with the browser developer tools, in the test user's session.
-
Item 1: with work item permissions on and View Approval Path removed from a test user, request the work item's approvals list, Activity, start definitions, the AI step result and a start: each says "No access". With the permission back: as before. Request the same approval's AI step result from My approvals and from the dashboard gadget: refused without the permission, shown with it. Repeat on Confluence; in the JSM portal, as customer and as agent, the panel works as before.
-
Item 2: request a definition with
viewOnly=truefrom the work item view without View Approval Path, and from space settings without the view or any definition permission: "No access". With a definition permission only: the masked definition. -
Item 3: as a user who cannot browse project B, open the definition filter in My overview, My approvals and gadget configuration: no project B definition, also when the request sends project B or a project B id in
selected-ids. A Jira admin sees all. In the portal's My approvals, only the portal's projects. Repeat on Confluence. -
Workflow configuration: as a team-managed project admin who is not a Jira admin, open the Approval Path workflow rule config: it lists global definitions and their own project's, none from a project they cannot browse. Repeat in an Automation rule's Approval Path action. A Jira admin sees every definition.
-
Item 4: as a Jira admin, open a global definition in the global settings: the start and step condition pickers list only global conditions; set its Space to a project and that project's conditions appear too. An existing global definition that uses a project condition shows it with "This condition belongs to a project. A global definition may use global conditions only." Save a definition with a condition id of another project or another QA site: refused, naming the id. A condition's usage list shows no uses from another QA site.
-
Item 5: after sending, turn off "Enable action buttons in notifications" and click Approve in Slack and in an email: no decision, the refusal shows. Repeat with "Enable actions without login". Check the settings text. Teams after the AP-2146 merge.
-
Permissions off (regression for the token flag fix): with work item permissions off in Jira and page permissions off in Confluence, open Approval Path on a work item, a page, the project or space settings, My approvals, the dashboard gadget and the JSM portal: the approvals list, start, decide, delete and archive work as before.
-
Turn off acting on approvals from email in the notification settings, then open an email decision link for a step that requires an email code: the page says acting from email is turned off and no code email arrives.
-
In a project's definition list, copy a global definition: the copy belongs to the project and its condition picker lists the project's conditions.