Using the Users API
Important
Before proceeding, complete the API Authentication steps in order to obtain a working client_id
and client_secret
.
Regions
The URL to access XDR APIs may differ according to the region your environment is deployed in:
- US1—
https://api.ctpx.secureworks.com
- US2—
https://api.delta.taegis.secureworks.com
- US3—
https://api.foxtrot.taegis.secureworks.com
- EU—
https://api.echo.taegis.secureworks.com
The examples in this XDR API documentation use https://api.ctpx.secureworks.com
throughout. If you are in a different region substitute appropriately.
You can use the XDR users API to invite, update, deactivate and retrieve tenant users.
Inviting a User into a Tenant ⫘
Part 1: Invite Requirements ⫘
There are four primary values required to invite a user into a tenant:
access_token
: XDR access token obtained by following the API Authentication steps.
tenant_id
: The ID of the tenant that this user is to be invited into.
Note
The access_token
you are using to make the invite request must have permission to invite users within the target tenant (tenant_id
).
email_address
: The email address of the user you wish to invite into the tenant.
role_id
: The ID of the role that you wish to assign to the invited user. Such as Tenant Admin (ba0fdcbd-e87d-4bdd-ae7d-ca6118b25068
) or Tenant Analyst (a4903f9f-465b-478f-a24e-82fa2e129d2e
)
Part 2: Invite Request ⫘
Role IDs:
- Tenant Analyst—
a4903f9f-465b-478f-a24e-82fa2e129d2e
- Tenant Admin—
ba0fdcbd-e87d-4bdd-ae7d-ca6118b25068
- Tenant Auditor—
ace1cae4-59fd-4fd1-9500-40077dc529a7
- Tenant Responder—
a72dace7-4536-4dbc-947d-015a8eb65f4d
mutation inviteTDRUser($invite: TDRUserInviteInput! = {email: "invitee_email_address", role_id: "invitee_role_id"})
{
inviteTDRUser(invite: $invite)
{
id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified
}
}
where invitee_email_address
is the users email_address
and invitee_role_id
is the ID of the role to assign the user both described in Part 1.
In addition to the graphql mutation in the body of the request, the x-tenant-context
header needs to be set to the tenant_id
that you wish to invite the user into. Your access_token
must also be set in the Authorization
header.
cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export EMAIL_ADDRESS="invitee_email_address"
export ROLE_ID="invitee_role"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header "Content-Type: application/json" \
--data '{"query": "mutation { inviteTDRUser(invite:{ email: \"$EMAIL_ADDRESS\" role_id: \"$ROLE_ID\" }){id email }}"}'
where your_access_token
is your bearer access_token
, tenant_id
is the ID of the tenant you wish to invite the user into, invitee_email_address
is the email_address
of the user you wish to invite and invitee_role
is the role_id
that you wish to assign to the new user. All of which are described in Part 1.
Part 3: Invite Response ⫘
Example Invite Response ⫘
{
"data": {
"inviteTDRUser": {
"email": "customer.name@octolabs.io",
"id": "828bda7c-a9d0-435e-8b70-f099aa55dccb"
}
}
}
The response to the inviteTDRUser
mutation will contain fields email
and id
.
The email
field matches your input invitee_email_address
and is the address that the invite is sent to.
The id
field contains the User ID for the invited user, this User ID can then be used to further reference the user, for example for updates or disabling.
Retrieve a User ⫘
Part 1: Retrieval Requirements ⫘
To retrieve details of a user the following three values are required:
access_token
: XDR access token obtained by following the API Authentication steps.
user_id
The unique ID of the user whose details you want to retrieve.
tenant_id
: The ID of the tenant that the target user is a member of.
Note
The access_token
you are using to to make the retrieval request must have permission to read users within the target tenant (tenant_id
).
Part 2: Retrieval Request ⫘
Retrieving existing user details is done with a graphql request to the users API calling the tdruser
query.
GraphQL ⫘
query tdruser($id: ID! = "user_id", $excludeDeactivatedRoleAssignments: Boolean, $includeMaskedRelatedUsers: Boolean)
{
tdruser(id: $id, excludeDeactivatedRoleAssignments: $excludeDeactivatedRoleAssignments, includeMaskedRelatedUsers: $includeMaskedRelatedUsers)
{
id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified
}
}
where user_id
is the ID of the user to retrieve.
In addition to the graphql query in the body of the request, the x-tenant-context
header needs to be set to the tenant_id
that the target user is a member of. Your access_token
must also be set in the Authorization
header.
cURL ⫘
All fields listed in the above GraphQL query are available to retrieve. This cURL example retrieves only the user email
field to keep the example concise.
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export TARGET_USER_ID="user_id"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header 'Content-Type: application/json' \
--data "{\"query\":\"query{ tdruser(id:\\\"$TARGET_USER_ID\\\"){ email }}\"}"
where your_access_token
is your bearer access_token
, tenant_id
is the ID of the target users tenant and user_id
is the ID of the user you wish to retrieve.
Update a User ⫘
Part 1: User Update Requirements ⫘
To update details of a user the following three values are required:
access_token
: XDR access token obtained by following the API Authentication steps.
user_id
The unique ID of the user who you wish to make updates to (the target user).
tenant_id
: The ID of the tenant that the target user is a member of.
Part 2: Update User Request ⫘
User updates are made via a graphql request to the users API calling the updateTDRUser
mutation containing a patch for the fields to be updated on the target user.
Note
The access_token
you are using to make the update request must have permission to update users within the target tenant (tenant_id
).
There are a number of variables available to set within a patch to update details of a user. Fields currently available to patch include:
given_name
family_name
phone_number
secondary_phone_number
GraphQL ⫘
mutation updateTDRUser($id: ID! = "user_id", $patch: TDRUserUpdateInput! = {phone_number:"+10000000000", secondary_phone_number:"+000000000000"})
{
updateTDRUser(id: $id, patch: $patch)
{
id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified
}
}
where user_id
is the ID of the user to update (described in Part 1), new_primary_phone_number
and new_secondary_phone_number
are the new phone number values for the targer user.
In addition to the graphql mutation in the body of the request, the x-tenant-context
header needs to be set to the tenant_id
that the target user is a member of. Your access_token
must also be set in the Authorization
header.
cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export TARGET_USER_ID="user_id"
export NEW_PRIMARY_PHONE_NUMBER="new_primary_phone"
export NEW_SECONDARY_PHONE_NUMBER="new_secondary_phone"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header 'Content-Type: application/json' \
--data "{\"query\":\"mutation { updateTDRUser(id:\\\"$TARGET_USER_ID\\\", patch:{ phone_number:\\\"$NEW_PRIMARY_PHONE_NUMBER\\\" secondary_phone_number:\\\"$NEW_SECONDARY_PHONE_NUMBER\\\"}) { id }}\"}"
where your_access_token
is your bearer access_token
, tenant_id
is the ID of the target users tenant, user_id
is the ID of the user you wish to update, new_primary_phone
and new_secondary_phone
are the new phone number values for the user.
This example curl request patches the phone number of a user, however, the patch fields can be substituted as required with any of the other patch fields detailed above.
Revoke a User’s Access ⫘
Part 1: Revocation Requirements ⫘
Revocation of a users access is performed by removing a user’s role assignments, once a user has 0 role assignments within a tenant they have no further access to that tenant. If a user has no role assignments within any tenant their account is marked as deactivated
and the user is prevented from logging in to XDR.
The following values are required to revoke a user’s role assignment:
access_token
: XDR access token obtained by following the API Authentication steps.
user_id
The unique ID of the user who you wish to revoke a role assignment (the target user).
tenant_id
: The ID of the tenant that the target user is a member of and for which the role is to be revoked.
role_id
: The ID of the role for which the assignment is to be revoked.
Part 2: Remove Role Assignment Request ⫘
Role assignment removals are made with a graphql request to the users API calling the removeTDRUserRoles
mutation.
Note
The access_token
you are using to make the role removal request must have permission to update users within the target tenant (tenant_id
).
Role IDs:
- Tenant Analyst—
a4903f9f-465b-478f-a24e-82fa2e129d2e
- Tenant Admin—
ba0fdcbd-e87d-4bdd-ae7d-ca6118b25068
- Tenant Auditor—
ace1cae4-59fd-4fd1-9500-40077dc529a7
- Tenant Responder—
a72dace7-4536-4dbc-947d-015a8eb65f4d
GraphQL ⫘
mutation removeTDRUserRoles($id: ID! = "user_id", $roles: [ID!]! = ["role_id"])
{
removeTDRUserRoles(id: $id, roles: $roles)
{
id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified
}
}
where user_id
is the ID of the target user and role_id
is the ID of the role to removed from the user, which are both described in Part 1.
In addition to the graphql mutation in the body of the request, the x-tenant-context
header needs to be set to the tenant_id
that the target user is a member of. Your access_token
must also be set in the Authorization
header.
cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export TARGET_USER_ID="user_id"
export ROLE_ID="role_id"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header 'Content-Type: application/json' \
--data "{\"query\":\"mutation { removeTDRUserRoles(id:\\\"$TARGET_USER_ID\\\", roles:[\\\"$ROLE_ID\\\"]) {id }}\"}"
where your_access_token
is your bearer access_token
, tenant_id
is the ID of the target users tenant, user_id
is the ID of the user for who you wish to revoke a role and role_id
is the ID of the role that you would like to remove from the user.
This example cURL request removes a single role for a user. However, it is possible to remove multiple roles for a user in a single request by specifying multiple role IDs in the mutations input roles
array.
Searching Users ⫘
Part 1: Search Requirements ⫘
To search users the following two values are required:
access_token
: XDR access token obtained by following the API Authentication steps.
tenant_id
: The ID of the tenant in which to search users.
Note
The access_token
you are using to to make the retrieval request must have permission to read users within the target tenant (tenant_id
).
Part 2: Search Request ⫘
User searches are made with a graphql request to the users API calling the tdrUsersSearch
query.
GraphQL ⫘
query tdrUsersSearch($filters: TDRUsersSearchInput = {tenantStatus="!Deactivated"})
{
tdrUsersSearch(filters: $filters)
{
result_count results { id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified } cursor_pos pageOffset has_next_page total_count
}
}
where filters
contains a list of filters that you would like to search by (tenantStatus used as an example) and results
contains the items for each user that you would like to retrieve (more available fields are listed in the user retrieval example).
The following filters are available when searching for users:
Filter | Example | Description |
---|---|---|
email |
email:"test@secureworks.com" |
Email address to filter for. Uses SQL 'like' matching. Note that email addresses can contain underscores. The underscore is escaped and is not used as a wildcard. |
emails |
emails:["test1@secureworks.com","test2@secureworks.com"] |
A list of email addresses to filter by. Matching is the same as used for email . |
role_IDs |
role_IDs:["58c0dd7f-a171-4701-931d-d53654d68089", "260f9d74-1a57-48cf-adca-a30778fc3879"] |
Role IDs assigned to users. |
tenantStatus |
tenantStatus:"!Deactivated" |
User status. If the status request begins with a '!' it uses the NOT matcher. This is useful if the request is for active users only: '!Deactivated'. |
perPage |
perPage:1 |
Pagination page size. Page size of -1 (default) indicates no pagination. |
cursorPos |
cursorPos:"test@secureworks.com" |
Pagination last cursor position. Value is the user email address of last entry returned in result set. Use only if not using pageOffset. |
pageOffset |
pageOffset:1 |
Pagination record offset. If included it overrides cursorPos . |
In addition to the graphql query in the body of the request, the x-tenant-context
header needs to be set to the tenant_id
that the target user is a member of. Your access_token
must also be set in the Authorization
header.
cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header 'Content-Type: application/json' \
--data '{"query":"query {tdrUsersSearch(filters:{tenantStatus:\"!Deactivated\"}) {result_count cursor_pos has_next_page total_count results {id user_id status email last_login}}}"}'
where your_access_token
is your bearer access_token
and tenant_id
is the ID of the tenant to list users for.
Example Searching Tenant Users With a Given Role cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export ROLE_ID="role_id"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header 'Content-Type: application/json' \
--data "{\"query\":\"query { tdrUsersSearch(filters:{tenantStatus:\\\"\!Deactivated\\\",role_IDs:[\\\"$ROLE_ID\\\"]}) {result_count cursor_pos has_next_page total_count results { id user_id status email last_login } }}\"}"
where your_access_token
is your bearer access_token
, tenant_id
is the ID of the tenant to list users for and role_id
is the ID of the role you wish to filter by.
Registering Pre-Verified User ⫘
A new Users API has been added to allow Partners to add new users to their tenants without following the standard invite process and email notification for registration.
Part 1: Register User Requirements ⫘
- Valid SSO Connection on the Partner or the child tenant the user will be assigned to
- User email domain must match the SSO Connection
- Only available to Partners and their tenants, not Secureworks tenants
- New Tenant Admin users must go through the standard invite process and will not work in this API
There are four primary values required to register a user into a tenant:
access_token
: XDR access token obtained by following the API Authentication steps.
tenant_id
: The ID of the tenant that this user is to be registered in.
Note
The access_token
you are using to make the register request must have permission to createPreRegisteredUser
users within the target tenant (tenant_id
). A TenantAdmin role has this permission.
email_address
: The email address of the user you wish to register in the tenant.
role_id
: The ID of the role that you wish to assign to the registered user, such as Tenant Auditor (ace1cae4-59fd-4fd1-9500-40077dc529a7
) or Tenant Analyst (a4903f9f-465b-478f-a24e-82fa2e129d2e
).
Part 2: Register User Request ⫘
Example Register Partner User GrahpQL Mutation ⫘
mutation registerPartnerUser($registrationInput: PartnerRegistrationInput! = {email: "user_email_address", role_id: "user_role_id", role_expires_at: "role_expiration_time", language: "user_preferred_lang", given_name: "user_first_name", family_name: "user_last_name", phone_number: "user_phone_number", timezone: "user_timezone"})
{
registerPartnerUser(registrationInput: $registrationInput)
{
id id_uuid user_id user_id_v1 created_at updated_at created_by updated_by last_login invited_date registered_date deactivated_date status status_localized email email_normalized family_name given_name phone_number phone_extension secondary_phone_number secondary_phone_extension roles tenants { id } tenants_v2 { id role } accessible_tenants { id name name_normalized enabled allow_response_actions actions_approver expires_at environments { name enabled } labels { id tenant_id name value } services { id name description } is_partner parent } role_assignments { id tenant_id role_id deactivated role_name role_display_name expires_at created_at updated_at allowed_environments } environments eula { date version } timezone tenant_status tenant_status_localized entitlement_channel allowed_entitlement_channels masked community_role is_scwx is_partner preferred_language pre_verified
}
}
cURL ⫘
export ACCESS_TOKEN="your_access_token"
export TENANT_ID="tenant_id"
export EMAIL_ADDRESS="user_email_address"
export ROLE_ID="user_role"
curl --request POST \
--url https://api.ctpx.secureworks.com/graphql \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "x-tenant-context: $TENANT_ID" \
--header "Content-Type: application/json" \
--data "{\"query\":\"mutation { registerPartnerUser(registrationInput:{ email: \\\"$EMAIL_ADDRESS\\\" role_id: \\\"$ROLE_ID\\\" }){id email }}\"}"
The optional fields in the mutation can be added to the registrationInput
field where needed.