MFA for Password Checkout

Centrify provides the ability to enforce multi-factor authentication when checking out a password. This provides added security for your tenant, by requiring an authenticated user to satisfy security challenges in order to check out a password for another account.

This document describes the API workflow to proceed through MFA for password checkout. This involves the following steps:

  • Query Centrify for accounts.
  • Get the grant string for the account on which you want to check out the password.
  • Get the MFA security challenges for checking out the account's password.
  • Poll to see if Oob challenges have been satisfied.
  • Check out the password.
  • Check in the password when you're done with it.

Before continuing, ensure you are familiar with authentication in Centrify.

Step 1. Get a list of Accounts

The first step is to invoke a RedRock Query to get a list of all accounts. This is done by setting the Script field in the body to @/lib/server/get_accounts.js(mode:'AllAccounts', newcode:true, localOnly:true):

POST /RedRock/query

{  
   "Script":"@/lib/server/get_accounts.js(mode:'AllAccounts', newcode:true, localOnly:true)",
   "Args":{  
      "PageNumber":1,
      "PageSize":100,
      "Limit":100000,
      "SortBy":"",
      "direction":"False",
      "Caching":-1
   }
}

The response contains account information for various entities. In the example below, information is returned for the vault account that we want to check out the password on:

{  
   "success":true,
   "Result":{  
      "IsAggregate":false,
      "Count":14,
      "Columns":[  
         {  
            "Name":"ID",
            "IsHidden":false,
            "DDName":null,
            "Title":"ID",
            "DDTitle":null,
            "Description":null,
            "Type":12,
            "Format":null,
            "Width":36,
            "TableKey":null,
            "ForeignKey":null,
            "TableName":null
         },
         ...
      ],
      "FullCount":14,
      "Results":[  

         {  
            "Entities":[  
               {  
                  "Type":"VaultAccount",
                  "Key":"dcefgefg-cb2d-4988-940e-f096afa7c487",
                  "IsForeignKey":false
               },
               ...        
            ],
            "Row":{  
               "IsAdministrativeAccount":null,
               "Name":"csssup-centos6",
               "User":"jtest",
               "IsFavorite":null,
               "AccountDiscoveredTime":null,
               "Status":"",
               "UseWheel":null,
               "ID":"dcefgefg-cb2d-4988-940e-f096afa7c487",
               "Host":"abcdabcd-ac5a-41be-8c4e-0ef427e6d565",
               "IsManaged":null,
               "Mode":null,
               "Description":"",
               "ActiveSessions":"0",
               "ActiveCheckouts":"0",
               "ComputerClass":"Unix",
               "FQDN":"csssup-centos6.resource.centrify.lab",
               "PasswordResetLastError":"",
               "DefaultCheckoutTime":15,
               "DatabaseID":null,
               "WorkflowEnabled":"1",
               "ProxyUser":"",
               "SessionType":"Ssh",
               "DomainID":null,
               "PasswordResetRetryCount":0,
               "WorkflowApprover":"{\"Type-generated-field\":...}",
               "NeedsPasswordReset":"NotNeeded",
               "LastChange":"\/Date(1518041891055)\/",
               "MissingPassword":null,
               "ServerID":"abcdabcd-ac5a-41be-8c4e-0ef427e6d565"
            }
         },
 
         ...
      ],
      "ReturnID":""
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Step 2. Get the Grant String for the Vault Account

The next step is to invoke the /Acl/GetEffectiveRowRights endpoint to get a grant string for that vault account. Pass in the ID returned in the previous call via the 'RowKey' field:

POST /Acl/GetEffectiveRowRights

{  
   "Rows":[  
      {  
         "Table":"VaultAccount",
         "RowKey":"dcefgefg-cb2d-4988-940e-f096afa7c487",
         "ReduceSysadmin":true
      },
      ...
   ]
}

The response contains the grant string:

{  
   "success":true,
   "Result":[  
      {  
         "GrantStr":"0000000000000000000000000000000000000000000110110000000011111111",
         "RowKey":"dcefgefg-cb2d-4988-940e-f096afa7c487",
         "Table":"VaultAccount"
      },
      ...
   ],
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Step 3. Start the Check Out Process

Next, start the pre-checkout process by invoking the /ServerManage/PreCheckout endpoint and pass it the ID for the vault account:

POST /ServerManage/PreCheckout

{  
   "PVID":"dcefgefg-cb2d-4988-940e-f096afa7c487"
}

The result field contains details about the checkout such as 'Life' which indicates how long the password can remain checked out:

{  
   "success":true,
   "Result":{  
      "Life":15,
      "Status":"OK",
      "ReportId":null
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Try the API in Postman:
Try the API in Postman.
Click here for help with using our sample Postman collection.

Now that the pre-checkout process is successful, invoke the /ServerManage/CheckoutPassword endpoint to start the checkout process, passing the vault account ID via the ID field:

POST /ServerManage/CheckoutPassword

{  
   "ID":"dcefgefg-cb2d-4988-940e-f096afa7c487"
}

The response contains ChallengeId which identifies the first challenge:

{  
   "success":false,
   "Result":{  
      "ChallengeId":"_dc_FUArvUqKYaW0dpu9nrGGQ1xdRRZMGvOPd755_MQ1"
   },
   "Message":"You must respond to a challenge to proceed.",
   "MessageID":null,
   "Exception":null,
   "ErrorID":"ChallengeRequired",
   "ErrorCode":null,
   "InnerExceptions":null
}

Step 4. Start the Challenges

Start the MFA security challenges by invoking the Security/StartChallenge endpoint and passing the ChallengeId returned from the previous call:

POST /Security/StartChallenge

{  
   "TenantId":"",
   "User":"[email protected]",
   "Version":"1.0",
   "AssociatedEntityType":"Portal",
   "AssociatedEntityName":"Portal",
   "ExtIdpAuthChallengeState":"",
   "ChallengeStateId":"_dc_FUArvUqKYaW0dpu9nrGGQ1xdRRZMGvOPd755_MQ1"
}

The Mechanisms field in the response contains the MechanismId identifying the security challenge that needs to be satisfied. In the following example, an Oob challenge has been initiated requiring the user to click a link in an email:

{  
   "success":true,
   "Result":{  
      "ClientHints":{  
         "PersistDefault":false,
         "AllowForgotPassword":false,
         "AllowPersist":false
      },
      "TenantId":"AAU0350",
      "Summary":"NewPackage",
      "SessionId":"UD_Wa19jAMo82hznXUaQd_voK8dMV4ZAmA2SBSTP7Hw1",
      "Challenges":[  
         {  
            "Mechanisms":[  
               {  
                  "PromptSelectMech":"Email... @centrify.com",
                  "Name":"EMAIL",
                  "AnswerType":"StartTextOob",
                  "PartialAddress":"centrify.com",
                  "MechanismId":"c-ZGYomIeQxa3w41DXEbqShZoFzboJ1ItQLAAdMSpD01",
                  "PromptMechChosen":"Click the link in the email sent to [email protected]"
               }
            ]
         }
      ],
      "Version":"1.0"
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Once the challenge has been started, you must poll Centrify by repeatedly invoking the /Security/AdvanceAuthentication endpoint until the response indicates that the security challenge has been satisfied:

POST /Security/AdvanceAuthentication

{  
   "TenantId":"AAU0350",
   "SessionId":"UD_Wa19jAMo82hznXUaQd_voK8dMV4ZAmA2SBSTP7Hw1",
   "PersistentLogin":null,
   "MechanismId":"c-ZGYomIeQxa3w41DXEbqShZoFzboJ1ItQLAAdMSpD01",
   "Action":"StartOOB"
}

The following example response indicates OobPending for the Summary field which means the security challenge has not yet been satisfied:

{  
   "success":true,
   "Result":{  
      "Summary":"OobPending"
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

The following example response indicates a value other than OobPending for the Summary field. Since there is only one challenge in this example, the value of LoginSuccess for the Summary field indicates that the user has been successfully authenticated to check out the password:

{  
   "success":true,
   "Result":{  
      "EmailAddress":"[email protected]",
      "Auth":"61F82...",
      "User":"[email protected]",
      "Summary":"LoginSuccess",
      "SystemID":"AAU0350",
      "CustomerID":"AAU0350",
      "PodFqdn":"support.my.centrify.com",
      "DisplayName":"J N",
      "SourceDsType":"CDS",
      "UserId":"d422fdd8-0f5c-4834-8894-bb9f749515f4",
      "UserDirectory":"CDS",
      "AuthLevel":"Normal"
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Step 5. Get the Password

The password is now available to check out. Invoke the /ServerManage/CheckoutPassword endpoint and set ID to the account ID:

/ServerManage/CheckoutPassword

{  
   "ID":"dcefgefg-cb2d-4988-940e-f096afa7c487"
}

The COID field in the response contains the ID of the checkout that can be used in a subsequent call to check the password in:

{  
   "success":true,
   "Result":{  
      "COID":"875f2a4e-ccd8-42eb-9250-b3ee103c4f0e",
      "Password":"hello12345"
   },
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}

Step 6. (Optional) Check in the Password

Once you're done with the password, invoke the /ServerManage/CheckinPassword endpoint to check the password back in. Pass the COID value returned above from the checkout endpoint via the ID field:

POST /ServerManage/CheckinPassword

{  
   "ID":"875f2a4e-ccd8-42eb-9250-b3ee103c4f0e",
   "RRFormat":true
}

Note: if you don't check in the password, it will expire after the timeout period configured on the Admin Portal.

The success field indicates the result fo the checkin operation:

{  
   "success":true,
   "Result":true,
   "Message":null,
   "MessageID":null,
   "Exception":null,
   "ErrorID":null,
   "ErrorCode":null,
   "InnerExceptions":null
}