Skip to content

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 mutation requires special Tenant:update or Tenant: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 (as TenantAdmin), to be able to create child tenants.
  • You can restrict the audience for labels using the owner_parent_tenant_id. In the example above partner_only_label_name is only visible to tokens that can access tenant xxxxx. 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 in echo and pilot.

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_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 returned id 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. Required
    • type — Type of connection, must be saml. Required
    • domains — List of email domains which use this connection for authentication. Required
    • testers — 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 be saml.
    • 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 as Draft at this step; other possible values are Testing, Enabled, or Disabled.
    • ssoConnectionParameters
      • postBackURL — Used to configure on the identity provider. This is the callback that receives the SAML assertion from the identity provider, also known as assertion 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 with cert.
  • 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 with metadataURL.
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 if metadataURL 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. Required
  • samlConfiguration
    • metadataURL — URL that allows downloads of the identity provider’s configuration. This is optional and if provided, the signingCert input is ignored.
    • signingCert — The identity provider’s signing certificate. This isoptional and if specified and metadataURL is not, signInEndpoint must also be specified.
    • signInEndpoint — URL to be used to authenticate the SSO user. This is optional and must be specified if signingCert 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 supported
  • status — Connection status, which transitions to Testing on successful completion of the request.
  • domains — The email domains that authenticate using this connection.
  • testers — The list of testers
  • cerName — 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 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.

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. Required
  • status — Updates the status of the connection. Valid values are Enabled, Disabled, or Testing. Optional
  • addTesters — A string array of new testers to add. Optional
  • removeTesters — A string array of testers to remove. Optional
  • addDomains — A string array of email domains to add. Optional
  • removeDomains — A string array of email domains to remove. Optional
  • samlConfiguration
    • metadataURL — URL that allows downloads of the identity provider’s configuration. If provided, the signingCert input is ignored. Optional
    • signingCert — The identity provider’s signing certificate. If specified but metadataURL is not, signInEndpoint must also be specified. Optional
    • signInEndpoint — URL to be used to authenticate the SSO user. Optional, but must be specified if signingCert 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 to Testing 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 to Testing 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.