Title: Clipboard manager rejected under Guideline 2.4.5 for using CGEvent.post — what is the correct approach?

I'm developing a sandboxed clipboard history manager for macOS. When a user selects an item from their clipboard history, the app:

  1. Writes the data to NSPasteboard.general
  2. Posts a ⌘V keystroke via CGEvent.post(tap: .cgSessionEventTap)

This requires the user to grant permission under System Settings > Privacy & Security > Accessibility (kTCCServicePostEvent). The app does not use any Accessibility framework APIs (AXUIElement, AXIsProcessTrusted, etc.) — only Core Graphics event posting.

The app has been rejected twice under Guideline 2.4.5, with the reviewer stating that Accessibility features should not be used for non-accessibility purposes.

My understanding is that kTCCServicePostEvent (used by CGEvent.post) is a separate TCC service from kTCCServiceAccessibility (used by AXUIElement APIs), but both appear under "Accessibility" in System Settings, which may be causing confusion.

My questions:

  1. Is there an approved way for a sandboxed Mac App Store app to simulate a keystroke (specifically ⌘V) after writing to the pasteboard?
  2. If CGEvent.post is not appropriate for App Store apps, what alternative API should clipboard managers use to provide a "paste" action?
  3. Is there a way to use CGEvent.post that is compliant with Guideline 2.4.5?

I have a minimal sample project (single Swift file, sandboxed) that demonstrates the behavior. I can share it if helpful.

I was referred here by DTS (Case-ID: 19088416).

Answered by DTS Engineer in 881772022

There are two parts to this:

  • Technical — What APIs are involved? And what TCC privileges do they need?
  • App Review — What is or isn’t allowed on the App Store?

I work for DTS, not App Review, so I’m only able to comment on the first part. I’ll come back to the second part at the end.

From a technical standpoint, there are three TCC privileges involved:

  • PostEvent — This controls the ability to post UI events, for example, by calling the CGEvent.post(tap:) method that you mentioned.
  • ListenEvent — This controls the ability to monitor UI events on a system-wide basis, for example, with a CG event tap [1].
  • Accessibility — This is aimed at accessibility products, and controls a wide variety of things, including the ability to example the UI state of other apps.

Note I’m using the service names that you would pass to tccutil, as explained in this post.

These privileges are represented in System Settings > Privacy & Security, but in a non-obvious way:

  • Both PostEvent and Accessibility map to Accessibility.
  • ListenEvent maps to Input Monitoring.

That first mapping is an clear source of confusion.

The APIs gated by the Accessibility privileged are not compatible with the App Sandbox. We call this out in Security > App Sandbox > Protecting user data with App Sandbox > Review functionality that is incompatible with App Sandbox.

The APIs gated by the other two privileges are compatible with the App Sandbox.

The Mac App Store requires that all code be sandboxed. In my experience this isn’t an impediment to apps that rely on the PostEvent and ListenEvent privileges, because those are compatible with the App Sandbox.

However, as I mentioned above, I don’t work for App Review and can’t make definitive statements on their behalf. If you believe that App Review is incorrectly applying their guidelines, I recommend that you raise that with App Review directly. For advice on how to do that, see DEveloper > App Review.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Weirdly, the nicest API for monitoring UI events on a system-wide basis, NSEvent.addGlobalMonitorForEvents(matching:handler:), isn’t gated by this privilege, but rather requires the Accessibility privilege. I’ve never investigated why that is.

There are two parts to this:

  • Technical — What APIs are involved? And what TCC privileges do they need?
  • App Review — What is or isn’t allowed on the App Store?

I work for DTS, not App Review, so I’m only able to comment on the first part. I’ll come back to the second part at the end.

From a technical standpoint, there are three TCC privileges involved:

  • PostEvent — This controls the ability to post UI events, for example, by calling the CGEvent.post(tap:) method that you mentioned.
  • ListenEvent — This controls the ability to monitor UI events on a system-wide basis, for example, with a CG event tap [1].
  • Accessibility — This is aimed at accessibility products, and controls a wide variety of things, including the ability to example the UI state of other apps.

Note I’m using the service names that you would pass to tccutil, as explained in this post.

These privileges are represented in System Settings > Privacy & Security, but in a non-obvious way:

  • Both PostEvent and Accessibility map to Accessibility.
  • ListenEvent maps to Input Monitoring.

That first mapping is an clear source of confusion.

The APIs gated by the Accessibility privileged are not compatible with the App Sandbox. We call this out in Security > App Sandbox > Protecting user data with App Sandbox > Review functionality that is incompatible with App Sandbox.

The APIs gated by the other two privileges are compatible with the App Sandbox.

The Mac App Store requires that all code be sandboxed. In my experience this isn’t an impediment to apps that rely on the PostEvent and ListenEvent privileges, because those are compatible with the App Sandbox.

However, as I mentioned above, I don’t work for App Review and can’t make definitive statements on their behalf. If you believe that App Review is incorrectly applying their guidelines, I recommend that you raise that with App Review directly. For advice on how to do that, see DEveloper > App Review.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Weirdly, the nicest API for monitoring UI events on a system-wide basis, NSEvent.addGlobalMonitorForEvents(matching:handler:), isn’t gated by this privilege, but rather requires the Accessibility privilege. I’ve never investigated why that is.

Title: Clipboard manager rejected under Guideline 2.4.5 for using CGEvent.post — what is the correct approach?
 
 
Q