Smart Card Setup – Admin Guide
This guide provides step-by-step instructions for system administrators on enforcing smart card authentication on MDM-managed devices. Due to current Apple platform limitations, full smart card enforcement (including keychain access and system updates) is not yet possible. However, with the right configuration, you can achieve up to 90% smart card enforcement for most workflows.
Important Recommendations:
- Deploy Company Certificates First: Before enforcing any smart card policies, ensure that company certificates are deployed to the device. Follow the Admin Certificates Admin Guide for details.
- Establish a Smart Card Pairing Workflow: Before enabling enforcement, set up a workflow for users to pair their smart card with their account. If enforcement is enabled without pairing, users will be locked out of their devices.
For maximum security and scalability, devices should be managed with a Mobile Device Management (MDM) system. The best practice for deploying smart card enforcement is to use MDM to push a configuration profile (.mobileconfig
file) with the required settings to your entire fleet.
If your organization does not use MDM, enforcing smart card is not recommended. In this case, refer to the User Guide for alternative approaches.
Smart Card Enforcement Workflow​
- Deploy Company Certificates to Device: Use MDM to push required company certificates.
- Guide Users Through Forced Pairing: Require users to pair their smart card with their account before proceeding. This can be enforced via MDM or onboarding scripts.
- Verify Pairing Success: Confirm that the smart card is correctly paired to the user account.
- (Optional) Exempt Admin Account or Unenforce for Troubleshooting: Consider maintaining an exempt admin account or a workflow to temporarily disable enforcement for troubleshooting purposes.
- Enforce Smart Card Policies: Once pairing is verified, enable smart card enforcement via MDM.
- Update PAM Configuration: After smart card enforcement is enabled, update your PAM (Pluggable Authentication Modules) configuration files to support smart card authentication for additional system functions as needed.
Enforcing Smart Card​
Step 1. Prior Requirements​
- Deploy Company Certificates: Deploy company Certificates to all devices by following the official guide: Admin Certificates Installation Guide.
- Establish Smart Card Pairing Workflow: We recommend using the Pair PIV ID workflow. This method can be easily pushed to users, requires minimal user interaction, supports smart card swapping, and allows a user to pair multiple smart cards. For more details, see the General | User Guide.
- Verify Smart Card Pairing: Ensure that smart card pairing is present for each user before enabling enforcement. You can use a script to check for pairing status, such as the example below:
#!/bin/zsh
# Check to see if SmartCard is user paired, and if the SmartcardLogin.plist exists
# and contains the required formatString for Kerberos
# Check for logged in user.
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}')
# Check if the file /etc/SmartcardLogin.plist exists and contains the Kerberos formatString
if [[ -f /etc/SmartcardLogin.plist ]]; then
formatString=$(plutil -extract "AttributeMapping.dsAttributeString" raw /etc/SmartcardLogin.plist 2>/dev/null)
if [[ "$formatString" == "dsAttrTypeStandard:AltSecurityIdentities" ]]; then
result="Paired"
else
result="NotPaired"
fi
else
# Check for pairing based on tokenidentity
tokenCheck=$(dscl /Local/Default read /Users/"$currentUser" AuthenticationAuthority 2>/dev/null | grep -c tokenidentity)
if [[ "$tokenCheck" -gt 0 ]]; then
result="Paired"
else
result="NotPaired"
fi
fi
# Output the result
echo "<result>$result</result>"
exit 0
Step 2. Create a Smart Card Enforcement Profile​
To enforce smart card authentication, configure the com.apple.security.smartcard
policy on managed devices. This is typically accomplished by deploying either a configuration profile (.mobileconfig
) or a property list (.plist
) through your MDM solution. Below are example configurations with detailed explanations for each value—adjust these settings as needed for your environment.
See Apple SmartCard Payload Documentation and Advanced Smart Card Options for more details on each key.
- Example .mobileconfig
- Example .plist
<!-- Example: Smart Card Enforcement.mobileconfig -->
<?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>PayloadContent</key>
<array>
<dict>
<!-- PayloadDescription: Optional description for this payload -->
<key>PayloadDescription</key>
<string></string>
<!-- PayloadDisplayName: Name shown in Profiles UI -->
<key>PayloadDisplayName</key>
<string>SmartCard</string>
<!-- PayloadEnabled: Whether this payload is enabled -->
<key>PayloadEnabled</key>
<true/>
<!-- PayloadIdentifier: Unique identifier for this payload -->
<key>PayloadIdentifier</key>
<string>com.cac-for-mac.smartcard.enforcement</string>
<!-- PayloadType: Must be com.apple.security.smartcard for smart card enforcement -->
<key>PayloadType</key>
<string>com.apple.security.smartcard</string>
<!-- PayloadUUID: Unique UUID for this payload -->
<key>PayloadUUID</key>
<string>6A2F1B3C-9D4E-4A1B-8C2F-1234567890AB</string>
<!-- PayloadVersion: Version number for this payload -->
<key>PayloadVersion</key>
<integer>1</integer>
<!--
UserPairing (boolean):
If false, users don’t get the pairing dialog, although existing pairings still work.
Default: true
-->
<key>UserPairing</key>
<false/>
<!--
allowSmartCard (boolean):
If false, disables the SmartCard for logins, authorizations, and screen saver unlocking.
Still allowed for other functions, such as signing emails and accessing the web.
Restart required for changes.
Default: true
-->
<key>allowSmartCard</key>
<true/>
<!--
checkCertificateTrust (integer):
Configures the certificate trust check.
0: Off
1: Standard validity check (no revocation)
2: Soft revocation check (default: valid unless explicitly revoked)
3: Hard revocation check (default: invalid unless explicitly OK)
Default: 0
-->
<key>checkCertificateTrust</key>
<integer>2</integer>
<!--
oneCardPerUser (boolean):
If true, a user can pair with only one SmartCard, although existing pairings are allowed if already set up.
Default: false
-->
<key>oneCardPerUser</key>
<false/>
<!--
enforceSmartCard (boolean):
If true, a user can only log in or authenticate with a SmartCard.
Available in macOS 10.13.2 and later.
Default: false
-->
<key>enforceSmartCard</key>
<true/>
<!--
allowUnmappedUsers (integer):
1 = allow users not mapped to a smart card, 0 = disallow
-->
<key>allowUnmappedUsers</key>
<integer>1</integer>
<!--
tokenRemovalAction (integer):
If 1, the system enables the screen saver when the SmartCard is removed.
Available in macOS 10.13.4 and later.
Default: 0
Possible Values: 0, 1
-->
<!-- <key>tokenRemovalAction</key>
<integer>1</integer> -->
</dict>
</array>
<!-- PayloadDescription: Description for the overall profile -->
<key>PayloadDescription</key>
<string>Settings for Smartcard Enforcement</string>
<!-- PayloadDisplayName: Name for the overall profile -->
<key>PayloadDisplayName</key>
<string>Smartcard Enforcement</string>
<!-- PayloadEnabled: Whether the profile is enabled -->
<key>PayloadEnabled</key>
<true/>
<!-- PayloadIdentifier: Unique identifier for the profile -->
<key>PayloadIdentifier</key>
<string>com.cac-for-mac.smartcard.profile.1B2C3D4E-5F6A-7B8C-9D0E-ABCDEF123456</string>
<!-- PayloadOrganization: Organization name -->
<key>PayloadOrganization</key>
<string>Your Organization</string>
<!-- PayloadRemovalDisallowed: If true, prevents removal of the profile -->
<key>PayloadRemovalDisallowed</key>
<true/>
<!-- PayloadScope: System = applies to all users -->
<key>PayloadScope</key>
<string>System</string>
<!-- PayloadType: Configuration profile type -->
<key>PayloadType</key>
<string>Configuration</string>
<!-- PayloadUUID: Unique UUID for the profile -->
<key>PayloadUUID</key>
<string>1B2C3D4E-5F6A-7B8C-9D0E-ABCDEF123456</string>
<!-- PayloadVersion: Version number for the profile -->
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
<!-- Example: /Library/Preferences/com.apple.security.smartcard.plist -->
<?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>
<!--
UserPairing (boolean):
If false, users don’t get the pairing dialog, although existing pairings still work.
Default: true
-->
<key>UserPairing</key>
<false/>
<!--
allowSmartCard (boolean):
If false, disables the SmartCard for logins, authorizations, and screen saver unlocking.
Still allowed for other functions, such as signing emails and accessing the web.
Restart required for changes.
Default: true
-->
<key>allowSmartCard</key>
<true/>
<!--
checkCertificateTrust (integer):
Configures the certificate trust check.
0: Off
1: Standard validity check (no revocation)
2: Soft revocation check (default: valid unless explicitly revoked)
3: Hard revocation check (default: invalid unless explicitly OK)
Default: 0
-->
<key>checkCertificateTrust</key>
<integer>2</integer>
<!--
oneCardPerUser (boolean):
If true, a user can pair with only one SmartCard, although existing pairings are allowed if already set up.
Default: false
-->
<key>oneCardPerUser</key>
<false/>
<!--
enforceSmartCard (boolean):
If true, a user can only log in or authenticate with a SmartCard.
Available in macOS 10.13.2 and later.
Default: false
-->
<key>enforceSmartCard</key>
<true/>
<!--
allowUnmappedUsers (integer):
1 = allow users not mapped to a smart card, 0 = disallow
-->
<key>allowUnmappedUsers</key>
<integer>1</integer>
<!--
tokenRemovalAction (integer):
If 1, the system enables the screen saver when the SmartCard is removed.
Available in macOS 10.13.4 and later.
Default: 0
Possible Values: 0, 1
-->
<!-- <key>tokenRemovalAction</key>
<integer>1</integer> -->
</dict>
</plist>
Step 3. Update PAM Configuration​
To enable smart card authentication for system functions such as sudo
, login
, and su
, you must update the relevant PAM (Pluggable Authentication Modules) configuration files. Below are two scripts: one that enables smart card authentication (recommended for smart card-enforced environments), and the default configuration for reference.
Modifying PAM configuration files can impact authentication and potentially prevent logins or sudo access if misconfigured. Test these changes thoroughly on a small group of devices before deploying to your entire fleet.
- smart card-Enabled PAM (Recommended)
- Default PAM (macOS)
#!/bin/bash
# This script configures PAM to support smart card authentication for sudo, login, and su.
# Write a new sudo PAM file to require smart card (pam_smartcard.so) for sudo access.
cat > /etc/pam.d/sudo << SUDO_END
# sudo: auth account password session
auth sufficient pam_smartcard.so # Allow smart card authentication
auth required pam_opendirectory.so # Fallback to local directory
auth required pam_deny.so # Deny if above fail
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
SUDO_END
chmod 444 /etc/pam.d/sudo
chown root:wheel /etc/pam.d/sudo
# Write a new login PAM file to support smart card and other authentication methods.
cat > /etc/pam.d/login << LOGIN_END
# login: auth account password session
auth sufficient pam_smartcard.so # Allow smart card authentication
auth optional pam_krb5.so use_kcminit
auth optional pam_ntlm.so try_first_pass
auth optional pam_mount.so try_first_pass
auth required pam_opendirectory.so try_first_pass
auth required pam_deny.so
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
LOGIN_END
chmod 644 /etc/pam.d/login
chown root:wheel /etc/pam.d/login
# Write a new su PAM file to require smart card for su access.
cat > /etc/pam.d/su << SU_END
# su: auth account password session
auth sufficient pam_smartcard.so # Allow smart card authentication
auth required pam_rootok.so
auth required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe
account required pam_permit.so
account required pam_opendirectory.so no_check_shell
password required pam_opendirectory.so
session required pam_launchd.so
SU_END
chmod 644 /etc/pam.d/su
chown root:wheel /etc/pam.d/su
#!/bin/bash
# This script restores the default macOS PAM configuration for sudo, login, and su.
# Default sudo PAM file (no smart card)
cat > /etc/pam.d/sudo << SUDO_END
# sudo: auth account password session
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
SUDO_END
chmod 444 /etc/pam.d/sudo
chown root:wheel /etc/pam.d/sudo
# Default login PAM file
cat > /etc/pam.d/login << LOGIN_END
# login: auth account password session
auth optional pam_krb5.so use_kcminit
auth optional pam_ntlm.so try_first_pass
auth optional pam_mount.so try_first_pass
auth required pam_opendirectory.so try_first_pass
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
LOGIN_END
chmod 644 /etc/pam.d/login
chown root:wheel /etc/pam.d/login
# Default su PAM file
cat > /etc/pam.d/su << SU_END
# su: auth account session
auth sufficient pam_rootok.so
auth required pam_opendirectory.so
account required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe
account required pam_opendirectory.so no_check_shell
password required pam_opendirectory.so
session required pam_launchd.so
SU_END
chmod 644 /etc/pam.d/su
chown root:wheel /etc/pam.d/su
What does this script do?
- sudo: Adds
pam_smartcard.so
as sufficient, allowing smart card authentication for sudo. If smart card is not present, falls back to local directory authentication. - login: Adds
pam_smartcard.so
as sufficient, enabling smart card authentication at login. Other modules (Kerberos, NTLM, etc.) remain optional or required as fallback. - su: Adds
pam_smartcard.so
as sufficient, allowing smart card authentication for switching users (su). Other checks (root, group, etc.) remain enforced. - Permissions: Sets correct permissions and ownership for each PAM file to ensure system security.
Step 4. Upload Smart Card Configuration Files​
To deploy smart card enforcement, upload the .mobileconfig
, .plist
, and any related scripts to your MDM solution. It is also recommended to upload uninstall scripts and ensure exempt accounts are set up.
Below are guides for uploading configuration profiles and scripts with popular MDMs:
- Jamf Pro: Uploading and Deploying Configuration Profiles
- Jamf Pro: Deploying Scripts
- Kandji: Uploading Custom Profiles
- Kandji: Custom Scripts
- Intune: Add or Create Configuration Profiles
- Intune: Deploy Scripts
Step 5. Enforce Smart Card Policies​
Before enforcing smart card policies, ensure every user has a smart card paired with their account or that you have an [exempt admin account available](#how-to-exempt-a-user-from-smart card-enforcement). Failing to do so may result in being locked out of the device.
- Assign the smart card enforcement profile (
.mobileconfig
or.plist
) to the appropriate device groups or users in your MDM. - Deploy the profile to all targeted devices.
Thoroughly test this configuration on a small set of devices before expanding deployment to your entire fleet. Confirm that smart card enforcement is working as intended and that users can access their accounts without issue.
Once you have validated successful smart card enforcement and user access, you can safely deploy the PAM configuration script (see Step 3) to enable smart card authentication for additional system functions such as sudo
, login
, and su
.
Step 6. Verify Functionality​
After deploying the smart card enforcement profile and updating PAM configuration, thoroughly verify that smart card authentication is functioning as intended across all targeted system functions.
- Test login, sudo, and su operations with a smart card on several devices.
- Confirm that users without a paired smart card or those not in the exempt group are unable to authenticate.
- Ensure that exempt admin/service accounts can still access the system as intended.
- Check for any unexpected lockouts or authentication issues and resolve them before proceeding with a wider deployment.
If any issues are detected, use your exempt account to regain access and adjust your configuration or policies as needed.
If you are required to comply with DISA STIGs or other local security policies, you may need to further adjust certain settings or smart card enforcement options to meet those requirements. Review your organization's compliance documentation and test accordingly.
Step 7. Test, Test, Test​
Smart card enforcement—especially when combined with compliance requirements—demands extensive testing. Some authentication functions or workflows may not work as expected depending on your complete setup, including:
- The method used for smart card pairing
- The deployment and trust of company certificates
- The specific compliance benchmarks or security policies (e.g., DISA STIGs) you must meet
Test all critical user and admin workflows, including login, sudo, su, and any other authentication-dependent processes. Validate that your configuration meets both operational and compliance requirements before deploying at scale.
How to Exempt a User from smart card Enforcement​
If you used the smart card PIV ID pairing workflow, the dedicated group called EXEMPT_GROUP
should already exist on your system. If it does not exist (for example, if you did not use the pairing workflow), you will need to create /private/etc/SmartcardLogin.plist
and configure it according to Apple's documentation.
Exempting users from smart card enforcement should be reserved for admin or service accounts only, to provide a backup option in case of lockout or for troubleshooting. For regular local users, it is more secure to remove the enforcement policy via MDM rather than adding them to the exempt group. This approach maintains a strong security posture and minimizes unnecessary exceptions.
Security Note:
Admin or service accounts in the exempt group should have additional protections, such as a disabled ("dead") password, a password that is rotated frequently, or other controls to ensure the account cannot be easily used for regular logins. You may also consider setting these accounts as standard (non-admin) users unless elevated privileges are absolutely required. These measures reduce the risk of these accounts being exploited as a bypass.
To exempt a user from smart card enforcement, add them to the EXEMPT_GROUP
. The script below checks for the existence of the group, creates it if necessary, and adds the specified user.
#!/bin/bash
# Exempt a user from smart card enforcement by adding them to the EXEMPT_GROUP
EXEMPT_USER="username_here" # <-- Set this to the username you want to exempt
EXEMPT_GROUP="EXEMPT_GROUP"
# Check if the group exists, create if it does not
if ! dscl . -read /Groups/"$EXEMPT_GROUP" &>/dev/null; then
sudo dscl . -create /Groups/"$EXEMPT_GROUP"
sudo dscl . -create /Groups/"$EXEMPT_GROUP" RealName "smart card Exempt Users"
sudo dscl . -create /Groups/"$EXEMPT_GROUP" passwd "*"
sudo dscl . -create /Groups/"$EXEMPT_GROUP" gid "600"
fi
# Add the user to the group
sudo dseditgroup -o edit -a "$EXEMPT_USER" -t user "$EXEMPT_GROUP"
- Set the
EXEMPT_USER
variable at the top of the script to the username you wish to exempt. - This script will ensure the group exists and add the user to it.
Uninstall PAM Configuration​
To revert the PAM configuration to the macOS defaults (removing smart card enforcement for sudo
, login
, and su
), use the following script:
#!/bin/bash
# This script restores the default macOS PAM configuration for sudo, login, and su.
# Default sudo PAM file (no smart card)
cat > /etc/pam.d/sudo << SUDO_END
# sudo: auth account password session
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
SUDO_END
chmod 444 /etc/pam.d/sudo
chown root:wheel /etc/pam.d/sudo
# Default login PAM file
cat > /etc/pam.d/login << LOGIN_END
# login: auth account password session
auth optional pam_krb5.so use_kcminit
auth optional pam_ntlm.so try_first_pass
auth optional pam_mount.so try_first_pass
auth required pam_opendirectory.so try_first_pass
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
LOGIN_END
chmod 644 /etc/pam.d/login
chown root:wheel /etc/pam.d/login
# Default su PAM file
cat > /etc/pam.d/su << SU_END
# su: auth account session
auth sufficient pam_rootok.so
auth required pam_opendirectory.so
account required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe
account required pam_opendirectory.so no_check_shell
password required pam_opendirectory.so
session required pam_launchd.so
SU_END
chmod 644 /etc/pam.d/su
chown root:wheel /etc/pam.d/su
This will restore the default PAM configuration for the main authentication functions.
If you found an error, noticed something missing, or need additional help, please submit feedback on GitHub or start a GitHub discussion.
If you'd like to contribute improvements to this guide, feel free to submit a pull request or select edit this page
below.