Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

block keyboard and camera due to security reason

Hello,

As part of developing a DLP system, I need to block input devices upon detection of data leakage. Could you advise if it's possible to temporarily disable the built-in keyboard and camera?

Thank you in advance, Pavel

Answered by DTS Engineer in 842652022

So, separating the two cases here:

temporarily disable the built-in keyboard

Yes, this is possible. Most straightforward approach would be to use CGEventTapCreate, which lets you hook your process into the system event delivery system. The API lets you modify or discard events, which will effectively block normal user input. Strictly speaking that could be bypassed by going directly to the HID system**, however, I wouldn't expect that to matter particularly for keyboard events*.

*The process of converting keyboards HID events into actual "keystrokes" is both remarkably complex and incredibly obscure. For example, the only public documentation I'm aware of that describes how keycodes map to basic ASCII is a chart from one of our old "Inside Macintosh" books, and that's just that start of the problem.

**Games are the only apps I'm aware of that regularly bypass the CGEvent system and that's because they can "cheat" their way around the mapping issue. They generally ship with some kind of "default" configuration that relies on a hard coded key map, then allow the user to modify that mapping by directly touching the key. That lets them just use whatever HID event that got without worrying about the actual mapping.

temporarily disable the built-in camera

This is a trickier problem. Two answers:

  1. You can block the connection at the point it's opened. Starting in macOS 26, ES_EVENT_TYPE_AUTH_IOKIT_OPEN has been made significantly more useful/capable. See my forum post here for more detail. Note that while the same event exists prior to macOS 26, the lack of information about the specific object being targeted would make it very difficult to reliably target the "right" connection attempts. It could still be used to block connection attempts, but it's also very likely that you'd block the "wrong" things.

  2. I can't think of any way to block the connection once it's open. Honestly, if that's a critical concern then I think the best option would be to use #1 to track "activity" (so you "know" that the camera could be open) and then terminate that process.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

So, separating the two cases here:

temporarily disable the built-in keyboard

Yes, this is possible. Most straightforward approach would be to use CGEventTapCreate, which lets you hook your process into the system event delivery system. The API lets you modify or discard events, which will effectively block normal user input. Strictly speaking that could be bypassed by going directly to the HID system**, however, I wouldn't expect that to matter particularly for keyboard events*.

*The process of converting keyboards HID events into actual "keystrokes" is both remarkably complex and incredibly obscure. For example, the only public documentation I'm aware of that describes how keycodes map to basic ASCII is a chart from one of our old "Inside Macintosh" books, and that's just that start of the problem.

**Games are the only apps I'm aware of that regularly bypass the CGEvent system and that's because they can "cheat" their way around the mapping issue. They generally ship with some kind of "default" configuration that relies on a hard coded key map, then allow the user to modify that mapping by directly touching the key. That lets them just use whatever HID event that got without worrying about the actual mapping.

temporarily disable the built-in camera

This is a trickier problem. Two answers:

  1. You can block the connection at the point it's opened. Starting in macOS 26, ES_EVENT_TYPE_AUTH_IOKIT_OPEN has been made significantly more useful/capable. See my forum post here for more detail. Note that while the same event exists prior to macOS 26, the lack of information about the specific object being targeted would make it very difficult to reliably target the "right" connection attempts. It could still be used to block connection attempts, but it's also very likely that you'd block the "wrong" things.

  2. I can't think of any way to block the connection once it's open. Honestly, if that's a critical concern then I think the best option would be to use #1 to track "activity" (so you "know" that the camera could be open) and then terminate that process.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you for these tips. The improvements to ES_EVENT_TYPE_AUTH_IOKIT_OPEN are excellent news! Regarding CGEventTapCreate(), unfortunately, the CoreGraphics is not daemon-safe framework.
Is there any way to implement keyboard locking directly at the daemon layer?

Thank you a lot for your help!

Regarding CGEventTapCreate(), unfortunately, the CoreGraphics is not daemon-safe framework.

Well... yes. That's because the entire concept of "events" comes from the WindowServer and is inherently part of the user session.

Is there any way to implement keyboard locking directly at the daemon layer?

No, certainly not one I'd consider remotely trustworthy/reliable. Theoretically you might be able to disrupt specific data source- for example, it's possible you could use the "raw" USB API to seize the HID device, which would prevent that device from emitting events. However:

  1. I'm not sure it would work all, as it relies on the WindowServer choosing to release the interface.

  2. If it does work, you're now stuck with the joyous task of task trying to anticipate and handle the face array of weird HID devices.

  3. It does nothing about the other inputs path like, for example, mouse and keyboard events arriving over the network.

  4. That still leaves you with the case of the system ITSELF generating it's own events.

Nothing on the list above is trivial to implement and, critically, the ONLY way to actually address #4... is to use CGEventTapCreate().

Returning to the question here:

Is there any way to implement keyboard locking directly at the daemon layer?

Having worked with many developers doing this kind of "security" product, many of them have the implicit assumption that having an agent is something to avoid/minimize. I think that's a mistake. The reality is that the entire system was architected around the daemon/agent divide and trying to avoid the agent context simply isn't going to end well. Solving the particular case here absolutely requires an agent but even without that issue, I'm skeptical that a high quality security product can actually be built solely within the daemon context.

Case in point, your goal here was to block user input from reaching the system. If you succeed at that goal... then what? As far as the user is concerned, their keyboard (and possibly their mouse) has simply stopped working without any explanation. Presumably you also need to tell them WHY this has happened, but that requires an agent, exactly what you were trying to avoid. The better path here is to think of your system as a central daemon with one or more agents (multiple user login) which are working together, then use which every component is right for each particular feature/goal.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

yes, I agree. It makes sense to implement this functionality in аgent. thank you!

block keyboard and camera due to security reason
 
 
Q