Account Create
Input/Output | Data Type |
---|---|
Input | StdAccountCreateInput |
Output | StdAccountCreateOutput |
Example StdAccountCreateInput
{
"attributes": {
"id": "john.doe",
"email": "[email protected]",
"department": "external",
"displayName": "John Doe",
"password": "test",
"entitlements": [
"user",
"administrator"
]
}
}
Example StdAccountCreateOutput
{
"key": {
"simple": {
"id": "john.doe"
}
},
"disabled": false,
"locked": false,
"attributes": {
"id": "john.doe",
"displayName": "John Doe",
"email": "[email protected]",
"entitlements": [
"administrator",
"sailpoint"
]
}
}
Description
The account create command triggers whenever ISC is told to provision entitlements for an identity on the target source, but no account for the identity on the target source exists yet. For example, if you create an access profile that grants a group on the target source and then add that access profile to a role, any identity matching that role’s membership criteria will be granted to the group. ISC determines which identities do not have accounts on the target source and triggers the account create command for each identity. If an identity already has an account, then it invokes the account update command.
To use this command, you must specify this value in the commands
array: std:account:create
The Provisioning Plan
The account create command accepts a provisioning plan from ISC and creates the corresponding account(s) in the target source. When you configure your source in ISC, you must set up ‘Create Profile’ to tell ISC how to provision new accounts for your source.
You can create the provisioning plan through the accountCreateTemplate
in the connector-spec.json
file, and you can also modify its behavior in ISC using the create profile screen:
‘Create Profile’ provides the instructions for the provisioning plan and determines which attributes are sent to your connector code. For example, if all the account attributes in the preceding image are configured for a value, then the following JSON payload is sent to your connector:
{
"key": {
"simple": {
"id": "john.doe"
}
},
"disabled": false,
"locked": false,
"attributes": {
"id": "john.doe",
"password": "secretPassword",
"email": "[email protected]",
"entitlements": [
"administrator",
"sailpoint"
]
}
}
The provisioning plan does not include any disabled attributes. In the earlier image, password
is disabled, so the payload to your connector does not not include a field for password
:
{
"key": {
"simple": {
"id": "john.doe"
}
},
"disabled": false,
"locked": false,
"attributes": {
"id": "john.doe",
"email": "[email protected]",
"entitlements": [
"administrator",
"sailpoint"
]
}
}
The provisioning plan presents multi-valued entitlements in two different ways:
If a multi-valued entitlement, like groups, has only one value, then the provisioning plan represents it as a string value:
{
"key": {
"simple": {
"id": "john.doe"
}
},
"disabled": false,
"locked": false,
"attributes": {
"id": "john.doe",
"email": "[email protected]",
"entitlements": "user"
}
}
If a multi-valued entitlement has more than one value, then the plan represents it as an array:
{
"key": {
"simple": {
"id": "john.doe"
}
},
"disabled": false,
"locked": false,
"attributes": {
"id": "john.doe",
"email": "[email protected]",
"entitlements": [
"administrator",
"sailpoint"
]
}
}
Your connector code must handle the possibility of both cases. The following code example from AirtableAccount.ts shows how to handle a multi-valued attribute:
public static createWithStdAccountCreateInput(record: StdAccountCreateInput): AirtableAccount {
const account = new AirtableAccount();
...
if (record.attributes['entitlements'] != null) {
if (!Array.isArray(record.attributes['entitlements'])) {
account.entitlments = [record.attributes['entitlements']]
} else {
account.entitlments = record.attributes['entitlements']
}
} else {
account.entitlments = []
}
return account;
}
The return object
When the account is returned to ISC, any values you set are updated in ISC. So if an account ID is auto-generated on the source system, you must send the account ID back to ISC so ISC is aware of it for future account update activities. This is useful for the compound key type.
Password Handling
There are three main ways to handle passwords on a source:
-
SSO, LDAP, or other federated authentication mechanisms are the preferred means of providing user login on a target source. If your source can integrate with a federated login service, use that service. If your source requires you to provide a password when you create accounts, even with a federated login, it is best to create a strong, random password. Your users will use the federated login, so they never need to know this password.
-
If your source has a password reset feature at login, it is best to initially create the account with a strong, random password the user does not have access to. Once the account is created, make the user request a password reset to set their own password. This method is the safest alternative to federated authentication because the initial password is strong and never known to anyone, and the user can generate his or her own password through secure channels.
-
The least secure method is setting a static password in the create profile that is well known among your users. This approach is not recommended. It does not require any automated communications with your users.
There are two ways you can generate random passwords:
- Use the “Create Password” generator in ‘Create Profile.’ (This can also be configured in the
accountCreateTemplate
)
- Disable the 'password' field.
Use ‘Create Profile’ and generate a random password in code. There are some JavaScript libraries that can generate random strings suitable for passwords, like random-string and crypto-random-string. Import either one of these libraries into your code to use them. The following example from airtable.ts uses a ternary operator to ensure the password is always provided. If the provisioning plan provides a password, use that value. If the provisioning plan does not provide a password, generate a random one.
async createAccount(input: StdAccountCreateInput): Promise<AirtableAccount> {
const account = AirtableAccount.createWithStdAccountCreateInput(input);
return this.airTableBase('Users').create({
"displayName": account.displayName,
"email": account.email,
"id": account.id,
"enabled": account.enabled ? 'true' : 'false',
"department": account.department,
"firstName": account.firstName,
"lastName": account.lastName,
"locked": account.locked ? 'true' : 'false',
"password": account.password ? account.password : crypto.randomBytes(20).toString('hex'),
"entitlements": account.entitlments.join(',')
}).then(record => {
const airtableRecord = AirtableAccount.createWithRecords(record)
return airtableRecord
}).catch(err => {
throw new ConnectorError('error while getting accounts: ' + err)
})
}
Testing in Identity Security Cloud
One way to test whether the account create code works in ISC is to set up an access profile and role that grants members an entitlement from the connector’s target source. Start by creating an access profile that grants one or more entitlements from the target source.
Next, create a role that uses the access profile created in the previous step.
Modify the role membership to use ‘Identity List’ and select one or more users that do not have accounts in the target source yet.
Click the ‘Update’ button in the upper right corner to initiate the account provisioning process. Doing so creates the account(s) on the target source once the process is complete.