XCreds Admin Guide
Sync Your Cloud Password to your Mac
How It Works
XCreds has two components: the XCreds app that runs in user space and XCreds Login window that is a security agent that runs when the user is logging in to their Mac. Both the security agent and the app share keychain items in the user’s keychain to keep track of the current local password and the tokens from the cloud provider. Both items prompt the user with a web view to authenticate to their cloud provider, verify login was successful, and then update the local password and user keychain passwords as needed.
Requirements
XCreds currently works with Azure and Google Cloud as an OIDC identity provider. It has been tested on the current version of macOS as well as prior versions back to macOS 12 Monterey, but should support earlier versions of macOS.
Components
XCreds consists of XCreds Login and XCreds app. They do similar tasks but run at different times.
XCreds Login
XCreds Login is a Security Agent that replaces the login window on macOS to provide authentication to the cloud provider. It presents a web view at the login window and fully supports multi-factor authentication. When authentication completes, the web view receives OpenID Connect (OIDC) tokens and stores those tokens in the login keychain. If the local password and the cloud password are different, the local password is updated to match the cloud password and the login keychain password is updated as well. The local password is then stored in the user keychain so that any password changes in the future can be updated silently. Only the security agent and the XCreds app are given permission to access the password and tokens.
XCreds App
The XCreds app runs when the user logs in. On first launch, it checks to see if XCreds tokens are available in the login keychain. If they are, the refresh token is used to see if it is still valid. If it is invalid (due to a remote password change), the user is prompted with a web view to authenticate with their cloud credentials. If they authenticate successfully, the tokens are updated in the login keychain and the password is checked to see if it has been changed. If it changed, the local account and login keychain are updated to match the cloud password.
Download
Download XCreds from the XCreds product page.
Setup
To get started with XCreds, follow the instructions below. All resources are within the app itself and setup is configured using command line tools inside the app bundle. Preferences are handled by configuration profiles (see below).
- Install the XCreds package. This will install XCreds.app into your application folder. In post-install, a security agent and a launch daemon are activated. See setup step 4 below.
- Install a configuration profile by follow the instructions below under the Configuration section.
- Launch the app by double clicking on it. A new menu item will appear with chasing arrows. A web view will also appear since there are no XCreds tokens in the keychain. Authenticate with your cloud password. You will be prompted for your local password and your local password and keychain password will be updated if it is different from your cloud password.
- XCreds Login is automatically activated when installed. The installer runs this command:
sudo /Applications/XCreds.app/Contents/Resources/xcreds_login.sh -i
. This will install an XCreds security agent calledXCredsLoginPlugin.bundle
in/Library/Security/SecurityAgentPlugins
and a launch daemon calledcom.twocanoes.xcreds-overlay.plist
in/Library/LaunchDaemons
. The launch daemon shows an overlay on the standard login window to return back to XCreds Login. Theauthorizationdb
is also updated to activate the Security Agent and you can see the new rules by running:security authorizationdb read system.login.console
. A backup copy of the replaced rules is stored in/Library/Application Support/xcreds/rights.bak
. - Log out of the Mac. The XCreds Login window will be presented. Log in with your cloud credentials.
- XCreds.app will not launch automatically. You can use Login Items in System Preferences to automatically launch XCreds.app or use an MDM policy.
Configuration
Configuration and settings are handled from a config profile. The discovery URL and client ID values are required. All others are optional. Example mobileconfig files are provided in the instructions for each cloud provider.
Azure Setup
Google Cloud Setup
See Google setup instructions.
Okta Setup
Uninstall
- To remove XCreds Login, restore the backup security agent rules and remove the launch agent, run:
sudo /Applications/XCreds.app/Contents/Resources/xcreds_login.sh -r
- Drag the XCreds app to the trash.
Preferences
Basic setup for each cloud provider will work by just installing the example mobileconfig file provided in the instructions for each cloud provider (after updating the relevant account ID values). An XCreds settings mobileconfig file can be edited using a text editor for basic changes. To change additional preferences, though, the easiest way is to use Profile Creator. Profile Creator can create a new mobileconfig file that sets all desired preferences. Install and launch Profile Creator. Then click the “+” button near the top left of the window to create a new profile. Give the profile a name and set Payload Scope
to be System
. Next find the navigation bar on the left below where it says No payloads
. This navigation bar will show icons for a check mark, an Apple logo, and an App Store logo. Click the App Store logo icon. Then scroll all the way to the bottom and find the line for XCreds. Drag XCreds from the bottom up to the top left below the item that says “General – 1 payload”. Click on this new item named XCreds below the item named General. Once this is done Profile Creator will show a form with information and options for all XCreds preferences. The following preference keys can then be set and managed.
Preferences Version 5.1
Name | Type | Description |
---|---|---|
ADDomain | string | The desired AD domain |
mapKerberosPrincipalName | string | The OIDC claim that has the kerberos principal name. This is used when logging in with OIDC and ADDomain is defined. During login, the claim that contains the kerberos principal name will be read and the local account will set dsAttrTypeNative:_xcreds_activedirectory_kerberosPrincipal to the kerberos principal name. The menu item will then use this value and the password to get a kerberos ticket. |
clientID | string | The OIDC client id public identifier for the app. |
clientSecret | string | Client Secret sometimes required by identity provider. |
CreateAdminUser | boolean | When set to true and the user account is created, the user will be a local admin. |
allowUsersClaim | string | The claim that contains the value to check for in the allowedUsersArray. Both must be defined. |
allowedUsersArray | array | List of users that are allowed to log in. An empty array or undefined array means any user can log in as long their cloud credentials are valid. The preference allowUsersClaim must be defined to a claim in the idToken that identifies the users. For example, if the allowUsersClaim is set to upn and the allowedUsersArray is set to an array that contains fred@twocanoes.com and the upn of a logging in user is fred@twocanoes.com, they would be allowed to log in. barney@twocanoes.com would not. |
allowLoginIfMemberOfGroup | array | List of groups whose members should be allowed to login. If the user is a member of any of these groups they can login regardless (including creating new local account) if authorization succeeds. If a local account exists but the user is no longer part of a group the login will be denied. |
CreateAdminIfGroupMember | array | List of groups that should have members be given local administrator status. Local administrator status can be given on first authentication when account created, or on later sign in of existing user when a group member. Administrator status is removed if group membership later revoked. Administrator status is not removed if user is the only XCreds admin user. Set as an Array of Strings of the group identifier. |
claimsToAddToLocalUserAccount | array | List of claims that should be added to the user local account. Will be prefixed with _xcreds_oidc_. Set as an Array of Strings of the claim. |
systemInfoAdditionsArray | array | Items to be added to the System Info Popover at login. Can be made dynamic by using the override script override to provide this setting |
shouldSwitchToLoginWindowWhenLocked | boolean | When set to true and the user locks the current session, XCreds will tell the system to switch to Login Window. The current session will stay active but the user will login with the XCreds Login Window to resume the session. |
LocalFallback | boolean | If the user attempts to login as an AD user and the login fails against AD, try against local user account if off domain or AD user not found. |
shouldActivateSystemInfoButton | boolean | Show the system info popover as active when first starting |
discoveryURL | string | The discovery URL provided by your OIDC / Cloud provider. For Google it is typically https://accounts.google.com/.well-known/openid-configuration and for Azure it is typically https://login.microsoftonline.com/common/.well-known/openid-configuration. |
EnableFDE | boolean | Enabled FDE enabled at first login on APFS disks. |
EnableFDERecoveryKey | boolean | Save the Personal Recovery Key (PRK) to disk for the MDM Escrow Service to collect. |
EnableFDERecoveryKeyPath | string | Specify a custom path for the recovery key. |
EnableFDERekey | boolean | Rotate the Personal Recovery Key (PRK). |
loginWindowWidth | integer | Login Window webview width (Integer). If this is not defined, it will be full width. Minimum value of 150. |
loginWindowHeight | integer | Login Window webview height (Integer). If this is not defined, it will be full height. Minimum value of 150. |
loadPageTitle | string | When no network connection or a profile is not defined, this title is shown in an HTML view to the user when cloud login is configured. |
loadPageInfo | string | When no network connection or a profile is not defined, this text is shown in an HTML view to the user when cloud login is configured. |
loginWindowBackgroundImageURL | string | URL to an image to show in the background while logging in. Default value: file:///System/Library/Desktop Pictures/Monterey Graphic.heic. |
menuItemIconData | data | Base64 data of icon. Should be 48 x 48. |
menuItemIconCheckedData | data | Base64 data of icon with checkmark. Should be 48 x 48. |
menuItemWindowBackgroundImageURL | string | URL to an image to show in the background of the window that appears when logged in and prompting for Active Directory username and password. |
shouldLoginWindowBackgroundImageFillScreen | boolean | Set the background image to Fill Screen rather than Fit to Screen |
passwordChangeURL | string | Add a menu item for changing the password that will open this URL when the menu item is selected. |
redirectURI | string | The URI passed back to the webview after successful authentication. Default value: xcreds://auth/ |
shouldShowCloudLoginByDefault | boolean | Determine if the Mac login window or the cloud login window is shown by default. When not set or set to true, show cloud login. If false, shows Mac login. |
refreshRateHours | integer | The number of hours between checks. Default value: 3. Minimum value: 0. Max value: 168. |
refreshRateMinutes | integer | The number of minutes between checks. Default value: 0. Minimum value: 0. Max value: 59. This value is added to refreshRateHours. If refreshRateHours is 0, minimum for refreshRateMinutes becomes 5. |
scopes | string | Scopes tell the identify provider what information to return. Note that the values are provided with a single space between them. Provide the following values the follow IdPs: Google: profile openid email Azure: profile openid offline_access Note that Google does not support the offline_access scope so instead use the preference shouldSetGoogleAccessTypeToOffline. Azure provides unique_name which is mapped to the local user account by using the prefix before “@” in unique_name and matching to the short name of a user account. Google provides “email” and is matched in the same way. |
shouldSetGoogleAccessTypeToOffline | boolean | When using Google IdP, a refresh token may need be requested in a non-standard way. |
shouldPromptForADPasswordChange | boolean | If the domain controller returns back that the password is expired or needs to be changed, prompt the user. If this is set to false, login will fail and an error message will be shown. |
shouldShowSignInMenuItem | boolean | Determine if the Sign In menu item is shown in the XCreds menu. When not set or set to true, show Sign In. If false, the Sign In menu item is hidden. |
shouldPreferLocalLoginInsteadOfCloudLogin | boolean | Favor using XCreds’ local login screen over the cloud login UI. |
shouldVerifyPasswordWithRopg | boolean | (Deprecated in v4.0) When verifying password in the menu app, use ROPG. |
ropgClientID | string | (Deprecated in v4.0) ROPG Client ID for use when checking password. |
ropgClientSecret | string | (Deprecated in v4.0) ROPG Client Secret for use when checking password. |
shouldUseROPGForLoginWindowLogin | boolean | When verifying password in the login window, use ROPG. |
shouldUseROPGForMenuLogin | boolean | When verifying password in the menu app, use ROPG. |
shouldUseROPGForPasswordChangeChecking | boolean | When verifying local password matches cloud password in the background, use ROPG. If set to false, the refresh token will be used to verify password change. |
resource | string | Resource URL when using ROPG. Typically needed only for Azure. Common value is https://graph.microsoft.com |
ropgResponseValue | string | When a ROPG request is completed succesfully to verify password, it may return an error that two factor is required. Add the response string that is returned in the JSON response. For Azure, it is typically interaction_required. |
hideIfPathExists | string | Don’t show the UI if this key is defined and a file or folder exists at this path. |
aliasName | string | Name of OIDC claim that contains an alias to add to a user account. Usually this is the “upn” (eg syd@twocanoes.com) so the user can log in at the standard login window the same as the IdP login window. Adds the value to record name of the user account as an alias. |
autoRefreshLoginTimer | integer | Timer for automatically refreshing login screen in seconds. If set to 0, does not automatically refresh. |
cloudLoginText | string | Text for return to cloud login on Mac login screen |
shouldShowAboutMenu | boolean | Show the About Menu item menu. Default value: true |
shouldShowMenuBarSignInWithoutLoginWindowSignIn | boolean | If the discovery URL is defined and there are no tokens or tickets, the sign in window in the user session will show even if the user did not log in from the XCreds Login Window |
refreshBannerText | string | Text at top of window shown in user session when prompting for password. |
shouldShowRefreshBanner | boolean | Show text at the top of the prompt window when tokens expire. |
shouldShowConfigureWifiButton | boolean | Show Configure WiFi button in XCreds Login. |
shouldShowShutdownButton | boolean | Show Shutdown button in XCreds Login. |
shouldShowRestartButton | boolean | Show Restart button in XCreds Login. |
shouldShowSystemInfoButton | boolean | Show Configure System Info in XCreds Login. |
shouldShowPreferencesOnStart | boolean | Show Settings on start if none are defined. Default value: false |
shouldPromptForMigration | boolean | Prompt for local account username and password if no account was mapped and there are standard users already on the system. |
shouldAllowKeyComboForMacLoginWindow | boolean | Allow key combo (control-option return) to switch logon window. Use command-option-control-return for Mac Login Window. |
keyCodeForLoginWindowChange | integer | key code for shouldAllowKeyComboForMacLoginWindow. If not defined, it is return or enter. If this is defined, this key is used with control-option to switch to login window and command-option-control and this key is used to switch to Mac Login Window. Uses CGKeyCode (for example, enter is 76 and return is 36) |
shouldShowMacLoginButton | boolean | Show the Mac Login Window button in XCreds Login. |
shouldShowLocalOnlyCheckbox | boolean | Show the local only checkbox on the local login page |
usernamePlaceholder | string | Placeholder text in local / AD login window for username |
passwordPlaceholder | string | Placeholder text in local / AD login window for password |
shouldShowSupportStatus | boolean | Show message in XCreds Login reminding people to buy support. |
shouldShowQuitMenu | boolean | Show Quit in the menu item menu. Default value: true |
shouldShowVersionInfo | boolean | Show the version number and build number in the lower left corner of XCreds Login. |
showDebug | boolean | Show push notifications for authentication progress. Default value: false |
username | string | When a user uses cloud login, XCreds will try and figure out the local username based on the email or other data returned for the IdP. Use this value to force the local username for any cloud login. Provide only the shortname. |
KeychainReset | boolean | Reset the keychain without prompting if the login password doesn’t match the local password. |
PasswordOverwriteSilent | boolean | Update the password silently to the new one. Used with the KeychainReset if the user has a secure token. |
HideExpiration | boolean | Hide AD Expiration even if defined in AD Account |
localAdminUserName | string | Username of local admin user. DO NOT SET THIS IN PREFERENCES. It is recommended to set this with the settingsOverrideScriptPath script. This user is used to reset the keychain if the user forgets their local password and to setup a secure token for newly created users. |
localAdminPassword | string | Password of local admin user. DO NOT SET THIS IN PREFERENCES. It is recommended to set this with the settingsOverrideScriptPath script. This user is used to reset the keychain if the user forgets their local password and to setup a secure token for newly created users. |
resetPasswordDialogTitle | string | Title of dialog prompting user to enter in their prior local password. |
systemInfoButtonTitle | string | The title of the button for system info in the bottom right corner of the login screen. This can either be plain text or one of these special values: .os, .hostname, .ipaddress, .serial, .mac, .computername, .ssid. Using the special value will populate the associated information as the button title. |
verifyPassword | boolean | When cloud password is changed and the local keychain password and local user account needs to be changed, a verification dialog can be shown to verify the password. Default value: true |
shouldDetectNetworkToDetermineLoginWindow | boolean | Check if network is up. If not, select username and password login window. |
idpHostName | string | Hostname of the page that has the password field. When the user submits the form, XCreds will use idpHostName to identify a page it needs to look for the password field. The password value is identified by an HTML id defined by passwordElementID. If this value is not defined. XCreds will look for login.microsoftonline.com and accounts.google.com. This value is commonly set for other IdP’s and for Azure environments that use ADFS. |
idpHostNames | array | array of hostnames of the page that has the password field. |
adUserAttributesToAddToLocalUserAccount | array | array of AD user attributes to add to local directory user account |
passwordElementID | string | Password element id of the html element that has the password. It is read by using JavaScript to get the value (for example, for Azure, the JavaScript document.getElementById(‘i0118’).value is sent. If this default is not set, standard values for Azure and Google Cloud will be used. To find out this value, use a browser to inspect the source of the page that has the password on it. Find the id of the textfield that has the password. Fill in the password and then open the JavaScript console. Run: document.getElementById(‘passwordID’).value changing “passwordID” to the correct element ID. If the value you typed into the textfield is returned, this is the correct ID. |
map_firstname | string | Local DS to OIDC/AD Mapping for First Name. Default value: “given_name” (OIDC), “givenName” (AD). map_firstname should be set to an OIDC claim/AD Attribute for first name. |
map_lastname | string | Local DS to OIDC/AD Mapping for Last Name. Default value: “family_name” (OIDC), “sn” (AD). map_lastname should be set to an OIDC claim for last name. |
map_fullname | string | Local DS to OIDC/AD Attribute Mapping for Full Name. Default value: “name”(OIDC), “displayName” (AD). map_fullname should be set to an OIDC claim/AD Attribute for full name. |
map_username | string | Local DS to OIDC Mapping/AD Attribute for Name. Default value: “name” (OIDC), “userPrincipalName” (AD). map_username should be set to an OIDC claim/AD Attribute for name. The macOS username will be set as the portion of this value before an @ symbol if present. |
map_fullusername | string | Local DS to OIDC Mapping for Full Username (for example, freddy@twocanoes.com) Default value: “unique_name”. map_username should be set to an OIDC claim for full username. |
map_uid | string | Local DS to OIDC Mapping/AD Attribute for UID at initial user creation. If not set, the uid will be set to the next available. If the mapped UID is used, login will fail. |
map_password_expiry | string | Password expiry mapping to claim. If this value is set to an OIDC claim, the value in that claim should be the number of seconds from the token issued time (iat) to the expiry date. |
settingsOverrideScriptPath | string | Script to override defaults. Must return valid property list with specified defaults. Script must exist at path, be owned by _securityagent and writable and executable only by _securityagent. |
menuItems | array | Menu Items |
Shares | array | Add menu item and mount/automount shares |
HomeMountEnabled | boolean | Show and mount home directory from AD profile if defined. |
HomeAppendDomain | boolean | Append the domain name to the share defined in the profile. |
shareMenuItemName | string | Name for Shares menu item. Default: “Shares”. |
Preferences Version
The preferences shown on this guide are for the current version of XCreds. When a new version of XCreds is released the new preferences manifest is sent to Profile Creator, however there may be a delay before Profile Creator is updated to reflect these new preferences. If new keys are not yet shown in Profile Creator see more information on how to use new preference keys.
Credential Provider
XCreds provides an option to automatically enter login credentials when using Safari. When enabled, this allows XCreds to provide Single Sign-On (SSO) functionality when a user needs to sign in to a web service with the same username and password as their macOS sign-in. To enable this, the XCreds menubar app must be launched at least once for each user. This can be done either with MDM or by installing the XCreds Launch Agent. The user will also need to enable Touch ID. Once the XCreds menubar app has launched there will be a new item added to macOS System Settings > General > AutoFill & Passwords
. Find the item shown for XCreds Login Autofill
and click to enable it. Once this has been enabled for a user, the menubar does not need to be running and can be quit if desired. Then to use autofill, go to a web service sign-in page in Safari. In the sign-in form click the lock pulldown icon and press the down arrow. Click the option shown for XCreds Login Autofill...
and then use Touch ID. When Touch ID is confirmed, XCreds will automatically enter the username and password. Autofill can be used for any web service sign-in that uses the same credentials configured for XCreds.
Scripting System Defaults
XCreds preferences can also be configured by using a script to set system defaults. More information is available on how this is done.
Troubleshooting
Payload Scope
If the current mobile config file used for XCreds settings was recently created with Profile Creator, double-check that Profile Creator has the General tab section for Payload Scope is set to System
. If this is left as the default value of User
, the XCreds login window web view will display an error or waiting message.
Client ID
Make sure to update the XCreds settings mobileconfig file value for clientID
to the value for your identity provider account. For example, in Azure, the clientID can be found from the Azure Portal by searching for App Registrations
, then clicking All applications
and finding the record used for XCreds. This will show the value to use for XCreds for Application (client) ID
.
Redirect URI
It may be necessary to verify the mobileconfig file value for redirectURI
. This can be any value but must match configuration set in the identity provide account used. For example, in Azure, go to Azure Portal > App Registrations
> All applications
. Find the application entry used for XCreds. Click on Redirect URIs
and verify the correct value to use in the mobileconfig file or add a new redirect URI in Azure Portal for this.
Background Image URL
The setting for loginWindowBackgroundImageURL
should change both the XCreds cloud login window background and the XCreds local login window. The image for this needs to be of type heic, png, or jpeg. Also to be able to see this background on the XCreds cloud login window, the settings for loginWindowWidth
and loginWindowHeight
need to be set in the profile as well to, for example, 500 each.
Kerberos Ticket
After configuring XCreds for Active Directory and signed in as an AD user, to get a Kerberos ticket the XCreds menubar item needs to be running or should be launched from the Applications folder.
Override Script
When using the configuration for settingsOverrideScriptPath
, the script file should be owned by _securityagent
and have permissions 700.
For example, for a script located at /usr/local/bin/override.sh, run the following commands:
sudo chown securityagent /usr/local/bin/override.sh
sudo chmod 700 /usr/local/bin/override.sh
CreateAdminIfGroupMember
When using this preference key it may be necessary to add configuration in the identity provider console. For Azure as an example it is necessary to go to the Azure console, navigate to App Registrations
, and find the app registration used with XCreds. Then on the left side, click Manage
, then Token configuration
and click Add groups claim
. Check the boxes for Security groups
, Directory roles
, and All groups
. Then click save. Once this is done go to Groups
in Azure console, create a new group, and note its Object Id
. Once this is done and an Azure user account is assigned to the group, create an XCreds configuration profile and set the CreateAdminIfGroupMember
preference key value to be the Object Id
for the Azure group that was created. This preference configuration will then allow XCreds to create the related user as an admin when first signing in to macOS.
Shares
XCreds can mount Active Directory shared drives when available by using the preference Shares
. Note that this requires configuration of shared drives on the Active Directory server. Depending on configuration it may be necessary to specify Active Directory group membership for a user to use shares with XCreds. When using Profile Creator it is not possible to edit the preference component for Shares > Groups. If Groups
is required it is recommended to edit the mobileconfig file separately with a text editor to enter Group
information.
More Info
More information is available in the XCreds knowledge base for other topics including the following items.
- How XCreds maps cloud authentication to a local user account
- Using new XCreds preference keys in Profile Creator
- Setting XCreds preferences with defaults
- Customizing mapped fields with XCreds
- How to configure Menubar items
- How to Use both Cloud OIDC and Active Directory
- How to use Active Directory shared drives
- How to use XCreds Launch Agent
Video
See the video on Youtube
Keep In Touch
Sign Up for XCreds security and product updates
Support
Please join the XCreds channel on MacAdmins Slack for any questions you have. Paid support is available from Twocanoes Software.
Thanks
Special thanks to North Carolina State University and Everette Allen for supporting this project.
OIDCLite is Copyright (c) 2022 Joel Rennich (https://gitlab.com/Mactroll/OIDCLite) under MIT License.
XCreds is licensed under BSD Open Source License.