Resolving subscription authorisation failures

padlock

It never fails to amaze me how often the same question gets asked by different people from different projects at around the same time. This time, I was asked by two people about resolving subscription authorisation failures. I could find lots of information about IBM MQ publish/subscribe, and general descriptions of what security checks are made. But there was not so much on how to use information from the queue manager that can help to deal with the inevitable failures.

Topic Objects and Strings

The most important thing to understand is the difference between Topic OBJECTS and Topic STRINGS.

A topic object is something that you explicitly define in the queue manager, in much the same way as you define a queue. Like queues, they have a name that is no longer than 48 characters. And they have to conform to the same restricted character set for those names. A topic object has an associated topic string, given as one of its attributes:

DEFINE TOPIC(A.B.C) TOPICSTR('/A/B/C')

A topic string can be much longer, and has a definite hierarchical structure with elements separated by the ‘/’ character. While every topic object has a topic string, there is no requirement for each topic string to have a directly matching topic object. So I can subscribe to the topic string /A/B/C/D without creating any further topic object. There is also no requirement for the object name to have any structure matching the topic string – I could do DEFINE TOPIC(XYZ) TOPICSTR(/A1/B2/C3) if I really wanted to – but that just leads to obscurity. You can also have ‘/’ in the object name, but I think that causes even more confusion and really should not be done for some other objects because of the problems it causes with handling publications that include the object name.

When writing programs, the MQI allows you to explicitly subscribe to a combination of objects and strings. Either or both of the fields can be filled in. When both are present, the object’s string attribute gets joined with the explicit string to create a single effective topic string:

MQSUB(Object='A.B.C',String='/D')

results in a subscription to /A/B/C/D. But that mixed mode is probably rarely used, and is not even possible in some of the other APIs. JMS, for example, only allows a single topic parameter in its methods. That gets passed to the queue manager as the topic string.

What is the point of a topic object?

The topic object is primarily something for a queue manager administrator. It sets default behaviour for publications and subscriptions.

AMQ8633I: Display topic details.
  TOPIC(SYSTEM.BASE.TOPIC)                TYPE(LOCAL)
  TOPICSTR()
  DESCR(Base topic for resolving attributes)
  CLUSTER( )                              CLROUTE(DIRECT)
  DURSUB(YES)                             PUB(ENABLED)
  SUB(ENABLED)                            DEFPSIST(NO)
  DEFPRTY(0)                              DEFPRESP(SYNC)
  ALTDATE(2019-01-26)                     ALTTIME(10.41.02)
  PMSGDLV(ALLDUR)                         NPMSGDLV(ALLAVAIL)
  PUBSCOPE(ALL)                           SUBSCOPE(ALL)
  PROXYSUB(FIRSTUSE)                      WILDCARD(PASSTHRU)
  MDURMDL(SYSTEM.DURABLE.MODEL.QUEUE)
  MNDURMDL(SYSTEM.NDURABLE.MODEL.QUEUE)
  MCAST(DISABLED)
  COMMINFO(SYSTEM.DEFAULT.COMMINFO.MULTICAST)
  USEDLQ(YES)                             CUSTOM( )

When a program creates a subscription or is getting ready to make a publication, the queue manager builds a tree of topic objects using the topic strings as the key for entries in the tree. The nearest node of the tree that matches the topic string will determine, for example, whether a publication is persistent or not.

The topic object tree

This picture shows an example of a set of topic object definitions:

Topic Objects in MQ Explorer

It can be convenient to see these objects laid out more like a tree, so you can understand the relationships between them. One of my MS0P plugins for the Explorer does that:

Topic Objects as a tree

This tree view interpolates nodes in the tree of topic strings, so even though there is no object defined with a topic string of /A/B/C (and hence the grey colour), there are no gaps in the visualisation.

When I use a particular topic string, then the first place the queue manager looks for how it will behave is the lowest entry in the tree that matches the start of the topic string. Subscribing to /A/B/X will pick up behaviour based on the A.B object as its topic string of /A/B is the nearest above the given string.

Do I need any object definitions?

Because topic objects are used to modify behaviour, then you might not need to create any new object beyond the default SYSTEM objects. So you can get going very easily with publishing and subscribing.

But the most likely reason for defining objects is to partition the topic tree for permissions. An administrator may want to constrain some users to only being able to publish or subscribe in a specific region of the tree.

Setting & checking permissions

Just like all other objects, permissions can be set against topic objects. For example, I can run

CMD: setmqaut -t topic -n A.B.C.D -m QM1 -p mqguest +sub

or

MQSC: SET AUTHREC PROFILE('A.B.C.D') OBJTYPE(TOPIC) PRINCIPAL('mqguest')  AUTHADD(SUB)

But when an application subscribes, multiple checks might get made on whether it is allowed. It’s not like opening a queue, where a single check is made based on the queue name. Instead, the queue manager steps up the topic object tree, looking at each level for an permitted authority. So if my program tries to subscribe to the topic string /A/B/C/D/CC, the queue manager will check in turn:

  • Permitted to use A.B.C.D?
  • Permitted to use A.B? (remember there’s no A.B.C object in the tree)
  • Permitted to use A?
  • Permitted to use SYSTEM.BASE.TOPIC? (that’s always at the top)

If any of these questions returns “YES” then the sequence stops and the subscription is allowed to go ahead. If we reach the top of the tree, and none of the questions has returned “YES” then the subscription attempt fails with 2035, MQRC_NOT_AUTHORISED. This sequence of checks, and the rules, might seem a bit odd. But it was designed that way for a number of reasons including when the subscription includes a wildcard that might cross multiple levels of the tree.

