> ## Documentation Index
> Fetch the complete documentation index at: https://docs.airmdr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Abnormal Security

> The Abnormal Security integration enables AirMDR to securely connect to the Abnormal Security REST API and use supported skills to retrieve or manage Abnormal Security data, such as detected email threats and security cases.

## Supported Versions

| Component             | Supported version                                           |
| --------------------- | ----------------------------------------------------------- |
| Abnormal Security     | Cloud-based Abnormal Security platform with REST API access |
| Abnormal Security API | REST API v1                                                 |
| AirMDR                | Current cloud-hosted AirMDR platform                        |
| Authentication        | Bearer API token                                            |
| Network protocol      | HTTPS over TCP port 443                                     |

## Authentication

AirMDR authenticates with Abnormal Security using a bearer API token.

When AirMDR makes an API request, the token is submitted in the following HTTP header: `Authorization: Bearer <API_TOKEN>`

<Note>
  Enter only the generated token in the AirMDR **API Token** field. Do not add the `Bearer` prefix unless the AirMDR UI explicitly requests it.
</Note>

### Required role

The user creating the token must be able to:

* Access **Settings → Integrations**.
* Create and manage API tokens.
* Select the tenant associated with the token.
* Assign API endpoint permissions.
* Configure token expiration and IP safelisting, when applicable.

### Token access requirements

Use **Custom Access** and grant only the endpoints required by the AirMDR skills that will use this connection.

For example:

| AirMDR operation              | Suggested Abnormal Security access            |
| ----------------------------- | --------------------------------------------- |
| Retrieve detected threats     | **Threats – Read Access**                     |
| Retrieve case information     | **Cases – Read Access**                       |
| Retrieve employee information | **Employees – Read Access**                   |
| Perform an action on a threat | Corresponding **Threats write/manage access** |
| Perform an action on a case   | Corresponding **Cases write/manage access**   |

### Pre-requisites

> <Check>
>   Users must have Administrator access to the **Abnormal Security** UI with sufficient privileges to create an API key.
> </Check>
>
> <Check>
>   Permission to create and access the Abnormal Security **API keys** settings.
> </Check>

<Note>
  Some endpoints require an additional Abnormal Security license. For example, access to the Cases API requires an Account Takeover Protection license.
</Note>

## Setup Steps

