preventing users from being able to quit an app

ChrisJScott-wor
New Contributor III

Our team is kicking the tires on Cisco's AMP client for Mac endpoint security and it seems that's there's no way to configure the client to prevent end user's from being able to quite it themselves

I'm wondering if anybody knows of any way to "protect" a running process so that an end user can't quit it on their own...?

1 REPLY 1

mm2270
Legendary Contributor II

It's actually odd that Cisco doesn't have a solution to this, considering one of their other applications, namely AnyConnect, already includes a way to deploy it so it will stay running. I don't know that it does this by default, but it can be configured to do so, and it's not using anything esoteric or custom. It deploys a LaunchAgent that keeps the app running, so if it gets quit it will auto relaunch the application. Keep in mind this just reopens the app if it's quit or shuts down for some reason, it does not prevent it from being quit. I don't know of a way to remove a Quit menu item from an app unless the app has some kind of preference setting to do so.

Here is an example of the LaunchAgent plist that can get installed along with the Cisco AnyConnect Secure Mobility Client.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <dict>
        <key>PathState</key>
        <dict>
            <key>/opt/cisco/anyconnect/gui_keepalive</key>
            <true/>
        </dict>
    </dict>
    <key>Label</key>
    <string>com.cisco.anyconnect.gui</string>
    <key>LimitLoadToSessionType</key>
    <string>Aqua</string>
    <key>ProgramArguments</key>
    <array>
        <string>open</string>
        <string>--wait-apps</string>
        <string>/Applications/Cisco/Cisco AnyConnect Secure Mobility Client.app</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

As you can see it uses the KeepAlive key, but in their case it uses a path to a file of some kind. I'm not entirely sure how that works, but you can simply use the KeepAlive key with a boolean value of true to have it work.

Using the above as a template, if you created a LaunchAgent plist that looked something kind of like this (you might need to adjust the application path), and deployed it to your machines, it would, or should keep the app running, once the agent is loaded.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.yourorg.cisco.amp</string>
    <key>LimitLoadToSessionType</key>
    <string>Aqua</string>
    <key>ProgramArguments</key>
    <array>
        <string>open</string>
        <string>--wait-apps</string>
        <string>/Applications/Cisco AMP for Endpoints.app</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

I would first test this out by using the path to another simple application, like TextEdit.app or something, install it locally on your own test/IT Mac and then load it using launchctl load /Library/LaunchAgents/<plist name> Then quit TextEdit and you should see it automatically relaunch within a second or two. If that works, unload the agent (launchctl unload /path/to/plist) and replace the plist with one using the path to Cisco AMP and reload it and test that out.

If that works, that could be an option. Keep in mind that because this is a user level LaunchAgent, if someone discovers it, they can actually unload it using the same Terminal command above. There is no sudo required to unload a LaunchAgent since they are user based. But generally speaking, most users aren't going to discover the agent unless they are really determined to keep Cisco AMP quit.
You could develop some ways to detect if the agent is missing or unloaded, but that's kind of going down a rabbit hole. However, if you feel you wanted to explore that, let me know and I can post some ways to detect if the agent is disabled and then re-enabled it using an ongoing policy.