Skip to content

2026.10.15 — 2026-10-06 ​

Breaking ​

  • Read metrics, the audit trail and alert rules only for what the caller may see (d8d8064c)

    A series of one queue needs queue:read on it; the totals of a cluster add up every queue, so they need queue:read on every one (403 otherwise). The audit trail of a cluster is whole for a caller with cluster:read; anyone else sees the events about queues and addresses they may read, taken before the page and count are.

    Alert permissions stay cluster permissions, held through a grant and never through a team. A threshold rule watches queues named by its queuePattern (none: all of them), so it is listed, created, changed and deleted only by a caller who may read every queue that pattern can match, and its firings are shown, and counted in the shell badge, with it. A state rule and the installation's rules follow the permission alone.

  • Draw the flow graph, consumer health and broker events from what the caller may read (ee6aee37)

    The flow graph shows producers through the address they send to, consumers through the queue they read, and diverts, bridges and dead-letter routes through the addresses and queues they join; what belongs to the cluster as a whole (hops between nodes, temporary queues) is drawn for a caller who reads every queue and address. Consumer health ranks and counts only the caller's queues. Broker events are listed and counted by the address they are about, and an event about no address is read with cluster:read.

  • Trace request-reply only for addresses the caller may read (bf02706d)

    Creating, changing or deleting a request-reply expectation needs rr:write on the cluster, which a team never grants, and read access to its request address and every reply address it names. Expectations, flows, diagnostics and statistics show only those about addresses the caller may read, and counts and pages are taken after that, so a total never includes a hidden flow. The wrapped payload of a flow is still shown only to a caller who holds message:read on the cluster.

  • Write and show diverts only between addresses the caller may read (95872c81)

    Creating a divert needs divert:write on both its source and its forwarding address, checked before anything is done. Deleting one needs it on both addresses of the divert as deployed, which Studio reads from the broker; a divert the caller may not read is not found, like one that does not exist. The divert list shows only diverts whose two addresses the caller may read (a capture's or plugin's tap, only its source), and the bridge list only bridges that start from a queue or address the caller may read.

  • Capture and query only the queues the caller may reach (9464d640)

    A capture, a SQL query and the message index now check the caller against the queues they can reach, not against the cluster.

    Creating, changing or deleting a message capture needs capture:write on every queue its pattern can match: a grant that reaches the cluster, or one of the caller's team patterns (or a share) that covers the whole pattern. A pattern that could reach another team's names is refused with 403 and the problem type resource-forbidden, which asks for a narrower one. The list of captures shows only those whose queues the caller may read.

    A SQL query needs message:read on every queue its FROM can match, and is refused rather than trimmed, so a result never leaves out a queue the query names. Clear values in the results need message:clear on all of them; a caller who holds it only on some queues sees masked values and cannot filter or sort on a masked field. Verifying that a message is still on its queue needs message:read on that queue. The message:clear check of messages read through the console is now made against the queue they are on.

  • Check every queue and address operation against its resource (055c0805)

    Queue, address, message, dead-letter, transfer and bulk operations now check the caller's permission on the queue or address they act on, not on the cluster. A user who holds a permission through a team or a share can use it on the team's queues and addresses and nowhere else.

    A queue or address the caller may not read is reported as not found, exactly like one that does not exist. One they may read and may not change is refused with 403 and the problem type resource-forbidden, which names the missing permission and the resource. An operation that touches several resources (moving messages, retrying from a dead-letter queue, a transfer, a bulk plan) checks all of them before it does anything: the permission on the source, message:send on each target address, and read access to every one. Bulk plans and transfers check again before each queue they act on, so a permission withdrawn mid-run stops the run there.

    Lists are filtered before they are searched, sorted, paged and counted: queues, addresses, consumers, producers, sessions and connections show only what the caller may read, and totals count only those. A consumer is read through its queue and a producer through its address. A session or connection is shown to a caller with connection:read on the cluster, and otherwise only through consumers and producers they may read, trimmed to those. Each row carries allowedActions, the actions the caller holds on it. A team-only user sees the clusters their teams own queues on, with counts filtered the same way.

    Creating a queue or address is allowed only inside the caller's patterns, and a queue cannot be bound to an address the caller may not create. The refusal lists the patterns where they may create. Destroying an address is now address:delete, no longer queue:delete; the built-in Operator, Team Operator and Team Admin roles gain it.