<Steps>
  <Step title="Identify the Tines tenant domain">
    1. Sign in to the [Abnormal Security](https://portal.abnormalsecurity.com) portal.
    2. From the navigation menu, select **Settings & Configuration →** **Integrations**.
    3. Locate the **API Token Management** section.
    4. Click **+ Create New Token**.
           <Frame>
             <img src="https://mintcdn.com/airmdr/4djC6l8gft8IDslc/images/image-5.png?fit=max&auto=format&n=4djC6l8gft8IDslc&q=85&s=6469d4b03ac4834ba3702a5b146cb41b" alt="Image" width="1458" height="238" data-path="images/image-5.png" />
           </Frame>
    5. For **Integration Type**, select **REST API**.
    6. Click **Next**.
    7. Continue with the applicable token-scope procedure, under **Token Scope**, select the appropriate scope.
       * Option 1: Tenant (Single Tenant)
       * Option 2: Customer (Multiple Tenants)
  </Step>

  <Step title="Option 1: Tenant (Single Tenant)">
    Use this scope when the AirMDR connection needs to access only one Abnormal Security tenant.

    1. Under **Token Scope**, select **Tenant (Single Tenant)**.
    2. From the tenant list, select the organization that will connect to AirMDR.
    3. Click **Next**.
    4. Under **Configure Access Type**, select **Custom Access**.
    5. Select the API endpoints required by the supported AirMDR skills.
    6. Assign the minimum required access level to each selected endpoint.
       For example:
       | Required operation                      | Suggested access                              |
       | --------------------------------------- | --------------------------------------------- |
       | Retrieve detected threats               | Threats – Read Access                         |
       | Retrieve security cases                 | Cases – Read Access                           |
       | Retrieve employee information	Employees | **Employees – Read Access**                   |
       | Perform actions on threats              | Corresponding **Threats write/manage access** |
       | Perform actions on cases                | Corresponding **Cases write/manage access**   |
    7. Click **Next**.
    8. Continue to Configure the Token Details.
           <Note>
             Access to some endpoints may depend on the Abnormal Security products licensed for the selected tenant. For example, the Cases API requires an Account Takeover Protection entitlement.
           </Note>
  </Step>
</Steps>

### Tines Credential Reference Table

| AirMDR Field      | What to Enter                                | Where to Get It in the Tines UI                                                                                                                                          | Example                     |
| ----------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- |
| **Tenant Domain** | Base URL of the Tines tenant                 | Sign in to the required Tines tenant and copy the base URL from the browser address bar. Do not include API, team, or story paths.                                       | `https://company.tines.com` |
| **API Key**       | API key generated for the AirMDR integration | In Tines, navigate to **Settings → Access & security → API keys → New API key**. Configure the appropriate key type and permissions, create the key, and copy its value. | `<TINES_API_KEY>`           |

<Note>
  Tines does not generate a separate Tenant Key. Enter the Tines tenant’s base URL in the AirMDR **Tenant Domain** field.
</Note>

### Validate Connectivity

Use the following request to confirm that the tenant domain and API key can access the Tines Teams API:

<AccordionGroup>
  <Accordion title="Sample Request ">
    ```json theme={null}
    curl --proto '=https' --tlsv1.2 \
      -X GET "https://<tenant-domain>/api/v1/teams" \
      -H "content-type: application/json" \
      -H "Authorization: Bearer <TINES_API_KEY>"
    ```
  </Accordion>

  <Accordion title="Sample Response">
    **Sample Successful Response:**

    ```text theme={null}
    A successful request returns the teams accessible to the API key. The /api/v1/teams endpoint and bearer-token format are documented by Tines.
    ```

    ```json theme={null}
    {
      "teams": [
        {
          "id": 1,
          "name": "Security Team",
          "groups": [
            {
              "id": 3,
              "name": "Tier 1"
            }
          ]
        },
        {
          "id": 2,
          "name": "Engineering Team",
          "groups": []
        }
      ],
      "meta": {
        "current_page": "https://<tenant-domain>/api/v1/teams?per_page=20&page=1",
        "previous_page": null,
        "next_page": null,
        "next_page_number": null,
        "per_page": 20,
        "pages": 1,
        "count": 2
      }
    }
    ```
  </Accordion>
</AccordionGroup>

<Note>
  A successful request returns the teams accessible to the API key. The `/api/v1/teams` endpoint and bearer-token format are documented by Tines.
</Note>

<Check>
  Do not run the command on shared systems or save the API key in shell history. Use environment variables or an approved secret manager where possible.
</Check>

### Configure **Abnormal Security** in AirMDR Integrations Dashboard

1. Navigate to [AirMDR](https://app.airmdr.com/auth/login), provide the credentials and click **Login**
2. Navigate to the AirMDR Integrations Dashboard in the left navigation pane and select **ADMIN → Integrations**.
3. Use the search option, enter the keyword "**Tines**", select the **Connections** tab, and click **+ New Connection** button.
4. Use the following values in the AirMDR integration configuration screen:
   | AirMDR Field      | Description                              | Example                        |
   | :---------------- | :--------------------------------------- | :----------------------------- |
   | **Instance**      | Unique name for the connection           | `Tines-Production`             |
   | **Organization**  | Organization associated with Integration | `AirMDR Organization`          |
   | **Description**   | Purpose of the connection                | `Tines production integration` |
   | **Tenant Domain** | Base URL copied from Tines               | `https://company.tines.com`    |
   | **API Key**       | API key generated in Tines               | `<TINES_API_KEY>`              |
   <Accordion title="Expand Advanced Configuration if required. (Optional)">
     1. In **Remote Agent**, select an AirMDR Remote Agent only when the Tines tenant is self-hosted, privately accessible, or must be reached through an approved private network route.
     2. In **Expiry**, select the date on which AirMDR should treat the stored connection credentials as expired, according to your organisation’s credential-rotation policy.
          <Note>
            The AirMDR **Expiry** setting is a connection-management control. It does not automatically configure or rotate the API key in Tines.
          </Note>
   </Accordion>
5. Click **Save**.

### Skills provided by this Integration

<AccordionGroup>
  <Accordion title="Artifact Management">
    | **Skill ID**           | **Purpose**                                                                                    | **Minimum Tines Role** | **Required Access**                         |
    | ---------------------- | ---------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------------- |
    | **Get Tines Artifact** | Retrieves large text-based data or content stored as an artifact for a specified Tines record. | Viewer                 | Read records and their associated artifacts |
  </Accordion>

  <Accordion title="Story Management">
    | **Skill ID**           | **Purpose**                                                                                                                 | **Minimum Tines Role** | **Required Access**                   |
    | ---------------------- | --------------------------------------------------------------------------------------------------------------------------- | :--------------------- | :------------------------------------ |
    | **List Tines Stories** | Retrieves stories from the Tines instance, with optional filtering by team or folder.                                       | Viewer                 | Read stories within the assigned team |
    | **Get Tines Story**    | Retrieves the details and configuration of a specified Tines story using its story ID.                                      | Viewer                 | Read stories within the assigned team |
    | **Create Tines Story** | Creates a story within a specified Tines team, with optional folder placement and tag configuration.                        | Editor                 | Create stories                        |
    | **Update Tines Story** | Updates an existing story’s properties, including its name, enabled or disabled status, tags, and event-retention settings. | Editor                 | Update stories                        |
  </Accordion>

  <Accordion title="Case Management">
    | **Skill ID**          | **Purpose**                                                                                   | **Minimum Tines Role** | **Required Access**                 |
    | :-------------------- | :-------------------------------------------------------------------------------------------- | :--------------------- | :---------------------------------- |
    | **List Tines Cases**  | Retrieves cases available in the connected Tines instance.                                    | Viewer                 | Read cases within the assigned team |
    | **Get Tines Case**    | Retrieves the complete details of a specified Tines case using its case ID.                   | Viewer                 | Read cases within the assigned team |
    | **Create Tines Case** | Creates a case within a specified Tines team using the supplied case information.             | Editor or Case Manager | Create  cases                       |
    | **Update Tines Case** | Updates the information or configuration of an existing case in the connected Tines instance. | Editor or Case Manager | Update cases                        |
  </Accordion>

  <Accordion title="Resource Management">
    | **Skill ID**              | **Purpose**                                                                                                 | **Minimum Tines Role** | **Required Access**                            |
    | :------------------------ | :---------------------------------------------------------------------------------------------------------- | :--------------------- | :--------------------------------------------- |
    | **List Tines Resources**  | Retrieves resources from the Tines instance, with optional filtering by team or folder.                     | Viewer                 | Read resources within the assigned team        |
    | **Get Tines Resource**    | Retrieves the details and stored value of a specified Tines resource using its resource ID.                 | Viewer                 | Read resources within the assigned team        |
    | **Update Tines Resource** | Updates a live resource or its test version, including its name, stored value, and access-control settings. | Editor                 | Update a resource’s name, value, or test value |
  </Accordion>

  <Accordion title="Record Management">
    | **Skill ID**            | **Purpose**                                                                                                                    | **Minimum Tines Role** | **Required Access**                          |
    | :---------------------- | :----------------------------------------------------------------------------------------------------------------------------- | :--------------------- | :------------------------------------------- |
    | **Create Tines Record** | Creates a record within a specified Tines record type (widget) and can optionally associate the record with one or more cases. | Editor                 | Create records within available record types |
  </Accordion>

  <Accordion title="Event Management">
    | **Skill ID**          | **Purpose**                                                                                  | **Minimum Tines Role** | **Required Access**                  |
    | :-------------------- | :------------------------------------------------------------------------------------------- | :--------------------- | :----------------------------------- |
    | **List Tines Events** | Retrieves recent events from the Tines instance, with optional filtering by story or team.   | Viewer                 | Read events within the assigned team |
    | **Get Tines Event**   | Retrieves the payload and associated metadata of a specified Tines event using its event ID. | Viewer                 | Read events within the assigned team |
  </Accordion>

  <Accordion title="Workflow Execution">
    | **Skill ID**           | **Purpose**                                                                                             | **Minimum Tines Role** | **Required Access**                           |
    | :--------------------- | :------------------------------------------------------------------------------------------------------ | :--------------------- | :-------------------------------------------- |
    | **Send Tines Webhook** | Sends a webhook request to a specified Tines webhook endpoint to initiate or continue a Tines workflow. | Editor                 | Run or initiate the associated Tines workflow |
  </Accordion>
</AccordionGroup>

<Tip>
  To view the details of Input Parameters and Output for the respective skills

  * Go to [AirMDR → Tines](https://app.airmdr.com/integrationsv2/126ec408-3021-4002-acab-1d125e1b8a71/skills?search=TINES) Integration page.
  * Select the **Skills** tab and click on the required listed skills.
</Tip>

## Additional Information

<AccordionGroup>
  <Accordion title="🧰 Error Handling">
    | Error or symptom                                  | Likely cause                                                                    | Resolution                                                                                   |
    | ------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
    | **Invalid tenant domain**                         | Login URL, API path, team path, or incorrect tenant was entered                 | Enter only the base tenant URL, such as `https://company.tines.com`                          |
    | **401 Unauthorized**                              | API key is missing, invalid, deleted, or incorrectly copied                     | Generate or copy a valid key and update the AirMDR connection                                |
    | **404 Not Found**                                 | Resource does not exist, or the key lacks permission to access it               | Verify the resource and assign the required team role or tenant permission                   |
    | **403 Forbidden**                                 | Access is blocked by tenant security or access-control policy                   | Review tenant permissions, IP restrictions, and organisational security controls             |
    | **429 Too Many Requests**                         | Tines API rate limit was reached                                                | Reduce request frequency and retry with exponential backoff                                  |
    | **Connection timeout**                            | DNS, firewall, proxy, or Remote Agent connectivity issue                        | Allow outbound TCP 443 and verify access to the configured tenant domain                     |
    | **TLS or certificate error**                      | Invalid, expired, or untrusted certificate, commonly in self-hosted deployments | Install a trusted certificate and verify the certificate chain                               |
    | **Some skills work, but others fail**             | The API key has partial access                                                  | Map each failing skill to the required Tines resource and grant only the missing permissions |
    | **Connection stops after the AirMDR expiry date** | The AirMDR connection has reached its configured expiry                         | Rotate or validate the key and update the AirMDR expiry setting                              |
    | **Wrong tenant data returned**                    | Domain belongs to a different Tines tenant                                      | Delete or update the connection using the correct tenant domain                              |
  </Accordion>

  <Accordion title="🔄 Monitoring & Logs">
    ### AirMDR monitoring

    Use the AirMDR application to review:

    * Connection status.
    * Skill execution status.
    * Execution start and completion times.
    * API error codes and error messages.
    * Remote Agent connectivity, when applicable.
          <Note>
            The exact log location and displayed fields can vary according to the AirMDR module from which the skill was executed.
          </Note>
      ### Tines audit logs
      Tines automatically records changes made through both its UI and API. Tenant administrators can access audit logs through the Tines UI or API and forward them to a SIEM or log-analysis platform. API-key creation, editing, and deletion are logged as authentication-token operations. Sensitive credential values are not included in Tines audit logs.<br />**Relevant audit operations include:**<br />`AuthenticationTokenCreation` `AuthenticationTokenEdit` `AuthenticationTokenDeletion`<br />**Sample Tines audit log**<br />`{` `  "created_at": "2026-08-14T10:30:00Z",` `  "request_ip": "192.0.2.10",` `  "tenant_id": 9,` `  "user_email": "airmdr-service@example.com",` `  "user_id": 123,` `  "user_name": "AirMDR Integration",` `  "operation_name": "AuthenticationTokenCreation"` `}`
          <Note>
            This sample illustrates the documented Tines audit-log structure. Actual values depend on the tenant and operation.
          </Note>
      ### Recommended monitoring
      * Monitor repeated `401`, `404`, `429`, and `5xx` responses.
      * Review API-key creation, modification, and deletion events.
      * Alert on unexpected activity from the AirMDR service account.
      * Review the API key’s team roles and tenant permissions periodically.
      * Monitor the AirMDR connection expiry date and planned key-rotation date.
  </Accordion>

  <Accordion title="🛑 Security & Access Best Practices">
    ### ✅ Do

    * Use a dedicated Team or Service API key for AirMDR.
    * Follow the principle of least privilege.
    * Restrict a Team API key to the team AirMDR must access.
    * Store the API key only in approved secret-storage systems.
    * Rotate the key periodically and after any suspected exposure.
    * Set an AirMDR connection expiry date aligned with the rotation policy.
    * Review Tines audit logs for unexpected API-key activity.
    * Use HTTPS and validate certificates.
    * Use a Remote Agent for privately accessible self-hosted environments when required.
    * Delete unused or superseded keys promptly.

    ### ❌ Don’t

    * Do not use a Tenant owner API key unless full tenant access is explicitly required.
    * Do not use a personal API key for a long-running production integration.
    * Do not enter `login.tines.com` as the tenant domain.
    * Do not include `/api/v1`, `/api/v2`, team paths, or story paths in the Tenant Domain field.
    * Do not store API keys in documentation, source control, or plain-text files.
    * Do not send API keys through email, chat, or support tickets.
    * Do not reuse the AirMDR API key across unrelated integrations.
    * Do not log authentication headers or API-key values.
  </Accordion>

  <Accordion title="👉 Support & Maintenance">
    * 📧 Contact [**AirMDR Support**](mailto:support@airmdr.com) through your designated support channel.
    * 🔁 Rotate credentials regularly. Recommended cadence: Every 90 days or as per internal security policy
    * 🔄 **Reconnect in AirMDR immediately when secrets are changed.**
  </Accordion>

  <Accordion title="🛑 Data Flow & Security">
    ### Data flow

    | Direction      | Data exchanged                                                                                               |
    | :------------- | :----------------------------------------------------------------------------------------------------------- |
    | AirMDR → Tines | Authenticated API requests required by the selected Tines skill                                              |
    | Tines → AirMDR | API responses containing permitted team, story, case, event, record, status, or execution information        |
    | AirMDR → Tines | Create, update, or execution requests only when supported by the selected skill and permitted by the API key |

    The exact information exchanged depends on the AirMDR skill being executed and the permissions assigned to the Tines API key.

    ### Authentication flow

    1. AirMDR sends an HTTPS request to the configured Tines tenant domain.
    2. The Tines API key is supplied in the request authentication header.
    3. Tines validates the key and its associated user, service account, team role, or tenant permissions.
    4. Tines processes the request only when the key has access to the requested resource.
    5. The API response is returned to AirMDR over HTTPS.

    ### Encryption

    * Tines requires authenticated API communication over HTTPS.
    * Tines states that customer personal data is encrypted in transit using at least TLS 1.2.
    * Tines states that customer personal data stored at rest is encrypted using AES-256.
    * AirMDR should store the API key as a secret and must not expose it in skill inputs, logs, screenshots, or exported troubleshooting data.

    ### Ports and endpoints

    | Requirement          | Value                                                 |
    | :------------------- | :---------------------------------------------------- |
    | Protocol             | HTTPS                                                 |
    | Outbound port        | TCP 443                                               |
    | Base endpoint        | `https://<tenant-domain>`                             |
    | API endpoint pattern | `https://<tenant-domain>/api/v1/...` or `/api/v2/...` |
    | Authentication       | Bearer token or `X-User-Token` header                 |

    No inbound connection from Tines is required for standard AirMDR-initiated API requests. If a supported workflow uses Tines webhooks, configure and secure the required inbound webhook separately
  </Accordion>
</AccordionGroup>
