Using 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
mutation
requires specialTenant:update
orTenant:create
access. TenantAdmin
on 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/json
header (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 ⫘
partnerTenantID
is 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
labels
using theowner_parent_tenant_id
. In the example abovepartner_only_label_name
is only visible to tokens that can access tenantxxxxx
. You can only set label ownership to the parent tenant for now. environments
can be used to set a list of environments where you want this child tenant enabled at, in this example the new tenant is enabled inecho
andpilot
.
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-test/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-test/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-test/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_id
can 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_id
is returned when you create a subscription. The returnedid
value 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 asDraft
at this step; other possible values areTesting
,Enabled
, orDisabled
.ssoConnectionParameters
postBackURL
— 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 ⫘
metadataURL
specifies the identity provider’s metadata URL. This is optional and mutually exclusive withcert
.cert
is 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.ssoConnectionConfiguration
samlConnectionConfiguration
is returned ifmetadataURL
is specified.signInEndpoint
is the endpoint Taegis invoked to authenticate the SSO user.signingCert
is 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. RequiredsamlConfiguration
metadataURL
— URL that allows downloads of the identity provider’s configuration. This is optional and if provided, thesigningCert
input is ignored.signingCert
— The identity provider’s signing certificate. This isoptional and if specified andmetadataURL
is not,signInEndpoint
must also be specified.signInEndpoint
— URL to be used to authenticate the SSO user. This is optional and must be specified ifsigningCert
is 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 toTesting
on 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.samlConnectionConfiguration
signInEndpoint
— 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. OptionalsamlConfiguration
metadataURL
— URL that allows downloads of the identity provider’s configuration. If provided, thesigningCert
input is ignored. OptionalsigningCert
— The identity provider’s signing certificate. If specified butmetadataURL
is not,signInEndpoint
must also be specified. OptionalsignInEndpoint
— URL to be used to authenticate the SSO user. Optional, but must be specified ifsigningCert
is 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 toTesting
on 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.samlConnectionConfiguration
signInEndpoint
— 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 toTesting
on 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.