Workflow Definitions Configuration Parameters
This section provides in-depth explanations and examples for using configuration parameters in workflow A workflow is a series of steps necessary to complete a process. In the context of Keyfactor Command, it refers to the workflow builder, which allows you automate event-driven tasks when a certificate is requested or revoked. definitions (see Configuration Parameters). The configuration parameters vary depending on the type of workflow step. The below information is broken down by step type. Most steps have at least one example, though the examples may incorporate more than one step type. The following examples are provided:
-
Invoke REST Request and Set Variable Data with Variable Passing
-
Use Custom PowerShell with Embedded REST Request, Send Email, and Require Approval
For an overview of the types of workflow steps, see Workflow Steps.
Invoke REST Request
Figure 172: Tokens are Highlighted
- Headers: Enter any headers needed for your request. For a Keyfactor API A set of functions to allow creation of applications. Keyfactor offers the Keyfactor API, which allows third-party software to integrate with the advanced certificate enrollment and management features of Keyfactor Command. request, this might look like:x-keyfactor-requested-with: APIClient
x-keyfactor-api-version: 1Tip: For a Keyfactor API request, version 1 is assumed if no version is specified. Content type and authorization headers do not need to be specified, since those are addressed elsewhere in the configuration. - Variable to Store Response in: Provide a name for the parameter A parameter or argument is a value that is passed into a function in an application. in which to store the response data from your request. You can then reference this parameter from subsequent steps in the workflow.
Tip: The response is stored as a serialized JObject. To make use of only a portion of the response data in your subsequent step, use JSON path syntax. For example, say you returned the data from a GET /Agents request in a variable called MyResponse and you wanted to reference the ClientMachine name for the orchestrator Keyfactor orchestrators perform a variety of functions, including managing certificate stores and SSH key stores. in a subsequent email message. To limit the data to the first result (0) and only the ClientMachine name, in the email message you would enter the following:$(MyResponse.[0].ClientMachine)
- Verb: In the dropdown, select the type of request you wish to make (e.g. GET, POST).
- Use Basic Authentication: Check this box to use Basic authentication for the request. If you do not check this box, Windows authentication in the context of the Keyfactor Command application pool user will be used (see Create Service Accounts for Keyfactor Command).
- Username and [Password]: Enter the username and password to use for authentication if Use Basic Authentication is checked. In the Username and Password dialogs, the options are Load From Keyfactor Secrets or Load From PAM Provider.
- URL: Enter the request URL for the request, including tokens if desired. For a Keyfactor API request, this might look like (with query parameters):https://keyfactor.keyexample.com/KeyfactorAPI/Certificates?pq.queryString=CN%20-contains%20%22appsrvr14%22%20AND%20CertStorePath%20-ne%20NULL
Or, with tokens:
https://keyfactor.keyexample.com/KeyfactorAPI/Certificates/$(certid)Note: To prevent REST requests from being made to inappropriate locations by malicious users, configure a system environment variable of KEYFACTOR_BLOCKED_OUTBOUND_IPS on your Keyfactor Command server pointing to the IP address or range of addresses in CIDR format that you wish to block. Both IPv4 and IPv6 addresses are supported. More than one address or range may be specified in a comma-delimited list. For example:192.168.12.0/24,192.168.14.22/24When a REST request is made where the URL is either configured to a blocked IP address or resolves via DNS The Domain Name System is a service that translates names into IP addresses. to a blocked IP address, the REST request will fail.
-
Content-Type: In the dropdown, select the content type for the request:
-
application/json
-
-
Request Content: The request body of the REST request, if required, with tokens, if desired. For a Keyfactor API request, this will vary depending on the request and might look like (for a PUT /Certificates/Metadata request):
Copy{
"Id": "$(certid)",
"Metadata":{
"RevocationComment":"$(cmnt)"
}
}Note: This example assumes you have a metadata field called RevocationComment (see Certificate Metadata).
For an example using a Keyfactor API endpoint An endpoint is a URL that enables the API to gain access to resources on a server. within a PowerShell script, see Use Custom PowerShell with Embedded REST Request, Send Email, and Require Approval. For an example using an Invoke REST Request and a PowerShell step passing data between them, see Invoke REST Request and Set Variable Data with Variable Passing.
Example: Invoke REST Request for Data Lookup on Enrollment
The following example takes the requester for an enrollment request and uses that to look up some information about the requester’s SSH The SSH (secure shell) protocol provides for secure connections between computers. It provides several options for authentication, including public key, and protects the communications with strong encryption. user record. This example uses a PowerShell step, a REST Request step, and an email step to deliver the information about the SSH user.
To do this, first create the PowerShell step. Here we use a Set Variable Data step (see Set Variable Data) since no functions need to be called outside the confines of Keyfactor Command other than those that are supported within Set Variable Data, though you could use a Custom PowerShell Script step instead. Add Script Parameters to pull the requester into the script (see Figure 173: Requester Lookup Example: Add Parameters).
In the Insert PowerShell Script field, enter a script similar to the following:
# Declare your parameters at the beginning
param(
[string]$Requester
)
#Convert the requester to JSON
$RequesterJSON = ($Requester | ConvertTo-Json)
# Build the query for the REST step
$Query = "Username -eq $RequesterJSON"
# Return the query to the workflow as a hashtable
$result = @{ "Query" = $Query }
return $result
Next, create the REST request step with the following values:
-
Headers: The GET /SSH/Users method has a version 2 with additional features. To access version 2, this version must be specified in the header.
Copy{
"x-keyfactor-requested-with": [
"APIClient"
],
"x-keyfactor-api-version": [
"2"
]
}Figure 174: Requester Lookup Example: Add Headers for REST Request
-
Variable to Store Response in: MyResponse
-
Verb: GET
-
URL: Note that the $(Query) from the PowerShell step is provided in the URL (keyfactor.keyexample.com is your Keyfactor Command server name).
Copyhttps://keyfactor.keyexample.com/KeyfactorAPI/SSH/Users?QueryString=$(Query)
-
Content-Type: application/json
-
Request Content: None (The request is provided in the URL; there is no body for this endpoint.)
This REST step takes the Query built in the PowerShell step, containing the requester’s username, and submits it to the GET /SSH/Users endpoint. The response contains all the information from the user’s SSH key record.
Next, create the Send Email step. In the configuration parameters, give your email a Subject that will help highlight the information:
Certificate Enrollment Request for $(request:cn)
In the main Message of the email, provide the required information using tokens, including the information retrieved from the GET /SSH/Users endpoint (see Substitutable Text Tokens for Workflow):
Hello,
A certificate using the $(template) template was requested by $(requester:displayname) from $(CA) on $(subdate).
The certificate details include:
<ul>
<li>CN: $(request:cn)</li>
<li>DN: $(request:dn)</li>
<li>SANs: $(sans)</li>
<li>App Owner First Name: $(metadata:AppOwnerFirstName)</li>
<li>App Owner Last Name: $(metadata:AppOwnerLastName)</li>
</ul>
The requester’s SSH information includes:
<ul>
<li>ID: $(MyResponse.Result[0].Key.Id)</li>
<li>Email: $(MyResponse.Result[0].Key.Email)</li>
<li>Comments: $(MyResponse.Result[0].Key.Comments.[*])</li>
</ul>
Thanks!
Your Certificate Management Tool
In the Recipients, add all the email recipients who should receive this information.
Invoke REST Request with OAuth
This step type is used only for Keyfactor Command implementations using an identity provider other than Active Directory. If you’re using Active Directory, refer to the Invoke REST Request step type (see Invoke REST Request).
Figure 175: Tokens are Highlighted
-
Headers: Enter any headers needed for your request. For a Keyfactor API request, this might look like:
x-keyfactor-requested-with: APIClient
x-keyfactor-api-version: 1Tip: For a Keyfactor API request, version 1 is assumed if no version is specified. Content type and authorization headers do not need to be specified, since those are addressed elsewhere in the configuration. -
Variable to Store Response in: Provide a name for the parameter in which to store the response data from your request. You can then reference this parameter from subsequent steps in the workflow.
Tip: The response is stored as a serialized JObject. To make use of only a portion of the response data in your subsequent step, use JSON path syntax. For example, say you returned the data from a GET /Agents request in a variable called MyResponse and you wanted to reference the ClientMachine name for the orchestrator in a subsequent email message. To limit the data to the first result (0) and only the ClientMachine name, in the email message you would enter the following:$(MyResponse.[0].ClientMachine) - Verb: In the dropdown, select the type of request you wish to make (e.g. GET, POST).
- Client ID: Enter the ID of the identity provider client that should be used to authenticate the session (see Authenticating to the Keyfactor API).
-
Client Secret: Click the Set\UpdateClient Secret button and in the Client Secret dialog, enter the secret for the identity provider client that should be used to authenticate the session. In the Client Secret dialog, the options are Load From Keyfactor Secrets or Load From PAM Provider.
-
Token Endpoint: The URL of the token endpoint for your identity provider instance. For example:
https://my-keyidp-server.keyexample.com/realms/Keyfactor/protocol/openid-connect/tokenFor Keyfactor Identity Provider, this is included among the information that can be found on the OpenID Endpoint Configuration page, a link to which can be found on the Realm Settings page (see Configuring Keyfactor Identity Provider and Collecting Data for the Keyfactor Command Installation).
-
Scope: One or more scopes that are submitted with the token request, if desired. Multiple scopes should be separated by spaces.
This value is not used for Keyfactor Identity Provider.
-
Audience: An audience value that is submitted with the token request, if desired.
This value is not used for Keyfactor Identity Provider.
-
URL: Enter the request URL for the request, including tokens if desired. For a Keyfactor API request, this might look like (with query parameters):
https://keyfactor.keyexample.com/KeyfactorAPI/Certificates?pq.queryString=CN%20-contains%20%22appsrvr14%22%20AND%20CertStorePath%20-ne%20NULLOr, with tokens:
https://keyfactor.keyexample.com/KeyfactorAPI/Certificates/$(certid)Note: To prevent REST requests from being made to inappropriate locations by malicious users, configure a system environment variable of KEYFACTOR_BLOCKED_OUTBOUND_IPS on your Keyfactor Command server pointing to the IP address or range of addresses in CIDR format that you wish to block. Both IPv4 and IPv6 addresses are supported. More than one address or range may be specified in a comma-delimited list. For example:192.168.12.0/24,192.168.14.22/24When a REST request is made where the URL is either configured to a blocked IP address or resolves via DNS to a blocked IP address, the REST request will fail.
-
Content-Type: In the dropdown, select the content type for the request:
-
application/json
-
-
Request Content: The request body of the REST request, if required, with tokens, if desired. For a Keyfactor API request, this will vary depending on the request and might look like (for a PUT /Certificates/Metadata request):
Copy{
"Id": "$(certid)",
"Metadata":{
"RevocationComment":"$(cmnt)"
}
}Note: This example assumes you have a metadata field called RevocationComment (see Certificate Metadata).
For an example using a Keyfactor API endpoint within a PowerShell script, see Use Custom PowerShell with Embedded REST Request, Send Email, and Require Approval. For an example using an Invoke REST Request to do a data lookup on enrollment, see Invoke REST Request for Data Lookup on Enrollment.
Example: Invoke REST Request and Set Variable Data with Variable Passing
The following example takes the revocation comment entered when a certificate is revoked and puts it together with some other information into a custom metadata field, retaining any existing data in that metadata field. This example uses both a PowerShell step and a REST Request step to demonstrate passing of information from one step to the other.
To do this, first create the PowerShell step. Here we use a Set Variable Data step (see Set Variable Data) since no functions need to be called outside the confines of Keyfactor Command, though you could use a Custom PowerShell Script step instead. Add Script Parameters to pull the revocation comment, submission date, revocation code, user making the revocation request, and the metadata field into which you will place your updated comment (Notes in this example) into the script. Figure 176: Metadata Update Example: Add Parameters shows only four of these. The metadata field Notes is a BigText type field in this example (see Metadata Field Operations).
In the Insert PowerShell Script field, enter a script similar to the following:
# Declare your parameters at the beginning ($Comment, $Notes, $RevCode, $Date, and $RevokeBy)
param(
[string]$Comment,
[string]$Notes,
[string]$RevCode,
[datetime]$Date
[string]$RevokeBy
)
# Append your additional text to the existing text in the metadata Notes field along with the revoker (removing
# the leading 'DOMAIN\' part), submission date, revocation code, and comment entered at revocation,
# and beginning the entry with a newline.
$Notes += "`nRevoked on " + $Date.ToString("MMMM d, yyyy") + " by " + $RevokeBy.SubString($RevokeBy.IndexOf('\')+1) + " with revocation option '" + $RevCode + "' and comment '" + $Comment + "'."
# Return the updated metadata Notes value as MyNotes to the workflow as a hashtable
$result = @{ "MyNotes" = $Notes }
return $result
Next, create the REST request step with the following values:
-
Headers: The API version does not need to be stated since version 1 is the default.
Copy{
"x-keyfactor-requested-with": [
"APIClient"
]
}Figure 177: Metadata Update Example: Add Headers for REST Request
-
Variable to Store Response in: None (there is no output from this command on a success)
-
Verb: PUT
-
Client ID: The client ID from your identity provider implementation (see Authenticating to the Keyfactor API). For example:
Keyfactor-API-Workflow-User -
Client Secret: The client secret from your identity provider implementation (see Authenticating to the Keyfactor API). For example:
WDBvGypDWuquyOmQQneeQp4IvmPDebz4 -
Token Endpoint: The token endpoint from your identity provider implementation. For example:
https://my-keyidp-server.keyexample.com/realms/Keyfactor/protocol/openid-connect/token -
URL: (Where keyfactor.keyexample.com is your Keyfactor Command server name.)
Copyhttps://keyfactor.keyexample.com/KeyfactorAPI/Certificates/Metadata
-
Content-Type: application/json
-
Request Content:
Copy{
"Id": "$(certid)",
"Metadata": {
"Notes": "$(MyNotes)"
}
}
This REST step takes the MyNotes output from the PowerShell step and updates the metadata Notes field to match that value. The resulting value in your Notes field will look something like this (assuming lines one, two and three were preexisting):
Figure 178: Metadata Update Example: Results
Require Approval
Figure 179: Tokens are Highlighted
- Minimum Approvals: Enter the minimum number of users who must approve the request to consider the request approved.
- Denial Email Subject: Enter the subject line for the email message that will be delivered if the request is denied, including tokens if desired.
- Denial Email Message: Enter the email message that will be delivered if the request is denied. The email message can be made up of regular text and tokens. If desired, you can format the message body using HTML. See Table 13: Tokens for Workflow Definitions for a complete list of available tokens.
-
Denial Email Recipients: Click Add, enter a recipient for the denial email, and Save. Each email message can have multiple recipients. You can use specific email addresses and/or use tokens to replace an email address variable with actual email addresses at processing time. Available email tokens include:
-
$(requester:mail)
The certificate requester, based on a lookup in Active Directory of the email address associated with the requester on the certificate.
Note: The $(requester:mail) substitutable special text token is only supported in environments using Active Directory as an identity provider. -
Your custom email-based metadata field, which would be specified similarly to $(metadata:AppOwnerEmailAddress).
-
- Approval Email Subject: Enter the subject line for the email message that will be delivered if the request is approved, including tokens if desired.
- Approval Email Message: Enter the email message that will be delivered if the request is approved. The email message can be made up of regular text and tokens. If desired, you can format the message body using HTML. See Table 13: Tokens for Workflow Definitions for a complete list of available tokens.
- Approval Email Recipients: Click Add, enter a recipient for the approval email, and Save. Each email message can have multiple recipients. You can use specific email addresses and/or use tokens to replace an email address variable with actual email addresses at processing time. Available email tokens include:
$(requester:mail)
The certificate requester, based on a lookup in Active Directory of the email address associated with the requester on the certificate.
Note: The $(requester:mail) substitutable special text token is only supported in environments using Active Directory as an identity provider.Your custom email-based metadata field, which would be specified similarly to $(metadata:AppOwnerEmailAddress).
Figure 180: Configuration Parameters for a Require Approval Workflow Definition Step
For an example using a require approval step with a condition, see Set Variable Data and Require Approval with a Condition.
Example: Use Custom PowerShell with Embedded REST Request, Send Email, and Require Approval
The following example takes information from an enrollment request that is destined for a certificate store and which requires approval and delivers it in an email to the managers designated as approvers of the request to provide them with the information necessary to make the go/no go decision. This example uses a Custom PowerShell step that calls a Keyfactor API method, a Send Email step, and a Require Approval step.
This step needs to be a Use Custom PowerShell step rather than a Set Variable Data step because it calls a Keyfactor API method in a loop within the script. Since the API method needs to be called in a loop to retrieve multiple pieces of data, it’s not practical to do this as a separate Invoke REST Request step.
To do this, first outside of Keyfactor Command create your PowerShell script containing content similar to the following:
# Declare your parameters at the beginning
param(
[string]$StoreData,
[string]$TimeData
)
# Pick one authentication mechanism for the Keyfactor API
# Basic authentication credentials to authenticate to the Keyfactor API
$user = 'KEYEXAMPLE\APIUser'
$pass = 'APIUserSuperSecretPassword'
# Encode Basic authentication credentials
$pair = "$($cred.Username):$($cred.GetNetworkCredential().Password)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"
# Token authentication credentials to authenticate to the Keyfactor API (uncomment the below 9 lines and update appropriately to use token authentication)
#$TokenBody = @{
# grant_type = "client_credentials"
# client_id = "Keyfactor-API-Workflow-User"
# client_secret = "WorkflowAPIClientSecret"
#}
#$TokenHeaders = @{
# 'Content-Type' = 'application/x-www-form-urlencoded'
#}
#$TokenURL = "https://appsrvr18.keyexample.com:1443/realms/Keyfactor/protocol/openid-connect/token"
# Request token from Keyfactor Identity Provider for token authentication (uncomment the below line to use token authentication)
#$TokenValue = Invoke-RestMethod -Method Post -Uri $TokenURL -Headers $TokenHeaders -Body $TokenBody
# Pick an authentication type for the header
$headerAuth = $basicAuthValue
#$headerAuth = "Bearer " + $TokenValue.access_token
# Build the headers for the API request
$headers = @{
"Authorization"=$headerAuth
"Accept"="application/json"
"x-keyfactor-requested-with"="APIClient"
}
# Convert incoming data from JSON
$StoreDataInfo = $StoreData | ConvertFrom-Json
$TimeDataInfo = $TimeData | ConvertFrom-Json
# Initialize Variables introduced in script
$JobTime = ""
$JobTimeHuman = ""
$TimeMessage = ""
$StoreMessage = ""
$StoreList = New-Object System.Collections.Generic.List[System.Object]
$CommandServer = 'keyfactor.keyexample.com'
# Evalulate the scheduled delivery time for the certificate store management job, if present, and populate a return message based on the content
if ("Immediate" -in $TimeDataInfo.PSobject.Properties.Name)
{
$TimeMessage = "The certificate has been scheduled to be delivered at the next orchestrator run."
}
elseif ("ExactlyOnce" -in $TimeDataInfo.PSobject.Properties.Name)
{
# Convert the certificate store job time to a human readable date/time
$JobTime = [DateTime]($TimeDataInfo.ExactlyOnce.Time)
$JobTimeHuman = $JobTime.ToString("M/dd/yyyy h:mm tt")
$TimeMessage = "The certificate has been scheduled to be delivered at the following time: $JobTimeHuman."
}
else
{
$TimeMessage = " "
}
# Pull out the display names of the certificate stores based on the store IDs in the incoming store info
foreach ($Store in $StoreDataInfo){
$response = Invoke-WebRequest -Uri "https://$($CommandServer)/KeyfactorAPI/CertificateStores/$($store.StoreId)" -Method:Get -Headers $headers `
-ContentType "application/json" -ErrorAction:Stop -TimeoutSec 60
$responseContent = $response.Content | ConvertFrom-Json
#Add the store to the store list
$StoreList.Add($responseContent.DisplayName)
}
# Evaluate whether any stores were returned and build a message that includes the store list if so, and an alternate message if not
if ($StoreList.Count -gt 0)
{
$StoreMessage = "If approved, the certificate will be delivered to the following stores:<br /><br />" + ($StoreList -join "<br />")
}
else
{
$StoreMessage = "If approved, the certificate will be available for download in the Keyfactor Command Management Portal. It has not been scheduled for delivery to any certificate stores."
}
# Return the time message and store message to the workflow as a hashtable
$result = @{ "TimeMessage" = $TimeMessage; "StoreMessage" = $StoreMessage }
return $result
Next, use the POST /Extension/Scripts API endpoint (see POST Extensions Scripts) to import your PowerShell script into the Keyfactor Command database before beginning to edit your workflow.
Once your PowerShell script has been imported into the Keyfactor Command database, you may begin creating your workflow. To create the Use Custom PowerShell step, add Script Parameters to pull the certificate store data—$(Stores)—and schedule time for the management job to add the certificate to the certificate stores—$(ManagementJobTime)—into the script as shown in Figure 181: Use Custom PowerShell with Embedded REST Request: Add Parameters. The $(Stores) and $(ManagementJobTime) tokens are not among those that appear in the dropdown.
In the PowerShell Field Name field, in the dropdown select the script you uploaded to the database.
Next, create the Send Email step. In the configuration parameters, give your email a Subject that will help highlight the request:
ACTION REQUIRED: Certificate Enrollment Request for $(request:cn)
This tells your users that they need to do something and includes the CN A common name (CN) is the component of a distinguished name (DN) that represents the primary name of the object. The value varies depending on the type of object. For a user object, this would be the user's name (e.g. CN=John Smith). For SSL certificates, the CN is typically the fully qualified domain name (FQDN) of the host where the SSL certificate will reside (e.g. servername.keyexample.com or www.keyexample.com). of the requested certificate in the subject line.
In the main Message of the email, tell your users what they need to do and provide the information from the request that will allow them to make an informed decision using tokens (see Substitutable Text Tokens for Workflow) and the certificate store information returned from the PowerShell script:
Hello,
A certificate using the $(template) template was requested by $(requester:displayname) from $(CA) on $(subdate). $(StoreMessage)
$(TimeMessage)
The certificate details include:
<ul>
<li>CN: $(request:cn)</li>
<li>DN: $(request:dn)</li>
<li>SANs: $(sans))</li>
<li>App Owner First Name: $(metadata:AppOwnerFirstName)</li>
<li>App Owner Last Name: $(metadata:AppOwnerLastName)</li>
</ul>
Please review this request and issue the certificate as appropriate by going here:
$(reviewlink)
Thanks!
Your Certificate Management Tool
In the Recipients, add all the email recipients who could possibly approve or deny the request.
Now create your Require Approval step. The step does not need any Conditions. In the Configuration Parameters, enter a value of at least 1 for the Minimum Required Approvals. Give the Denial Email Subject a value something like:
Certificate Enrollment Request Denied for $(request:cn)
And the Approval Email Subject a value something like:
Certificate Enrollment Request Approved for $(request:cn)
Enter an appropriate message for the Denial Email Message. You may use tokens, including the returned values from the PowerShell script. You may want to deliver this message to the requester, so a message similar to this might be appropriate:
Hello $(requester:givenname),
The certificate you requested on $(subdate) in the name $(request:cn) has not been issued for the following reason:
$(approvalsignalcmnts)
The certificate details include:
<ul>
<li>CN: $(request:cn)</li>
<li>DN: $(request:dn)</li>
<li>SANs: $(sans))</li>
<li>App Owner First Name: $(metadata:AppOwnerFirstName)</li>
<li>App Owner Last Name: $(metadata:AppOwnerLastName)</li>
</ul>
For assistance, please contact <a href="mailto:support@keyexample.com">support@keyexample.com</a>.
Thanks!
Your Certificate Management System
Enter an appropriate message for the Approval Email Message. This message would also likely go to the requester and might look similar to:
Hello $(requester:givenname),
The certificate you requested in the name $(request:cn) on $(subdate) was successfully approved with the following comment:
$(approvalsignalcmnts)
The certificate details include:
<ul>
<li>CN: $(request:cn)</li>
<li>DN: $(request:dn)</li>
<li>SANs: $(sans))</li>
<li>App Owner First Name: $(metadata:AppOwnerFirstName)</li>
<li>App Owner Last Name: $(metadata:AppOwnerLastName)</li>
</ul>
You will receive an update when it has been issued. For assistance, please contact <a href="mailto:support@keyexample.com">support@keyexample.com</a>.
Thanks!
Your Certificate Management System
In the Recipients for both the approval and denial emails, enter the token for the requester’s email—$(requester:mail).
In the Signals for the Require Approval step, select the security role(s) to which the users responsible for approving or denying the request belong.
Finish off the workflow process by configuring an issued certificate request alert to let the requester know when the certificate has been issued (see Issued Certificate Request Alerts).
Send Email
Figure 182: Tokens are Highlighted
- Subject: Enter the subject line for the email message that will be delivered when the workflow definition step is executed, including tokens if desired.
-
Message: Enter the email message that will be delivered when the workflow definition step is executed. The email message can be made up of regular text and tokens. If desired, you can format the message body using HTML. For example, for an enrollment pending request notification:
CopyHello,
A certificate using the $(template) template was requested by $(requester:displayname) from $(CA) on $(subdate). The certificate details include:
<table>
<tr><th>Certificate Details</th><th>Metadata</th></tr>
<tr><td>CN: $(request:cn)</td><td>App Owner First Name: $(metadata:AppOwnerFirstName)</td></tr>
<tr><td>DN: $(request:dn)</td><td>App Owner Last Name: $(metadata:AppOwnerLastName)</td></tr>
<tr><td>SANs: $(sans)</td><td>App Owner Email Address: $(metadata:AppOwnerEmailAddress)</td></tr>
<tr><td> </td><td>Business Critical: $(metadata:BusinessCritical)</td></tr>
Please review this request and issue the certificate as appropriate by going here:
$(reviewlink)
Thanks!
Your Certificate Management ToolSee Table 13: Tokens for Workflow Definitions for a list of available tokens.
Note: The $(requester:displayname) substitutable special text token is only supported in environments using Active Directory as an identity provider. - Recipients: Click Add, enter a recipient for the email, and Save. Each email message can have multiple recipients. You can use specific email addresses and/or use tokens to replace an email address variable with actual email addresses at processing time. Available email tokens include:
$(requester:mail)
The certificate requester, based on a lookup in Active Directory of the email address associated with the requester on the certificate.
Note: The $(requester:mail) substitutable special text token is only supported in environments using Active Directory as an identity provider.Your custom email-based metadata field, which would be specified similarly to $(metadata:AppOwnerEmailAddress).
Figure 183: Step Configuration for an Email Workflow Definition Step
For an example using Send Email in a Require Approval workflow, see Use Custom PowerShell with Embedded REST Request, Send Email, and Require Approval.
Set Variable Data
-
Script Parameters: Add any parameters you will use to pass data into your script. These can contain static values or tokens (see Table 13: Tokens for Workflow Definitions). To add a parameter:
-
In the Script Parameters section, click Add.
-
In the Add/Edit Parameter dialog, enter a name for the parameter in the Parameter field. In the Value field, enter either a static value to be passed into the PowerShell script or select from the available tokens to pass the token value into the PowerShell in your parameter.
-
Click Save to save your parameter.
-
-
Insert PowerShell Script: Enter the PowerShell commands to execute. This should be the actual contents of the PowerShell script (the PowerShell commands and supporting components), not a path and filename to an external file.
To receive your defined parameters from the previous step into the PowerShell script, begin the script by declaring the expected parameters like so (referencing the three parameters—TestOne, TestTwo, and TestThree):
Copyparam(
[string]$TestOne,
[int]$TestTwo,
[string]$TestThree
)You may then use these parameters within the script.
To return data from the PowerShell script, create a hashtable of the data you wish to return like so (where $MyField1 and $MyField2 are parameters introduced within the script and the new value in $TestThree is reloaded back into that parameter and used to update that field if the original parameter was set to a token):
Copy$result = @{ "MyFieldOne" = $MyField1; "MyFieldTwo" = $MyField2; "TestThree" = $TestThree }
return $resultThis will result in the following dictionary entries being added to the database and available for output or use in subsequent steps in the workflow:
Copy{["MyFieldOne", "[your value as defined in the script]", ["MyFieldTwo", "[your value as defined in the script]", ["TestThree", "[your value as defined in the script]",]}
You can reference these as tokens in subsequent steps as follows: $(MyFieldOne), $(MyFieldTwo), $(TestThree).
Figure 185: Configuration Parameters for a Set Variable Data Workflow Definition Step
Example: Set Variable Data for Revocation
The following example takes the revocation comment entered when a certificate is revoked and appends an additional comment, including dates, to it. To create this, add Script Parameters to pull the revocation comment, submission date and effective date into the Set Variable Data script as shown in Figure 176: Metadata Update Example: Add Parameters.
Figure 186: Revocation Comment Update Example: Add Parameters
In the Insert PowerShell Script field, enter a script similar to the following:
# Declare your parameters at the beginning ($Comment, $SDate, and $Edate)
param(
[string]$Comment,
[datetime]$SDate,
[datetime]$EDate
)
# Append your additional text to the existing comment along with the submission and effective dates
$Comment += " - Revocation requested on " + $SDate.ToString("g") + " and effective on " + $EDate.ToString("g")
# Return the updated comment to the workflow in the original parameter as a hashtable
$result = @{ "Comment" = $Comment }
return $result
The resulting comment will look something like:
Figure 187: Revocation Comment Update Example: Results
You may reference the updated comment using the standard revocation comment token ($(cmnt)) in subsequent steps in your workflow and may view the updated comment wherever the revocation comment is available for viewing within Keyfactor Command.
Example: Set Variable Data for Enrollment
The following example takes two additional enrollment fields submitted on an enrollment and sets the value of one to a fixed value if the value of the other (a multi-value field) is a given value using a Set Variable Data script. In other words, the possible values for Department (a multi-value field) are:
- Accounting
- E-Commerce
- HR
- IT
- Marketing
- R & D
- Sales
If the value of Department is anything other than Accounting, the value of Code (a string field) can be any value. If the value of Department is Accounting, anything submitted in the Code field by the end user is discarded and replaced by the fixed value for Code provided in the script.
This example provides a solution using a Set Variable Data step type and demonstrates manually unpacking the JSON attribute string. One possible method of doing this is provided in the example. If you prefer, you may instead use the ConvertFrom-Json cmdlet similarly to the example for putting approval comments in a metadata field and avoid the manual string manipulation steps.
To create this, add Script Parameters to pull the additional attributes into the script as shown in Figure 188: Additional Attribute Update Example: Add Parameters
In the Insert PowerShell Script field, enter a script similar to the following:
# Declare your parameters at the beginning
param(
[string]$AdditionalAttributes
)
# Trim brackets off incoming attribute string
$TrimmedAttributes = $AdditionalAttributes.Substring(1,$AdditionalAttributes.Length-2)
# Replace commas bracketed by quotes in attribute string with a temporary string to facilitate splitting (assumes no incoming values contain temp string)
$TempString = "`"######`""
$CleanAttributes = $TrimmedAttributes -replace "`",`"", $TempString
# Split the incoming attribute string into its component values at the temporary string
$SplitAttributes = $CleanAttributes.Split('######')
# Split the incoming attribute string key/value pairs
foreach($attribute in $SplitAttributes){
$attributeComponents = $attribute.Trim() -split ":"
$attributeComponents
Switch($attributeComponents[0].Trim()){
'"Department"' {$Department = $attributeComponents[1].Substring(1,$attributeComponents[1].Length-2)}
'"Code"' {$Code = $attributeComponents[1].Substring(1,$attributeComponents[1].Length-2)}
}
}
# Initialize a hashtable
$UpdatedAttributes = @{}
# Load original attributes in UpdatedAttributes for the else case
if(![string]::IsNullOrWhiteSpace($Code)) {
$UpdatedAttributes['Code'] = $Code
}
if(![string]::IsNullOrWhiteSpace($Department)) {
$UpdatedAttributes['Department'] = $Department
}
# If the value of Department is "Accounting", then the value of Code must be "G5N145"; override submitted value--if any--and use fixed value
if($UpdatedAttributes['Department'] -eq "Accounting") {
$UpdatedAttributes['Code'] = "G5N145"
}
# Return the updated attributes to the workflow in the original parameter as a hashtable
$result = @{ "AdditionalAttributes" = $UpdatedAttributes }
return $result
The updated attributes will be submitted to the CA A certificate authority (CA) is an entity that issues digital certificates. Within Keyfactor Command, a CA may be a Microsoft CA or a Keyfactor gateway to a cloud-based or remote CA. as part of the enrollment package and can be viewed in the workflow instance (see Viewing a Workflow Instance).
Use Custom PowerShell
-
Script Parameters: Add any parameters you will use to pass data into your script. These can contain static values or tokens (see Table 13: Tokens for Workflow Definitions). To add a parameter:
-
In the Script Parameters section, click Add.
-
In the Add/Edit Parameter dialog, enter a name for the parameter in the Parameter field. In the Value field, enter either a static value to be passed into the PowerShell script or select from the available tokens to pass the token value into the PowerShell in your parameter.
-
Click Save to save your parameter.
-
-
PowerShell Script Name: The script contents are stored in the Keyfactor Command database. After uploading your script to the database, select a script from the dropdown on the step. All scripts in the database that have been configured for the workflow will be available for selection. See Extensions Scripts for information on adding scripts to the database. The file must be in JSON-escaped format and have an extension of .ps1. The script should use the same input and output method for parameters as described for the Set Variable Data step type (see Set Variable Data).
Tip: A sample PowerShell script, CustomPowershellExample.ps1, is provided in the workflow directory (default: C:\Program Files\Keyfactor\Keyfactor Platform\ExtensionLibrary\Workflow).
Figure 190: Step Configuration for a Custom PowerShell Workflow Definition Step
Example: Use Custom PowerShell for Enrollment
The following example takes the common name A common name (CN) is the component of a distinguished name (DN) that represents the primary name of the object. The value varies depending on the type of object. For a user object, this would be the user's name (e.g. CN=John Smith). For SSL certificates, the CN is typically the fully qualified domain name (FQDN) of the host where the SSL certificate will reside (e.g. servername.keyexample.com or www.keyexample.com). entered during an enrollment and evaluates it to determine whether the domain suffix ends with “keyexample.com”. If it does, the script does a DNS lookup of the full CN to find the IPv4 address for that name and, if found, adds that value as a SAN The subject alternative name (SAN) is an extension to the X.509 specification that allows you to specify additional values when enrolling for a digital certificate. A variety of SAN formats are supported, with DNS name being the most common. to the request. Two additional SANs are added to the request by removing the “keyexample.com” domain suffix and instead appending the domain suffixes provided in the Domain1 and Domain2 parameters (e.g. mycert.keyother.com and mycert.keyother2.com). If the CN does not have a domain suffix ending with “keyexample.com”, the PowerShell script does nothing.
This step needs to be a Use Custom PowerShell step rather than a Set Variable Data step because it calls a PowerShell command (Resolve-DnsName) that exists outside the confines of Keyfactor Command.
To do this, first use the POST /Extension/Scripts API endpoint (see POST Extensions Scripts) to import your PowerShell script into the Keyfactor Command database before beginning to edit your workflow. Your script file prior to import should contain content similar to the following:
# Declare your parameters at the beginning ($InputCN, $Domain1, $Domain2, and $InputSANs)
param(
[string]$InputCN,
[string]$Domain1,
[int]$Domain2,
[string]$InputSANs
)
# Split the incoming SANs string into its component values
$SplitSANs = $InputSANs.Split(',')
# Initialize variables for the two types of SANs we're handling
$DnsSans = @()
$IpSans = @()
# Add the incoming SANs to the correct list (assumes only IPv4 addresses or DNS SANs will be encountered)
foreach($san in $SplitSANs){
$sanComponents = $san.Trim() -split ":"
Switch ($sanComponents[0].Trim()){
"DnsName" {$DnsSans += ,$sanComponents[1].Trim()}
"IPAddress" {$IpSans += $sanComponents[1].Trim()}
}
}
# Check to see if the incoming CN ends with keyexample.com and, if so, add some SANs.
$Suffix = "keyexample.com"
if ($InputCN.EndsWith($Suffix))
{
# Load just the portion of the CN without the domain name into a variable.
$CNName = $InputCN.SubString(0,$InputCN.Length - $Suffix.Length)
# Do a lookup on the requested CN to find its IPv4 address.
$IPResult = Resolve-DnsName -Name $InputCN -Type A -ErrorAction SilentlyContinue
# If an address is found, add that address as a SAN.
# Also add SANs built with the contents of Domain1, Domain2, and the leading part of the CN
# (e.g. mycert.my-first-other-domain.com and mycert.my-second-other-domain.com).
if ($IPResult -ne $null)
{
$SAN1 = $IPResult.IPAddress
$SAN2 = $CNName + $Domain1
$SAN3 = $CNName + $Domain2
$DnsSans += ,$SAN2
$DnsSans += ,$SAN3
$IpSans += ,$SAN1
# If an IP address is not found, add only the SANs featuring Domain1 and Domain2.
else {
$SAN2 = $CNName + $Domain1
$SAN3 = $CNName + $Domain2
$DnsSans += ,$SAN2
$DnsSans += ,$SAN3
}
}
# Load the resulting IPv4 and DNS SANs into the SANS variable
$UpdatedSANs = @{}
if(![string]::IsNullOrWhiteSpace($DnsSans)) {
$UpdatedSANs['dns'] = $DnsSans
}
if(![string]::IsNullOrWhiteSpace($IpSans)) {
$UpdatedSANs['ip4'] = $IpSans
}
# Return the updated SANs to the workflow as a hashtable (case matters in the return value name "SANs" in order
# to reload the results back into the SANs token)
$result = @{ "SANs" = $UpdatedSANs; }
return $result
Once your PowerShell script has been imported into the Keyfactor Command database, you may begin creating your workflow. To create the Use Custom PowerShell step, add Script Parameters to pull the CN and SANs into the script as shown in Metadata Update Example: Add Parameters, and add to static values to pass in your two additional domain names.
Figure 191: Update SANs Example: Add Parameters
In the PowerShell Script Name field dropdown, select the script you uploaded to the database.
Your enrollment will complete using the updated list of SANs, including any SANs you added manually on the PFX A PFX file (personal information exchange format), also known as a PKCS#12 archive, is a single, password-protected certificate archive that contains both the public and matching private key and, optionally, the certificate chain. It is a common format for Windows servers. enrollment page or in the CSR A CSR or certificate signing request is a block of encoded text that is submitted to a CA when enrolling for a certificate. When you generate a CSR within Keyfactor Command, the matching private key for it is stored in Keyfactor Command in encrypted format and will be married with the certificate once returned from the CA.. You may reference the updated SANs using the standard SANs token ($(sans)) in subsequent steps in your workflow and may view the complete SAN list wherever the SANs are available for viewing within Keyfactor Command.
- Include an Update Certificate Request Subject\SANs step in your workflow (see Update Certificate Request Subject\SANs for Microsoft CAs). This is Keyfactor's preferred solution for workflow due to the limited risk profile.
- Use Keyfactor's SAN Attribute Policy Handler (see Installing the Keyfactor CA Policy Module Handlers). This opens security risks as well, which can be mitigated, however, this is not Keyfactor's preferred solution for workflow.
- Configure your CA to support the addition of SANs outside the initial request (enable the EDITF_ATTRIBUTESUBJECTALTNAME2 flag). Keyfactor does not recommend this solution due to the inherent security risks.
Example: Use Custom PowerShell and Require Approval
The following example takes the approval comment entered when a certificate is enrolled or the approval or denial comment entered when a certificate is revoked using a require approval step and stores the comment in a metadata field. There will be no certificate to associate the metadata field with for an enrollment request that is denied. Normally, approval and denial comments are discarded after a workflow instance is complete, so this allows the comment to be retained.
This example uses a Use Custom PowerShell step after the Require Approval step(s) in the workflow. The Use Custom PowerShell step needs to come after the Require Approval step so that it can include comments gathered from the approve/deny requests.
To do this, first use the POST /Extension/Scripts API endpoint (see POST Extensions Scripts) to import your PowerShell script into the Keyfactor Command database before beginning to edit your workflow. Your script file prior to import should contain content similar to the following:
# Declare your parameters at the beginning
param(
[string]$ApprovalComment,
[string]$SignalComment,
[string]$Metadata
)
# Initialize a hashtable to contain your metadata fields and populate it
$UpdatedMetadata = @{}
$jsonobject = $Metadata | ConvertFrom-Json
foreach( $property in $jsonobject.PSObject.Properties )
{
$UpdatedMetadata[$property.Name] = $property.Value
}
# Append your signal comment(s) to any existing comment in the ApprovalComment metadata field
if([string]::IsNullOrWhiteSpace($ApprovalComment)) {
$UpdatedMetadata['ApprovalComment'] = $SignalComment
}else {
$UpdatedMetadata['ApprovalComment'] = $ApprovalComment + ", " + $SignalComment
}
# Return the updated metadata fields, including ApprovalComment, to the workflow in the original parameter as a hashtable
$result = @{ "ApprovalComment" = $UpdatedMetadata }
return $result
Once your PowerShell script has been imported into the Keyfactor Command database, you may begin creating your workflow. To create the Use Custom PowerShell step, add Script Parameters to pull any approval comments and the metadata field you're planning to store them in (in this example, a field called ApprovalComments) into the script, along with the metadata bucket to include any remaining metadata values, as shown in Figure 192: Approval Comment Update Example: Add Parameters.
In the PowerShell Script Name field dropdown, select the script you uploaded to the database.
The resulting comment will look something like:
Figure 193: Approval Comment Update Example: Results
If the workflow requires multiple approvals or has multiple require approval steps, all the approval comments entered in the given workflow instance prior to the PowerShell step will be added to the metadata field. If you expect to have multiple comments, you may prefer to use a big text field rather than the string type fields shown here.
Update Certificate Request Subject\SANs for Microsoft CAs
This step is used to create a new signed CSR to prepare an updated enrollment request for delivery to a Microsoft CA after a previous step in the workflow has been used to update either the SANs in the initial request, subject (DN A distinguished name (DN) is the name that uniquely identifies an object in a directory. In the context of Keyfactor Command, this directory is generally Active Directory. A DN is made up of attribute=value pairs, separated by commas. Any of the attributes defined in the directory schema can be used to make up a DN.) in the initial request or both. This step must be placed later in the workflow than the step(s) that modify the SANs and/or subject. The SANs and subject may be modified with either of the PowerShell step types (see Set Variable Data and Use Custom PowerShell) or a custom step type. This step is used for both PFX enrollment and CSR enrollment, since both use a CSR that is generated at the start of the workflow. A Microsoft CA will not accept a CSR for enrollment if the subject has been modified and will only accept a CSR for enrollment with modified SANs if the EDITF_ATTRIBUTESUBJECTALTNAME2 flag has been enabled on the CA—a security risk Keyfactor does not recommend. EJBCA doesn’t support enroll on behalf of (EOBO A user with an enrollment agent certificate can enroll for a certificate on behalf of another user. This is often used when provisioning technology such as smart cards.), so this step type does not apply to EJBCA CAs. EJBCA is able to handle subject and SAN changes without the need for this type of step based on end entity profile constraints.
-
Enrollment Agent Certificate: Click Browse to search for the desired base-64 encoded PKCS#12 A PFX file (personal information exchange format), also known as a PKCS#12 archive, is a single, password-protected certificate archive that contains both the public and matching private key and, optionally, the certificate chain. It is a common format for Windows servers. (.PFX) enrollment agent certificate with private key Private keys are used in cryptography (symmetric and asymmetric) to encrypt or sign content. In asymmetric cryptography, they are used together in a key pair with a public key. The private or secret key is retained by the key's creator, making it highly secure. to sign the CSR. This can be either a user certificate or a computer certificate and must have a Certificate Request Agent EKU.
-
Set Private Key Password: The password for the enrollment agent certificate. Click Set Private Key Password to open the Private Key Password dialog. Choose the No Value checkbox to not assign a password, or choose from Load From Keyfactor Secrets or Load From PAM Provider.
Figure 194: Update Certificate Request Subject\SANs for Microsoft CAs Workflow Definition Step
Example: Update Certificate Request Subject\SANS for MSFT CAs
The following example uses PowerShell to take the distinguished name (subject) and SANs entered during an enrollment along with two static domain names and evaluates the domain name of the common name in the subject to determine whether the domain suffix ends with the “original” domain name provided in the static value (“keyexample.com”). If it does, the script replaces the domain name in the subject with the value provided by the “new” static value and adds a SAN with CN prefix and the new domain name (e.g. CN=mycert.keyexample.com becomes CN=mycert.keyother.com and a SAN is added for mycert.keyother.com). If the CN does not have a domain suffix ending with “keyexample.com”, the PowerShell script does nothing. Here we use a Set Variable Data step (see Set Variable Data) since no functions need to be called outside the confines of Keyfactor Command, though you could use a Custom PowerShell Script step instead. Then an Update Certificate Subject\SANs for Microsoft CAs step is used to re-sign the request before it is submitted to the CA.
To create this, add Script Parameters to pull the DN and SANs into the script as shown in Metadata Update Example: Add Parameters and add two static values to pass in your two domain names.
Figure 195: Update SANs and Subject Example: Add Parameters
In the Insert PowerShell Script field, enter a script similar to the following:
# Declare your parameters at the beginning
param(
[string]$CSRSubject,
[string]$CSRSANs,
[string]$OriginalDomain,
[string]$NewDomain
)
# Split the incoming SANs string into its component values
$SplitSANs = $CSRSANs.Split(',')
# Initialize variables for the two types of SANs we're handling
$DnsSANs = @()
$IpSANs = @()
# Add the incoming SANs to the correct list (assumes only IPv4 addresses or DNS SANs will be encountered)
foreach($san in $SplitSANs){
$sanComponents = $san.Trim() -split ":"
Switch ($sanComponents[0].Trim()){
"DnsName" {$DnsSANs += ,$sanComponents[1].Trim()}
"IPAddress" {$IpSANs += $sanComponents[1].Trim()}
}
}
# Load original SANs in UpdatedSANs for the else case
$UpdatedSANs = @{}
if(![string]::IsNullOrWhiteSpace($DnsSANs)) {
$UpdatedSANs['dns'] = $DnsSANs
}
if(![string]::IsNullOrWhiteSpace($IpSANs)) {
$UpdatedSANs['ip4'] = $IpSANs
}
# Load original subject in NewSubject for the else case
$NewSubject = $CSRSubject
# Replace escaped commas in the subject temporarily with a string to facilitate splitting
$TempString = "######"
$CleanSubject = $CSRSubject -replace "\\,", $TempString
# Split the incoming Subject string into its component values
$SplitSubject = $CleanSubject.Split(',')
# Initialize variables for the components of the subject
$SubjectCN = @()
$SubjectO = @()
$SubjectOU = @()
$SubjectL = @()
$SubjectST = @()
$SubjectC = @()
$SubjectE = @()
# Load subject values
foreach($element in $SplitSubject){
$SplitElement = $element.Split('=')
Switch($SplitElement[0]){
"CN" {$SubjectCN = $SplitElement[1]}
"O" {$SubjectO = $SplitElement[1]}
"OU" {$SubjectOU = $SplitElement[1]}
"E" {$SubjectE = $SplitElement[1]}
"L"{$SubjectL = $SplitElement[1]}
"ST"{$SubjectST = $SplitElement[1]}
"C"{$SubjectC = $SplitElement[1]}
}
}
# Check to see if the incoming CN ends with $OriginalDomain and, if so, add it as a SAN with $NewDomain and update the Subject with $NewDomain (assumes non-null CN)
if ($SubjectCN.EndsWith($OriginalDomain))
{
# Load just the portion of the CN without the domain name into a variable.
$CNName = $SubjectCN.SubString(0,$SubjectCN.Length - ($OriginalDomain.Length + 1)) # +1 to account for the '.'
# Build new DNS SAN
$NewSAN = $CNName + "." + $NewDomain
# Add new SAN to DNS SANs
$DnsSans += ,$NewSAN
# Build new Subject with $NewDomain
$NewSubject = "";
if(![string]::IsNullOrWhiteSpace($SubjectCN)){
$NewSubject += "CN=" + $CNName + "." + $NewDomain + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectO)){
$NewSubject += "O=" + $SubjectO + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectOU)){
$NewSubject += "OU=" + $SubjectOU + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectL)){
$NewSubject += "L=" + $SubjectL + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectST)){
$NewSubject += "ST=" + $SubjectST + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectC)){
$NewSubject += "C=" + $SubjectC + ","
}
if(![string]::IsNullOrWhiteSpace($SubjectE)){
$NewSubject += "E=" + $SubjectE + ","
}
$NewSubject = $NewSubject.Remove($NewSubject.Length - 1) # remove the last ','
# Replace temporary string with escaped commas in Subject
$NewSubject = $NewSubject -replace $TempString, "\,"
# Load the resulting IPv4 and updated DNS SANs into the SANs variable
$UpdatedSANs = @{}
if(![string]::IsNullOrWhiteSpace($DnsSANs)) {
$UpdatedSANs['dns'] = $DnsSANs
}
if(![string]::IsNullOrWhiteSpace($IpSANs)) {
$UpdatedSANs['ip4'] = $IpSANs
}
}
# Return the updated subject and SANs as NewSubject and NewSANs to the workflow as a hashtable
$result = @{ "Subject" = $NewSubject; "SANs" = $UpdatedSANs }
return $result
Add an Update Certificate Request Subject\SANs for Microsoft CAs step at a point in the workflow after your PowerShell step to allow the request to be re-signed before it is submitted to the Microsoft CA for enrollment.
Your enrollment will complete using the updated list of SANs, including any SANs you added manually on the PFX enrollment page or in the CSR, and the updated subject. You may reference the updated SANs using the standard SANs token ($(sans)) and updated subject using the standard DN token ($(request:dn)) in subsequent steps in your workflow and may view the subject and complete SAN list wherever the subject and SANs are available for viewing within Keyfactor Command.
Windows Enrollment Gateway - Populate from AD
This step is needed for any Keyfactor Windows Enrollment Gateway requests where the incoming template A certificate template defines the policies and rules that a CA uses when a request for a certificate is received. (the template from the client side) is configured to build the subject of the certificate request from Active Directory. It has no configuration parameters.