Role-based tag permission vs client visualisation

We want to use security on tags and split the tags up in groups of control.
We also need to visualise that an operator can or can’t control something. But I seem to be lacking a way to link the tag configuration to the visualisation.

F.e. an operator who’s only responsible for the packing area can only control motors of that area.
When he clicks on a motor, he sees a popup that shows a motor instance. But the controls should be enabled or disabled based on the role of the operator.

The popup is the same, so I need to get the info from the UDT instance in some way.

I thought about getting it from the tag security directly (via some expression or runScript). But I can’t seem to find it that way.

My second thought was to add an UDT parameter, and base the tag permission on that. Then we could read the parameter (via some bound memory tag) to visualise it. It would be less flexible, but at least we wouldn’t have to define everything twice.

Alas, that doesn’t seem to work either. It doesn’t seem to accept curly braces as parameter replacements.

Is there a way to get a link between vision and the tag permissions? Or are we just doomed to define everything twice and get into inconsistencies?

Does anyone actually use role-based permissions on tags?

Hmm, apparently you also can’t set the tag security using scripting.

This project is pretty big (thats the reason we need a finer separation in roles), so setting every motor or other device by hand will be a very tedious job.

I guess we’ll have to give up on tag-based permission, and just disable buttons in Vision.

Could you create roles named after the machines or areas and then use those roles for the security?
Role: PackingArea1Motors
Tag Security Access: Custom
Tag Permissions: Rolename: PackingArea1Motors, Security Zone: Default, Access: Read/Write
Tag Permissions: Rolename: LowLevelOperator, Security Zone: Default, Access: Read Only

Then just use HasRole to set enabled on the Template or Control?

1 Like

My issue is, how do I know what role to check in the popup? The popup for the motor is a generic popup. The same as for any motor. So I need to get that info somewhere from the UDT instance. (did they open a motor on packing area 1 or 2?)

I could check some UDT parameter or memory tag on the instance to decide that. But then the actual security on the tag isn’t linked with what is visualised. Which can easily lead to differences.

Are your tags organized into areas?
If so you could check tag path, or have a custom property on the UDT called EditRole or something and use that.

Without building this from the ground up with set paths, roles, access rules, etc it will be a big undertaking to retrofit something.

They are split into areas, and the areas match the roles pretty well. Though they’re not usable on their own, as some devices are more dangerous and thus need elevated rights.

I was planning to use the paths in order to automate the job of assigning the correct permissions to the correct tags, with manual corrections afterwards (that’s how I got all the alarms zoned up and notifying the right people/guiding them to the right page).

I know it’s a lot of work. Even with proper automation, it would probably cost a week to figure all this out.

But what I absolutely don’t want is ambiguity. F.e. when a button looks enabled, but when clicking it, the action is refused. This can cause a lot of downtime if an operator on a night shift is supposed to do some action, but suddenly doesn’t have the rights for it and nobody else is around.

I don’t trust myself to open every motor instance and select the right roles for it, if nobody can see the difference afterwards.

So if can’t automate the tag permissions, nor can check their settings from Vision popups, I won’t use the tag permissions. Keeping the security purely visual will be the only option I guess.

Hmm, I have found some way to check the permissions on a tag.

If only I would be able to edit them now…

def getPermission(tagPath):
	"""
	Method to test access rights of a tag
	Returns:
		* "Error" if the tag config cannot be read
		* "Denied" if any access is denied
		* "Read_Only" if the tag can be read
		* "Read_Write" if the tag can be read and written
	"""
	userRoles = system.security.getRoles()
	t = system.tag.browseConfiguration(tagPath, False)

	print t.toJSON()
	tagConfig = system.util.jsonDecode(t.toJSON())
	if len(tagConfig) == 0:
		return "Error"
	
	if "accessRights" not in tagConfig[0]:
		return "Read_Write"
	
	if tagConfig[0]["accessRights"] != "Custom":
		return tagConfig[0]["accessRights"]
		
	permission = "Denied"
	permissionModel = tagConfig[0]["permissionModel"]
	for conf in permissionModel:
		if conf["role"] in userRoles:
			if conf["writeAccess"]:
				return "Read_Write"
			else:
				permission = "Read_Only" # at least read access
	else:
		return permission

print getPermission("New Instance/bTag")

EDIT: better/more generic code

1 Like

We use an integer access level that is assigned to users based off of Roles.
We have client tags that check user roles, assign the int value to the tags and then use those to secure access to devices and navigation.
All of our systems run off a database that controls just about every aspect of the application though so I don’t think this would apply easily for you.

That would probably be too much, but it’s a possibility.

So you just do the checks client-side? Or do you also call a function when clicking a button to check off the rights in the gateway?

I can probably edit the tags via exporting and importing. Not sure how well that would work …

We do both, using an integer level for access you can assign a specific int to a Role and use that for specific access to things, or you can do the general if AccLevel>9999 etc.

To find out if the current user has write access to a specific tag, you can use the "CanWrite" property of the tag.