Get Started with the Tenants 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 the XDR Tenants API may differ according to the region your environment is deployed in:
- US1โ
https://api.tenants.ctpx.secureworks.com/public/query - US2โ
https://api-tenants.delta.taegis.secureworks.com/public/query - US3โ
https://api-tenants.foxtrot.taegis.secureworks.com/public/query - EUโ
https://api-tenants.echo.taegis.secureworks.com/public/query
The examples here use https://api.tenants.ctpx.secureworks.com/public/query throughout. If you are in a different region substitute appropriately.
You can use the Secureworksยฎ Taegisโข XDR public tenants API to search, create and update tenant information.
Accessing the Tenants API๐
The Tenants API can be used to interact with our tenant graph and partner data graph. Unlike other graphql APIs, tenants-api needs to be accessed using a different ingress from our normal APIs (see the regions above).
You must authenticate to this API using Authorization : Bearer {token}, just like any other of our APIs. Authorization to this API honors the following rules:
- The client/user token that has read access to the tenant (
Tenant:read) either is your tenant, or you have access to the related partner/parent tenant. - Read access is always applied to the query, even if you donโt provide any filter (for example
name,id,labels, etc). Only tenants you have access are returned. - Secureworks personnel/systems might be able to access a child tenant if it has support enabled.
- Updating with a
mutationrequires specialTenant:updateorTenant:createaccess. TenantAdminon the partner/parent tenant should be enough to read and update any tenant in that hierarchy.
Tenant Graph Overview๐
Most queries and mutations return a Tenant object. The full schema can be introspected from graphql, but the most important elements are:
# Not all fields listed for brevity
type Tenant {
# The tenant ID, an int like: 12345
id: ID!
# Created and updated times, e.g. : 2022-03-23T15:15:37Z
created_at: Time
updated_at: Time
# The tenant's name
name: String!
# A list of labels assigned to this tenant.
labels: [TenantLabel!]
# A list of environments indicating where the tenant is enabled at.
environments: [Environment!]
# A date when the tenant expires.
expires_at: Time
# Contains hierarchy and subscription information.
partnership: Partnership
# Either Secureworks support users have access to read this tenant.
support_enabled: Boolean!
...
}
# Partnership contains some important information about this tenant's partner hierarchy.
type Partnership {
# Indicates the parent tenant id, this is your partner tenant.
parent: ID
# If true, indicates that the tenant is a partner (parent)
is_partner: Boolean!
# Subscriptions that the partner assigned to the tenant.
subscriptions: [PartnerSubscription!]
}
Querying For Tenants๐
You can use query tenants(TenantsQuery!) to retrieve a list of tenants that you have access to. Results are wrapped with some pagination metadata, so you can easily scroll
through the results:
# Not all fields shown; use query introspection to retrieve the full schema.
input TenantsQuery {
# Start results after this id
cursorPos: ID
# How many results to return
maxResults: Int
# If provided (and not cursorPos is provided) pageNum allows getting a specific result page (maxResults = per page)
pageNum: Int
# optional name (supports wildcard %) or tenant id
name: String
# optional ids to return, useful when only a few tenants are needed and ids are known
ids: [ID!]
# optional filter for environments
environmentFilter: TenantEnvironmentFilter
# optional label filter
labelFilter: TenantLabelFilter
# optional partner service (subscription) filter
withPartnerSubscription: String
# optional partnership filter
partnership: PartnershipFilter
# Return tenants who were created during the specified time range
createdTimeFilter: TimeFilter
# Return tenants who were modified during the specified time range
modifiedTimeFilter: TimeFilter
# Allows to filter by is_partner flag
isPartner: Boolean
# Sets the order for the query results, ID by default
orderBy: TenantOrderField = Id
# Sets the order direction for the results, Asc by default
orderDir: OrderDir = asc
# optional support selector to find tenants or partners with support enabled
withSupport: Boolean
}
type TenantResults {
# The actual query results
results : [Tenant!]!
# Indicates the last cursor for cursor based pagination.
cursorPos : ID
# Represents the number of records returned.
count: Int!
# Indicates if there are more records after the requested page/cursor
hasMore: Boolean!
# Represents the total number of records when offset pagination is used (page / per page)
totalCount: Int
}
All requests to tenants-api must have the following form:
POST 'https://api.tenants.ctpx.secureworks.com/query'Content-Type: application/jsonheader (for content type negotiation)Authorization: Bearer {ACCESS_TOKEN}with the access token that you obtained for your client and user.
GraphQL๐
query tenants($tenantsQuery: TenantsQuery! = {maxResults: 10})
{
tenants(tenantsQuery: $tenantsQuery)
{
results { id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot } cursorPos count hasMore totalCount
}
}
cURL๐
# Get 10 results from the second page
curl --location --request POST 'https://api.tenants.ctpx.secureworks.com/query' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query tenants ($tenantsQuery: TenantsQuery!) { tenants (tenantsQuery: $tenantsQuery) { count totalCount results { id name created_at support_enabled partnership { subscriptions { id service_id created_at updated_at name description } } labels { name value } } }}","variables":{"tenantsQuery":{"maxResults":10}}}'
{
"data": {
"tenants": {
"count": 10,
"totalCount": 24834,
"cursorPos": "aWR8MTAwMTc=",
"results": [
{
"id": "10008"
}
]
}
}
}
Paginate Tenants๐
GraphQL๐
Page Num๐
query tenants($tenantsQuery: TenantsQuery! = {maxResults: 10, pageNum: 2})
{
tenants(tenantsQuery: $tenantsQuery)
{
results { id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot } cursorPos count hasMore totalCount
}
}
Cursor๐
query tenants($tenantsQuery: TenantsQuery! = {maxResults: 10, cursor_pos: "aWR8MTAwMzc="})
{
tenants(tenantsQuery: $tenantsQuery)
{
results { id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot } cursorPos count hasMore totalCount
}
}
You can use both modes of pagination interchangeably if your use case requires it. Sorting results changes the cursor computation, so make sure you pass the right value to cursorPos if you ever change the order.
Filter Tenants๐
You can mix and match filters. You can use any (or all of the filters):
- name
- ids
- forHierarchies
- environmentFilter
- labelFilter
- withService
- withServices
- withPartnerSubscription
- withPartnerSubscriptions
- partnership
- createdTimeFilter
- modifiedTimeFilter
- isPartner
- withSupport
query tenants($tenantsQuery: TenantsQuery! = {maxResults: 10, ids=["xxxxx"], name="%my name%", forHierarchies=["id"], environmentFilter: {name: "echo", enabled: true}, labelFilter: {label_name: "testing"}, withPartnerSubscription: "%", withPartnerSubscription: ["%"], createdTimeFilter: {startTime: "2019-07-04T15:00:22", endTime: "2019-07-06T15:00:22Z"}})
{
tenants(tenantsQuery: $tenantsQuery)
{
results { id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot } cursorPos count hasMore totalCount
}
}
Sort Tenants๐
Results can be sorted by any of the following:
- Id
- Name
- CreatedAt
- UpdatedAt
GraphQL๐
query tenants($tenantsQuery: TenantsQuery! = {maxResults: 10, createdTimeFilter: {startTime: "2019-07-04T15:00:22", endTime: "2019-07-06T15:00:22Z"}, orderBy: CreatedAt, orderDir: desc})
{
tenants(tenantsQuery: $tenantsQuery)
{
results { id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot } cursorPos count hasMore totalCount
}
}
Create a Tenant๐
mutation createTenant(TenantCreateInput!) creates a tenant on a partner with some restrictions:
- You cannot create a child tenant on a partner (parent tenant) that you donโt have access to.
- You cannot create a new partner tenant (unless you are a Secureworks user with the right role).
mutation createTenant($newTenant: TenantCreateInput! = {name: "New Tenant Name", partnerTenantID: "xxxxx", labels: {name: "partner_only_label_name", value: "label_value", owner_partner_tenant_id: "xxxxx"}, environments: ["echo", "pilot"]})
{
createTenant(newTenant: $newTenant)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https://api.tenants.ctpx.secureworks.com/query' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation createTenant($newTenant: TenantCreateInput!) { createTenant (newTenant: $newTenant) {idpartnership {parent}environments {nameenabled}labels {namevalueowner_partner_tenant_id } } }","variables":{"newTenant":{"name":"New tenant name","partnerTenantID":"xxxxx","labels":[{"name":"partner_only_label_name","value":"label_value","owner_partner_tenant_id":"xxxxx"}],"environments":["echo","pilot"]}}}'
Notes๐
partnerTenantIDis the parentโs partner tenant ID. As the name indicates, you must have access to that tenant (asTenantAdmin), to be able to create child tenants.- You can restrict the audience for
labelsusing theowner_parent_tenant_id. In the example abovepartner_only_label_nameis only visible to tokens that can access tenantxxxxx. You can only set label ownership to the parent tenant for now. environmentscan be used to set a list of environments where you want this child tenant enabled at, in this example the new tenant is enabled inechoandpilot.
Rename Tenant๐
To rename a tenant, use mutation updateTenant(TenantUpdateInput):
GraphQL๐
mutation updateTenant($tenantID: ID! = "xxxxx", $tenantUpdate: TenantUpdateInput! = {name: "Updated Tenant Name"})
{
updateTenant(tenantID: $tenantID, tenantUpdate: $tenantUpdate)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https://api.tenants.ctpx.secureworks.com/query' \
--header 'Authorization: Bearer { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation updateTenant($tenantID: ID!, $updateInput: TenantUpdateInput!) { updateTenant (tenantID: $tenantID, tenantUpdate: $updateInput) { id name partnership { parent is_partner } environments { name enabled } labels { name value owner_partner_tenant_id } }}","variables":{"tenantID":xxxxx,"updateInput":{"name":"new tenant name"}}}'
Manage Tenant Environments๐
When tenants are created, they are enabled in at least one environment. To change that environment use mutation updateTenant(TenantUpdateInput):
GraphQL๐
mutation updateTenant($tenantID: ID! = "xxxxx", $tenantUpdate: TenantUpdateInput! = {environments: [{name: "echo", enabled: false}, {name: "delta", enabled: true}]})
{
updateTenant(tenantID: $tenantID, tenantUpdate: $tenantUpdate)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation updateTenant($tenantID: ID!, $updateInput: TenantUpdateInput!) { updateTenant (tenantID: $tenantID, tenantUpdate: $updateInput) { id name environments { name enabled } } }","variables":{"tenantID":xxxxx,"updateInput":{"environments":[{"name":"echo","enabled":true},{"name":"delta","enabled":false}]}}}'
Tip
You can enable and/or disable several environments in a single request. A tenant is considered active if itโs enabled in at least one environment.
Disable Tenant๐
To disable a tenant, you can either disable it in all its environments or simply set the field "disable" : true. Both options yield the same result.
GraphQL๐
mutation updateTenant($tenantID: ID! = "xxxxx", $tenantUpdate: TenantUpdateInput! = {disable: true})
{
updateTenant(tenantID: $tenantID, tenantUpdate: $tenantUpdate)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS _TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation updateTenant($tenantID: ID!, $updateInput: TenantUpdateInput!) { updateTenant (tenantID: $tenantID, tenantUpdate: $updateInput) { id name enabled expires_at environments { name enabled } } }","variables":{"tenantID":xxxxx,"updateInput":{"disable":true,"clearExpiration":true}}}'
Manage Tenant Expiration๐
A tenant with an expiration date is automatically disabled after a period of 60 days. The expiration date can be modified with mutation updateTenant(TenantUpdateInput):
GraphQL๐
mutation updateTenant($tenantID: ID! = "xxxxx", $tenantUpdate: TenantUpdateInput! = {expiresAt: "2023-12-31T00:00:00Z"})
{
updateTenant(tenantID: $tenantID, tenantUpdate: $tenantUpdate)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
Clear an Expiration๐
GraphQL๐
mutation updateTenant($tenantID: ID! = "xxxxx", $tenantUpdate: TenantUpdateInput! = {clearExpiration: true})
{
updateTenant(tenantID: $tenantID, tenantUpdate: $tenantUpdate)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS _TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation updateTenant($tenantID: ID!, $updateInput: TenantUpdateInput!) { updateTenant (tenantID: $tenantID, tenantUpdate: $updateInput) { id name enabled expires_at environments { name enabled } } }","variables":{"tenantID":xxxxx,"updateInput":{"expiresAt":"2022-09-09T14:30:34Z"}}}'
Managing Tenant Labels๐
Labels can be created, updated, and deleted in tenants using the following mutations:
createTenantLabel(label_id ID!, label_input ID!: InputTenantLabel!): TenantLabel!,InputTenantLabel.owner_partner_tenant_idcan be used to establish label audience.updateTenantLabel(label_id ID!, tenant_id ID!, label_input: InputTenantLabel!): TenantLabel!deleteTenantLabel(label_id: ID!, tenant_id: ID!): TenantLabel!
Note
Some labels are restricted and cannot be modified or deleted. The Tenants API informs you if you attempt to modify a restricted label.
Create a Tenant Label๐
To create a new label on a tenant that you own:
GraphQL๐
mutation createTenantLabel($tenant_id: ID! = "xxxxx", $label_input: InputTenantLabel! = {name: "test", value: "value"})
{
createTenantLabel(tenant_id: $tenant_id, label_input: $label_input)
{
id tenant_id name value owner_partner_tenant_id
}
}
cURL๐
curl --location --request POST 'https://api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation createTenantLabel ($tenant_id: ID!, $label_input: InputTenantLabel!) { createTenantLabel (tenant_id: $tenant_id, label_input: $label_input) { id name value owner_partner_tenant_id } } ","variables":{"tenant_id":xxxxx,"label_input":{"value":"value","name":"test"}}}'
Manage Partner Subscriptions๐
You can manage both available partner subscriptions and subscription assignments on child tenants with the following mutations:
createSubscription(input: NewSubscription!): Service!allows you to create a subscription that can be assigned to child tenants.updateSubscription(input: SubscriptionUpdate!): Service!lets you rename a subscription that you have access to.deleteSubscription(id: ID!): Service!removes a subscription that is not assigned. An error is returned if the subscription is already assigned.assignSubscription(tenant_id: ID!, subscription_id: ID!): Tenant!allows you to set a subscription on a partner child tenant.unassignSubscription(tenant_id: ID!, subscription_id: ID!): Tenant!allows removing a subscription from a partner child tenant.
GraphQL๐
mutation assignSubscription($tenant_id: ID! = "xxxxx", $subscription_id: ID! = "1cb04358-0e00-4ffb-abc8-14ccbc7b42b0")
{
assignSubscription(tenant_id: $tenant_id, subscription_id: $subscription_id)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL๐
curl --location --request POST 'https://api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation($tenant_id: ID!, $subscription_id: ID!) { assignSubscription(tenant_id: $tenant_id, subscription_id: $subscription_id) { id } }","variables":{"tenant_id":"xxxxx","subscription_id":"1cb04358-0e00-4ffb-abc8-14ccbc7b42b0"}}'
Notes๐
subscription_idis returned when you create a subscription. The returnedidvalue is the subscription assignment ID, which you can use to unassign the subscription.
Allow Secureworks Support๐
tenants-api can be used to enable or disable support on the partner child tenants via the following mutations:
enableTenantSupport(tenantID: ID!): Tenant!disableTenantSupport(tenantID: ID!): Tenant!
GraphQL๐
mutation enableTenantSupport($tenantID: ID! = "xxxxx")
{
enableTenantSupport(tenantID: $tenantID)
{
id created_at updated_at enabled name name_normalized domain domain_normalized description allow_response_actions actions_approver labels { id tenant_id name value owner_partner_tenant_id } environments { id created_at updated_at tenant_id name enabled } services { id created_at updated_at name description owner_tenant_id } expires_at partnership { parent is_partner subscriptions { id service_id name description created_at updated_at } child_tenants } support_enabled enabled_in_production enabled_in_pilot
}
}
cURL Disable Support๐
To disable support on a tenant:
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: Bearer { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"mutation { disableTenantSupport (tenantID : \"xxxxx\") { id support_enabled } }","variables":{}}'
Configure Single Sign-On Connections๐
Configuring a third-party identity provider for authentication to the Taegis platform is handled by the Tenants API. Only SAML providers are supported and this guide describes the steps necessary to configure a provider. In this scenario of SAML communications, the Taegis platform is the service provider.
GraphQL๐
mutation createSSOConnection($newConnection: NewSSOConnectionInput!)
{
createSSOConnection(newConnection: $newConnection)
{
id name type status externalName environment externalID tenantID updatedAt createdAt certName expiresAt notBefore issuer subject domains testers ssoConnectionParameters { postBackURL entityID metadataURL callbackURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signingCert signInEndpoint } azureADConnectionConfiguration { clientID clientSecret domain } }
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Context: { TENANT_ID} ' \
--data '{"query":" mutation ($name: String!, $type: SSOConnectionType!, $domains: [String!]!, $testers: [String!]) { createSSOConnection(newConnection: { name: $name, type: $type, domains: $domains, testers: $testers }) { id name type status externalName externalID environment domains testers ssoConnectionParameters { postBackURL entityID metadataURL callbackURL } expiresAt createdAt updatedAt } }","variables":{"name": " { NEW_CONNECTION_NAME } ", "type": "saml", "domains": [" { EMAIL_DOMAIN1 } "], "testers": [" { TESTER1@EMAIL_DOMAIN1} "]}}'
Notes๐
-
Inputs
nameโ The name of the SSO connection to be created. Requiredtypeโ Type of connection, must besaml. Requireddomainsโ List of email domains which use this connection for authentication. Requiredtestersโ List of testers who are the early adopters for this connection. Optional
-
Outputs
idโ The internal ID of the connection.typeโ The type of connection created, should besaml.createdAtโ The time the connection was created.updatedAtโ The time of last update.externalNameโ The connectionโs external name. This is generated.externalIDโ The connectionโs external ID. This is generated.domainsโ The list of configured email domains using this connection.testersโ The list of users testing this connection.statusโ The status of this connection; should report asDraftat this step; other possible values areTesting,Enabled, orDisabled.ssoConnectionParameterspostBackURLโ Used to configure on the identity provider. This is the callback that receives the SAML assertion from the identity provider, also known asassertion consumer service.entityIDโ Identifies the Taegis connection to the identity provider.
The postBackURL and entityID are usually configured on the SAML identity provider prior to continuing to the next step.
Get SSO Configuration๐
The getSSOConnectionConfig query retrieves information that is required by the SAML service provider (Taegis). This step is typically done as pre-confirmation to make sure configuration settings are correct.
GraphQL๐
query getSSOConnectionConfig($metadataURL: String = "metadata_url", $cert: String)
{
getSSOConnectionConfig(metadataURL: $metadataURL, cert: $cert)
{
ssoConnectionConfiguration { samlConnectionConfiguration { signingCert signInEndpoint } azureADConnectionConfiguration { clientID clientSecret domain } } expiresAt notBefore issuer subject
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Context: { TENANT_ID} ' \
--data '{"query":"query ($metadataURL: String, $cert: String) { getSSOConnectionConfig (metadataURL: $metadataURL, cert: $cert) { expiresAt notBefore issuer subject ssoConnectionConfiguration { samlConnectionConfiguration { signInEndpoint signingCert } } } }","variables":{"metadataURL": "{ METADATA_URL }"}}'
Notes๐
Inputs๐
metadataURLspecifies the identity providerโs metadata URL. This is optional and mutually exclusive withcert.certis the signing certificate for the identity provider. This is not strictly necessary since the other data is available and is provided as a convenience. This is optional and mutually exclusive withmetadataURL.
Outputs๐
expiresAtโ Expiration date for the signing certificate.notBeforeโ Start date the signing certificate is valid from.issuerโ Entity that issued the signing certificate.subjectโ Entity the signing certificate was issued for.ssoConnectionConfigurationsamlConnectionConfigurationis returned ifmetadataURLis specified.signInEndpointis the endpoint Taegis invoked to authenticate the SSO user.signingCertis the identity providerโs signing certificate extracted from the metadata URL.
Complete Initial SSO Connection Configuration๐
To complete the initial connection configuration, either the identity providerโs metadata URL or the combination of the signing certificate and sign-in endpoint are required. On successful completion the connection transitions to Testing status.
GraphQL๐
mutation updateSSOConnection($updatedConnection: UpdateSSOConnectionInput! = {id: "connection_id", connectionConfiguration: {samlConfiguration: {metadataURL: "metadata_url", signingCertName: "certificate_name", signingCert: "certificate", signInEndpoint: "sign_in_endpoint"}}})
{
updateSSOConnection(updatedConnection: $updatedConnection)
{
id name type status externalName environment externalID tenantID updatedAt createdAt certName expiresAt notBefore issuer subject domains testers ssoConnectionParameters { postBackURL entityID metadataURL callbackURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signingCert signInEndpoint } azureADConnectionConfiguration { clientID clientSecret domain } }
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Context: { TENANT_ID} ' \
--data '{"query":"mutation ($id: ID!, $signingCert: String, $signInEndpoint: String, $metadataURL: String, $certName: String) { updateSSOConnection ( updatedConnection: { id: $id, samlConfiguration: { metadataURL: $metadataURL, signingCert: $signingCert, signInEndpoint: $signInEndpoint, signingCertName: $certName } } ) { id name externalName externalID createdAt updatedAt type status domains testers certName notBefore expiresAt issuer subject ssoConnectionParameters { postBackURL entityID metadataURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signInEndpoint signingCert } } }}","variables":{"id": " { CONNECTION_ID } ", "metadataURL": " { METADATA_URL } ", "certName": "issuer.pem"}}'
Notes๐
Inputs๐
idโ Internal ID of the connection. RequiredsamlConfigurationmetadataURLโ URL that allows downloads of the identity providerโs configuration. This is optional and if provided, thesigningCertinput is ignored.signingCertโ The identity providerโs signing certificate. This isoptional and if specified andmetadataURLis not,signInEndpointmust also be specified.signInEndpointโ URL to be used to authenticate the SSO user. This is optional and must be specified ifsigningCertis used.signingCertNameโ File name of the signing certificate; used to historically identify the last certificate used, but not used to retrieve the certificate from the userโs local file system. Optional
Outputs๐
idโ Internal ID of the connection.nameโ The connection name.externalNameโ External name used by Taegis to handle SSO authentication.externalIDโ External ID used by Taegis to handle SSO authentication.createdAtโ The time the connection was created.updatedAtโ The time the connection was last updated.typeโ The type of SSO connection; only SAML is currently supportedstatusโ Connection status, which transitions toTestingon successful completion of the request.domainsโ The email domains that authenticate using this connection.testersโ The list of testerscerNameโ If specified in the update request, the certificate file name.notBeforeโ The time the signing certificate is valid from.expiresAtโ The time the signing certificate expires.issuerโ The entity that issued the signing certificate.subjectโ The entity the signing certificate was issued to.ssoConnectionParametersโ The service providerโs (Taegis) SAML attributespostBackURLโ The endpoint that receives the SAML assertion response from the identity provider.entityIDโ Identifier for the Taegis SAML entity.metadataURLโ URL the identity provider can use in the future to download Taegisโs SAML configuration if updates are needed.
ssoConnectionIDPConfigโ The identity providerโs configuration.samlConnectionConfigurationsignInEndpointโ The endpoint Taegis uses to authenticate SSO users.signingCertโ The identity providerโs signing certificate.
Updating SSO Connections๐
After testing is complete, the SSO connection must be placed in Enabled status to make it available to the registered email domains. Other attributes may also need to be adjusted. For example, a new signing certificate when the configured one is set to expire.
GraphQL๐
mutation updateSSOConnection($updatedConnection: UpdateSSOConnectionInput! = {id: "connection_id", status: "Enabled"})
{
updateSSOConnection(updatedConnection: $updatedConnection)
{
id name type status externalName environment externalID tenantID updatedAt createdAt certName expiresAt notBefore issuer subject domains testers ssoConnectionParameters { postBackURL entityID metadataURL callbackURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signingCert signInEndpoint } azureADConnectionConfiguration { clientID clientSecret domain } }
}
}
cURL๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Context: { TENANT_ID} ' \
--data '{"query":" mutation ($id: ID!, $addTesters: [String!], $removeTesters: [String!], $addDomains: [String!], $removeDomains: [String!], $status: SSOConnectionStatus, $signingCert: String, $signInEndpoint: String, $metadataURL: String, $certName: String) { updateSSOConnection(updatedConnection: { id: $id, connectionConfiguration: { samlConfiguration: { signingCert: $signingCert, signInEndpoint: $signInEndpoint } } }) { id name type status externalName externalID environment domains testers expiresAt createdAt updatedAt ssoConnectionParameters { postBackURL entityID metadataURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signInEndpoint signingCert } } } }","variables":{"id": " { CONNECTION_ID } ", "status": "Enabled"}}'
Notes๐
Inputs๐
idโ Internal ID of the connection. Requiredstatusโ Updates the status of the connection. Valid values areEnabled,Disabled, orTesting. OptionaladdTestersโ A string array of new testers to add. OptionalremoveTestersโ A string array of testers to remove. OptionaladdDomainsโ A string array of email domains to add. OptionalremoveDomainsโ A string array of email domains to remove. OptionalsamlConfigurationmetadataURLโ URL that allows downloads of the identity providerโs configuration. If provided, thesigningCertinput is ignored. OptionalsigningCertโ The identity providerโs signing certificate. If specified butmetadataURLis not,signInEndpointmust also be specified. OptionalsignInEndpointโ URL to be used to authenticate the SSO user. Optional, but must be specified ifsigningCertis used.signingCertNameโ File name of the signing certificate. Used to historically identify the last certificate used and not used to retrieve the certificate from the userโs local file system. Optional
Outputs๐
idโ Internal ID of the connection.nameโ The connection name.externalNameโ External name used by Taegis to handle SSO authentication.externalIDโ External ID used by Taegis to handle SSO authentication.createdAtโ The time the connection was created.updatedAtโ The time the connection was last updated.typeโ The type of SSO connection. Only SAML is currently supported.statusโ Connection status; this should transition toTestingon successful completion of this request.domainsโ The email domains that authenticate using this connection.testersโ The list of testers.cerNameโ If specified in the update request, this is the certificate file name.notBeforeโ The time the signing certificate is valid from.expiresAtโ The time the sigining certificate expires.issuerโ The entity which issued the signing certificate.subjectโ The entity the signing certificate was issued to.ssoConnectionParametersโ The service providerโs (Taegis) SAML attributes.postBackURLโ The endpoint that receives the SAML assertion response from the identity provider.entityIDโ Identifier for the Taegis SAML entity.metadataURLโ URL the identity provider can use in the future to download Taegisโs SAML configuration if updates are needed.
ssoConnectionIDPConfigโ The identity providerโs configuration.samlConnectionConfigurationsignInEndpointโ The endpoint Taegis uses to authenticate SSO users.signingCertโ The identity providerโs signing certificate.
Delete SSO Connections๐
GraphQL๐
mutation deleteSSOConnection($connectionID: ID! = "connection_id")
{
deleteSSOConnection(connectionID: $connectionID)
{
id name type status externalName environment externalID tenantID updatedAt createdAt certName expiresAt notBefore issuer subject domains testers ssoConnectionParameters { postBackURL entityID metadataURL callbackURL } ssoConnectionIDPConfig { samlConnectionConfiguration { signingCert signInEndpoint } azureADConnectionConfiguration { clientID clientSecret domain } }
}
}
cURL Delete SSO Configuration Example๐
curl --location --request POST 'https:// api.tenants.ctpx.secureworks.com/public/query' \
--header 'Authorization: { ACCESS_TOKEN }' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Context: { TENANT_ID} ' \
--data '{"query":"mutation ($connectionID: ID!) { deleteSSOConnection(connectionID: $connectionID) { id name type status externalName externalID domains testers } }","variables":{"connectionID": " { CONNECTION_ID } "}}'
Notes๐
Inputs๐
connectionIDโ Internal ID of the connection. Required
Outputs๐
idโ Internal ID of the connection.nameโ The connection name.typeโ The type of SSO connection; only SAML is currently supported.statusโ Connection status; transitions toTestingon successful completion of the request.externalNameโ External name used by Taegis to handle SSO authentication.externalIDโ External ID used by Taegis to handle SSO authentication.domainsโ Email domains that authenticate using this connection.testersโ The list of testers.