This is also why you have to be careful about granting permissions against SYSTEM.BASE.TOPIC: if someone has authority on that object, they will have permissions against all topics, regardless of permissions set lower down the tree.

What might cause user confusion

Both of the questions that came to me recently had a similar description, and a similar cause. In both cases, the application was subscribing to a simple, non-structured topic. Something like:

context = connectionFactory.createContext();                           
destination = context.createTopic("topic://" + "myTopic");         
subscriber = context.createConsumer(destination);

And the administrator claimed to have done a setmqaut for that topic:

setmqaut -m QM1 -t topic -n "myTopic" -p mqguest +sub

But the program was still getting authorisation exceptions.

But in reality, the word “topic” was (understandably) being used in different ways by the two people. To the application developer, the term was referring to an MQ Topic String (JMS just talks about “topics”). In the administrator’s world, the term was being used to refer to a Topic Object. The lack of a ‘/’ in the application’s topic string made it even less obvious what was being used. It is possible to define authorisations for non-existent objects, so the setmqaut succeeded even though there was no object named myTopic.

How do we resolve this

What information does the queue manager provide for the administrator to narrow down what is wrong, and how to resolve it.

Error Logs

Usually for an authorisation problem, the queue manager error log will tell you the object that needs additional permissions applied. For example:

AMQ8077W: Entity 'mqguest' has insufficient authority to access object DEV.QUEUE.1 [queue].
EXPLANATION:
The specified entity is not authorized to access the required object. The following requested permissions are unauthorized: put

So I know I have to use setmqaut (or SET AUTHREC) against that queue.

For a subscription failure, there is a very similar message:

AMQ8009W: Entity 'mqguest' has insufficient authority to access topic string 'myTopic'.
EXPLANATION:
The specified entity is not authorized to access the required topic. The following permissions were requested: sub

Note the subtle difference in the message. Here it explicitly refers to the topic string that was being used. If you do not fully appreciate the difference between the two concepts, then it’s easy to see why the administrator issued a setmqaut but it didn’t actually resolve the problem. Since there was no structure to the topic string, and no explicit object with that string, the authorisation check was actually being made against the SYSTEM.BASE.TOPIC object.

It would be nice if this error message told you the topic object you needed to apply permissions to. But the queue manager cannot tell which of the several authorisation checks walking up the tree would be the correct one to modify. It will depend on the administrative policy as to how broadly to grant permissions.

The error message cannot include a list of all the objects checked – it could be a long list, and there are limits in error messages as to the number and length of inserts. I suppose it would be possible to issue something like this error message for each of the checks made on the tree, but it could fill the logs with unmanageable quantities of messages, where a single failure resulted in many error messages.

The administrator first has to remember the difference between topics and other object types, work out the topic object tree, as in the Explorer picture above, and then decide which object is most appropriate for the security policy.

Authorisation Events

A better view of the failure is given by authorisation events. I would hope that you have these events enabled. If not, then

ALTER QMGR AUTHOREV(ENABLED)

This example shows a user trying and failing to use one of the structured topics. I’ve used the amqsevt sample program to format the event from the SYSTEM.ADMIN.QMGR.EVENT queue:

Event Type         : Queue Mgr Event [44]
 Reason            : Not Authorized [2035]
 Event created     : 2021/12/10 15:57:53.61 GMT
   Queue Mgr Name  : QM1
   Reason Qualifier: Sub Not Authorized
   Sub Options     : 0x00202022 [create managed fiq wc_topic ]
   User Identifier : mqguest
   Appl Type       : Unix
   Appl Name       : ssub
   Topic String    : /A/B/C/D/CC
   Admin Topic Names : A.B.C.D
                     : A.B
                     : A
                     : SYSTEM.BASE.TOPIC

Here we can see the topic string used by the program as well as a list of all of the topic objects referenced during the authorisation checks. While I still have to decide which object to grant permission for, this event makes it much clearer as to my choices.

Publications

Although the questions I received were about subscriptions, the same things happen with publications – potentially multiple topic objects being checked when an application publishes messages. The error log and events are much the same, and the resolution process is identical:

AMQ8009W: Entity 'mqguest' has insufficient authority to access topic string '/A/B/C/D/CC'.
EXPLANATION:
The specified entity is not authorized to access the required topic. The following permissions were requested: pub

and

Event Type             : Queue Mgr Event [44]
 Reason                : Not Authorized [2035]
 Event created         : 2021/12/12 14:54:31.27 GMT
   Queue Mgr Name      : QM1
   Reason Qualifier    : Open Not Authorized
   Topic String        : /A/B/C/D/CC
   Admin Topic Names   : A.B.C.D
                       : A.B
                       : A
                       : SYSTEM.BASE.TOPIC
   Open Options        : 0x00002010 [ fiq out ]
   User Identifier     : mqguest
   Appl Type           : Unix
   Appl Name           : amqspub
   Object Queue Mgr Name  :

Summary

Understanding the differences between topic objects and strings is key to being able to manage a publish/subscribe environment. Application developers and administrators need to understand each other’s terminology.

I hope this short article helps to clarify and give advice on the security model, particularly when things are not working as expected.

Update History
  • 2021-12-10: Initial publication
  • 2021-12-13: Added AUTHREC example; added comments about publications

This post was last updated on December 13th, 2021 at 01:23 pm

One thought on “Resolving subscription authorisation failures”

  1. Hi Mark,
    great article again! would you mind adding the equivalent AUTHREC’s to the article for the setmqaut commands, as they can be administered remotely using runmqsc in client mode.

Leave a Reply

Your email address will not be published. Required fields are marked *