Added ​

  • Read metrics, the audit trail and alert rules only for what the caller may see (d8d8064c)

    A series of one queue needs queue:read on it; the totals of a cluster add up every queue, so they need queue:read on every one (403 otherwise). The audit trail of a cluster is whole for a caller with cluster:read; anyone else sees the events about queues and addresses they may read, taken before the page and count are.

    Alert permissions stay cluster permissions, held through a grant and never through a team. A threshold rule watches queues named by its queuePattern (none: all of them), so it is listed, created, changed and deleted only by a caller who may read every queue that pattern can match, and its firings are shown, and counted in the shell badge, with it. A state rule and the installation's rules follow the permission alone.

  • Draw the flow graph, consumer health and broker events from what the caller may read (ee6aee37)

    The flow graph shows producers through the address they send to, consumers through the queue they read, and diverts, bridges and dead-letter routes through the addresses and queues they join; what belongs to the cluster as a whole (hops between nodes, temporary queues) is drawn for a caller who reads every queue and address. Consumer health ranks and counts only the caller's queues. Broker events are listed and counted by the address they are about, and an event about no address is read with cluster:read.

  • Trace request-reply only for addresses the caller may read (bf02706d)

    Creating, changing or deleting a request-reply expectation needs rr:write on the cluster, which a team never grants, and read access to its request address and every reply address it names. Expectations, flows, diagnostics and statistics show only those about addresses the caller may read, and counts and pages are taken after that, so a total never includes a hidden flow. The wrapped payload of a flow is still shown only to a caller who holds message:read on the cluster.

  • Write and show diverts only between addresses the caller may read (95872c81)

    Creating a divert needs divert:write on both its source and its forwarding address, checked before anything is done. Deleting one needs it on both addresses of the divert as deployed, which Studio reads from the broker; a divert the caller may not read is not found, like one that does not exist. The divert list shows only diverts whose two addresses the caller may read (a capture's or plugin's tap, only its source), and the bridge list only bridges that start from a queue or address the caller may read.

  • Capture and query only the queues the caller may reach (9464d640)

    A capture, a SQL query and the message index now check the caller against the queues they can reach, not against the cluster.

    Creating, changing or deleting a message capture needs capture:write on every queue its pattern can match: a grant that reaches the cluster, or one of the caller's team patterns (or a share) that covers the whole pattern. A pattern that could reach another team's names is refused with 403 and the problem type resource-forbidden, which asks for a narrower one. The list of captures shows only those whose queues the caller may read.

    A SQL query needs message:read on every queue its FROM can match, and is refused rather than trimmed, so a result never leaves out a queue the query names. Clear values in the results need message:clear on all of them; a caller who holds it only on some queues sees masked values and cannot filter or sort on a masked field. Verifying that a message is still on its queue needs message:read on that queue. The message:clear check of messages read through the console is now made against the queue they are on.

  • Check every queue and address operation against its resource (055c0805)

    Queue, address, message, dead-letter, transfer and bulk operations now check the caller's permission on the queue or address they act on, not on the cluster. A user who holds a permission through a team or a share can use it on the team's queues and addresses and nowhere else.

    A queue or address the caller may not read is reported as not found, exactly like one that does not exist. One they may read and may not change is refused with 403 and the problem type resource-forbidden, which names the missing permission and the resource. An operation that touches several resources (moving messages, retrying from a dead-letter queue, a transfer, a bulk plan) checks all of them before it does anything: the permission on the source, message:send on each target address, and read access to every one. Bulk plans and transfers check again before each queue they act on, so a permission withdrawn mid-run stops the run there.

    Lists are filtered before they are searched, sorted, paged and counted: queues, addresses, consumers, producers, sessions and connections show only what the caller may read, and totals count only those. A consumer is read through its queue and a producer through its address. A session or connection is shown to a caller with connection:read on the cluster, and otherwise only through consumers and producers they may read, trimmed to those. Each row carries allowedActions, the actions the caller holds on it. A team-only user sees the clusters their teams own queues on, with counts filtered the same way.

    Creating a queue or address is allowed only inside the caller's patterns, and a queue cannot be bound to an address the caller may not create. The refusal lists the patterns where they may create. Destroying an address is now address:delete, no longer queue:delete; the built-in Operator, Team Operator and Team Admin roles gain it.

Security ​

  • Check the queue an orphaned transfer returns messages into (f9928ce6)

    Returning the messages of an orphaned transfer staging queue needed message:move on the cluster and then moved them into any queue named in the request. It now needs message:move on the staging queue, queue:read on the queue they go back into, and message:send on the address that queue is bound to, checked together; a staging queue is named by no team's pattern, so only a grant that reaches the cluster passes, as before. A target queue that no node has is refused like one that may not be read.

  • Keep node addresses from a caller who sees the cluster only through a team (8714777b)

    The cluster, its topology and its capabilities returned each node's management and Core URLs, its last connection error, and capability reasons that name the hosts tried, to anyone who could see the cluster, including a member of a team that owns a few of its queues. These now need cluster:read on the whole cluster. Anyone else gets the nodes and their state without the URLs and errors, capability statuses without reasons, and a connection failure that says the brokers could not be reached and not where. The capabilities endpoint also checks that the caller sees the cluster, which it did not.

  • Move into a queue only through the address it is bound to (5001fabd)

    A move was checked against the address of its target queue as the scrape knew it, and against the queue's own name when no node had the queue. The address is now looked up on the scrape or the live nodes, and a target that no node has is refused like one the caller may not read, with the same not-found, so a name is never guessed. The caller also needs queue:read on the target queue, as for a transfer.

  • Leave other teams' queues out of the flow graph, events and audit trail (d2d11650)

    A dead-letter or expiry route in the flow graph needs its source readable as well as its target. A broker event whose routing name is a queue the caller may not read, such as a binding of another team's queue to their address, is left out, and counted out. The parameters of an audit event that name another queue or address, such as where messages were moved or a transfer sent them, are replaced for a reader who may not read it, and so is the cluster of a transfer then.

  • Answer a run of other teams' queues with the run's own not-found (1b8ac8e7)

    Reading, executing or stopping a bulk or transfer run whose queues the caller may not read was answered with a not-found that named a queue of the run (or, for several, a generic one). It now says the run does not exist, and names none of what it touches.

  • Name only the readable queues when an address cannot be deleted (74e067fa)

    Deleting an address that still has queues bound to it said which queues, including those of other teams. The refusal now names the queues the caller may read and counts the rest ("and 2 others"), or says none of them are theirs.

  • Retry only the messages that came from the addresses checked (014aa85e)

    A retry sends each message back to the address it came from. The addresses were read and checked first and the retry then ran as a separate call that retried the whole queue, so a message that arrived in between, from an address the caller may not send to, was retried too. A caller without message:send on the whole cluster now has the messages fixed after the check, by the checked addresses, and retried by id; an id that is not among them is left alone, including when ids were given.

  • Delete a divert only when it is the caller's on every node (1100f0bd)

    Deleting a divert read the addresses it runs between from one node and checked divert:write against them, but the divert is destroyed on every node. A divert of the same name that belonged to another team on a second node was destroyed with it. The addresses are now read on every node that has the divert, divert:write is required on all of them, and each node is checked again just before its own divert is destroyed: one that runs between addresses nobody checked is left alone.

    A divert whose addresses the caller may not read, or that no node has, is now answered with the same not-found, so the answer no longer says whether a divert of that name exists.

  • Send into a target queue only through the address it is bound to (7a487277)

    A transfer took the address to send to from the request and checked message:send against it, then moved the messages into the target queue whatever address that queue is bound to. A caller who could send to an address of their own could name a queue of another team as the target and write into it.

    The target address is now the one the target queue is bound to, and the request may leave it out or repeat it; naming another address is refused. The caller needs queue:read on the target queue and message:send on its address, checked together so that the not-found names neither. A target queue the broker would create is checked as a creation: queue:create on its name and message:send on the address it goes under. The run stores the address it resolved, and a run that loses queue:read on its target queue stops like one that loses message:send.

  • Require read access to a queue's configuration (9dd86950)

    The endpoint that reads a queue's configuration, per node, checked nothing beyond signing in. It now needs read access to that queue: a caller who may not read the queue gets the same not-found as for a queue that does not exist, so it no longer reveals a queue's address, routing type or settings.

Apache-2.0. Apache ActiveMQ and Apache ActiveMQ Artemis are trademarks of the Apache Software Foundation. Artemis Studio is an independent project, not produced by, endorsed by, or affiliated with the ASF.