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

# Connections

> Connect your tools, observability platforms, and cloud log providers to Struct

Struct integrates with your existing stack to receive alerts, query logs and metrics, and deliver investigation reports where your team already works.

| Category                                               | Connections                                                   |
| ------------------------------------------------------ | ------------------------------------------------------------- |
| [Work & Collaboration](#work--collaboration)           | GitHub (required), Slack, Linear, Asana                       |
| [Observability Platforms](#observability-platforms)    | Sentry, Datadog, Grafana, Prometheus, Loki, SumoLogic, Render |
| [Cloud Log Providers](#cloud-log-providers)            | AWS CloudWatch, Azure Monitor, Google Cloud Logging           |
| [Container & Orchestration](#container--orchestration) | Kubernetes                                                    |

<Note>
  All observability and cloud log integrations are **read-only**. Struct never modifies your monitoring configuration, log groups, or workspaces.
</Note>

***

## Work & Collaboration

| Integration       | Required | Purpose                                           |
| ----------------- | -------- | ------------------------------------------------- |
| [GitHub](#github) | **Yes**  | Codebase context and PR creation                  |
| [Slack](#slack)   | No       | Receive investigations, trigger on-demand queries |
| [Linear](#linear) | No       | Trigger from issues, track progress               |
| [Asana](#asana)   | No       | Trigger from tasks (requires configuration)       |

***

## GitHub

<Warning>**Required.** GitHub is how Struct accesses your codebase during investigations and creates pull requests.</Warning>

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to GitHub" />

  <Step title="Install the Struct GitHub App" />

  <Step title="Select which repositories to enable" />
</Steps>

With GitHub connected, Struct can:

* Cross-reference errors with recent commits and deployments
* Search your codebase for relevant code paths
* Create branches and pull requests when a fix is approved

<Tip>
  Start with a single repository to test the workflow before expanding access.
</Tip>

***

## Slack

Connect Slack to receive investigation reports and trigger on-demand investigations.

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Slack" />

  <Step title="Authorize the Struct app in your workspace" />

  <Step title="Invite @Struct to channels where alerts are posted" />
</Steps>

### Triggering Investigations

Mention Struct in any channel where it's been invited:

```
@Struct investigate high error rate on the payments API
```

Struct responds in-thread with a structured investigation report.

<Tip>
  You can ask follow-up questions directly in the thread—Struct maintains full context throughout the conversation.
</Tip>

### Auto-Investigation

Struct can also automatically investigate messages in your configured investigation channels. Configure keyword filters to control which alerts trigger investigations, or let AI classification decide.

See [Auto-Investigations](/auto-investigations#slack) for setup details.

***

## Linear

Connect Linear to trigger investigations from issues and receive updates as comments.

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Linear" />

  <Step title="Authorize and select teams to monitor" />
</Steps>

Assign an issue to Struct or @tag it in a comment to trigger an investigation. Struct posts its findings as a comment on the issue.

### Auto-Investigation

Enable auto-investigation to have Struct automatically investigate new issues created in your default team. Configure keyword filters to focus on specific issue types.

See [Auto-Investigations](/auto-investigations#linear) for setup details.

***

## Asana

Connect Asana to trigger investigations from tasks.

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Asana" />

  <Step title="Authorize and select projects to monitor" />
</Steps>

<Warning>
  Automatic investigation triggers are not enabled by default. Enable auto-investigation and configure keyword filters in **Connections** → **Asana** → **Manage**.
</Warning>

See [Auto-Investigations](/auto-investigations#asana) for setup details.

***

## Observability Platforms

Struct queries your observability platforms during investigations to pull error details, metrics, traces, and alert context. The more sources connected, the richer the investigation.

| Platform                  | What Struct Pulls                                          |
| ------------------------- | ---------------------------------------------------------- |
| [Sentry](#sentry)         | Stack traces, breadcrumbs, error frequency, affected users |
| [Datadog](#datadog)       | Metrics, monitors, APM traces, event context               |
| [Grafana](#grafana)       | Dashboard data, alert rules, annotations                   |
| [Prometheus](#prometheus) | Metrics, alerting rules, time-series data                  |
| [Loki](#loki)             | Log streams, label-based log queries                       |
| [SumoLogic](#sumologic)   | Log analytics, search results                              |
| [Render](#render)         | Service logs, deploy events                                |
| [Snowflake](#snowflake)   | Telemetry (event tables), query history, read-only SQL     |

<Tip>
  To connect an observability platform, go to **Connections** and click **Connect** next to the platform.
</Tip>

***

## Sentry

<Tip>**Recommended.** Sentry is one of the most impactful integrations—it gives Struct direct access to error details and stack traces.</Tip>

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Sentry" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from Sentry

* **Stack traces** — Pinpoints the exact code path that threw the error
* **Breadcrumbs** — Reconstructs the sequence of events leading to the error
* **Error frequency** — Determines if this is a new issue or a recurring pattern
* **Affected users** — Assesses impact scope

### Example

When a Sentry alert fires, Struct automatically:

1. Pulls the full stack trace and breadcrumbs
2. Cross-references the failing code with recent commits
3. Checks if this error pattern has appeared in previous investigations
4. Delivers a root cause report to Slack

***

## Datadog

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Datadog" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### Required application key scopes

Datadog enforces read permissions on the **application key's** role, not the API key. The role attached to the application key you provide must grant all of the following scopes, or Struct will receive `403 Forbidden` from the corresponding endpoints:

| Scope              | Permission      | Used for                          |
| ------------------ | --------------- | --------------------------------- |
| `logs_read_data`   | Logs Read       | Searching and reading logs        |
| `timeseries_query` | Metrics Query   | Querying metric timeseries values |
| `monitors_read`    | Monitors Read   | Reading monitors and alert state  |
| `dashboards_read`  | Dashboards Read | Listing and reading dashboards    |

<Warning>
  `timeseries_query` ("Query Timeseries Data") is a separate permission from "Metrics Read" metadata access. Without it, metric **queries** fail with `403 Forbidden` even though listing metric names succeeds. Make sure the application key's role has `timeseries_query` enabled.
</Warning>

### What Struct uses from Datadog

* **Metrics** — CPU, memory, latency, error rates, and custom metrics
* **APM traces** — Distributed traces across services; fetch a full trace by trace ID to inspect span timing and pinpoint the slow or failing service
* **Monitors** — Alert context and monitor history
* **Events** — Deployment events, configuration changes

<Tip>
  Struct can query Datadog metrics in natural language during an investigation. For example: *"Show me p99 latency for the checkout service over the last 2 hours."*
</Tip>

<Note>
  APM trace retrieval requires the Datadog **Application Key** to have the `apm_read` (APM Read) scope.
</Note>

***

## Grafana

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Grafana" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from Grafana

* **Dashboard data** — Queries panels for relevant metrics
* **Alert rules** — Understands what thresholds triggered
* **Annotations** — Correlates deployments and incidents with metric changes

***

## Prometheus

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Prometheus" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from Prometheus

* **Metrics** — Queries PromQL-compatible metrics during investigations
* **Alerting rules** — Reads active and pending alerts for context
* **Time-series data** — Analyzes trends around the time of the incident

***

## Loki

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Loki" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from Loki

* **Log streams** — Queries logs by labels, service, and time range
* **Log context** — Pulls surrounding log lines for errors

### Example query Struct might run

```logql theme={null}
{service="api-gateway"} |= "error" | json | status >= 500
```

<Tip>
  If you use Grafana with Loki as a data source, connect both for the richest investigation context.
</Tip>

***

## SumoLogic

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to SumoLogic" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from SumoLogic

* **Log search** — Runs targeted searches across your log data
* **Analytics** — Aggregates and patterns from log analytics

***

## Render

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Render" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct uses from Render

* **Service logs** — Pulls application logs from your Render services
* **Deploy events** — Correlates errors with recent deployments

***

## Snowflake

Struct connects to Snowflake with **key-pair authentication**: a fresh RSA key pair is generated for each connection, you set the public key on a dedicated read-only service user, and Struct signs a short-lived JWT per request. There is no password or token to rotate or renew, and no network policy is required.

<Steps>
  <Step title="Go to Connections and click Connect next to Snowflake" />

  <Step title="Choose a service user name (default: STRUCT_READER)" />

  <Step title="Run the setup command">
    Copy the generated SQL into a Snowsight worksheet and run it as an admin (e.g. `ACCOUNTADMIN`). It creates the service user (if it doesn't exist), sets the generated public key on it, and grants a **read-only** role.
  </Step>

  <Step title="Enter your account identifier and click Connect">
    From your Snowsight URL `app.snowflake.com/<org>/<account>/…`, join the two path segments with a dash (e.g. `app.snowflake.com/mkzwlrt/qx41832` → `mkzwlrt-qx41832`).
  </Step>
</Steps>

The warehouse, default database, and event table are detected automatically from the account — no manual configuration needed.

### What Struct uses from Snowflake

* **Telemetry (event tables)** — Logs, traces, and metrics emitted by stored procedures, UDFs, Snowpark code, tasks, and dynamic tables
* **Query history** — Failed loads, pipeline errors, and slow queries from the last 7 days, with error codes and timing breakdowns
* **Read-only SQL** — Answers data questions (counts, lookups, aggregations) against tables you've granted access to

### Access is read-only

The setup command grants Struct **read access only**: the `SNOWFLAKE.EVENTS_VIEWER` application role for telemetry, `USAGE` on one warehouse to run queries, and `SELECT` across your databases. Struct can never write to your account.

The database grants are applied by a loop over your current standard databases (shared databases and Native Apps are skipped). `FUTURE` grants cover new tables, views, and schemas created inside those databases automatically — but if you create a **brand-new database** later, re-run the `EXECUTE IMMEDIATE` block from the setup command to include it (Snowflake has no account-wide grant).

<Tip>
  Prefer a narrower scope? Skip the `EXECUTE IMMEDIATE` block and grant only specific databases instead:

  ```sql theme={null}
  GRANT USAGE ON DATABASE MY_DB TO ROLE STRUCT_READER_ROLE;
  GRANT USAGE ON ALL SCHEMAS IN DATABASE MY_DB TO ROLE STRUCT_READER_ROLE;
  GRANT SELECT ON ALL TABLES IN DATABASE MY_DB TO ROLE STRUCT_READER_ROLE;
  GRANT SELECT ON ALL VIEWS IN DATABASE MY_DB TO ROLE STRUCT_READER_ROLE;
  ```
</Tip>

To revoke access at any time, run:

```sql theme={null}
ALTER USER STRUCT_READER UNSET RSA_PUBLIC_KEY;
```

### IP allowlisting (optional)

You can restrict where the Struct service user is allowed to connect from with a Snowflake network policy:

```sql theme={null}
CREATE NETWORK POLICY struct_policy ALLOWED_IP_LIST = ('<struct-egress-ip>');
ALTER USER STRUCT_READER SET NETWORK_POLICY = struct_policy;
```

Contact support for Struct's current egress IP addresses. Key-pair authentication works with or without a network policy — this is optional hardening, not a requirement.

***

## Cloud Log Providers

Struct queries your cloud logs in real time during investigations—pulling relevant log entries, filtering by time range, and correlating log patterns with errors and alerts.

| Provider                                        | Status    |
| ----------------------------------------------- | --------- |
| [AWS CloudWatch](#aws-cloudwatch)               | Available |
| [Azure Monitor / Log Analytics](#azure-monitor) | Available |
| [Google Cloud Logging](#google-cloud-logging)   | Available |

<Tip>
  To connect a cloud log provider, go to **Connections** and follow the setup instructions for your provider.
</Tip>

***

## AWS CloudWatch

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to AWS CloudWatch" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct queries

* **Log groups** — Application and service logs
* **Log streams** — Filtered by time range and keywords
* **CloudWatch Insights** — Structured queries across log groups

### Example

During an investigation into a Lambda timeout, Struct might query:

```
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 50
```

<Tip>
  Grant access to specific log groups rather than all logs if you want to limit scope.
</Tip>

***

## Azure Monitor

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Azure Monitor" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct queries

* **Log Analytics workspaces** — Application logs, custom logs, diagnostic logs
* **KQL queries** — Structured queries across Azure log data
* **Resource logs** — Logs from Azure services (App Service, Functions, AKS, etc.)

### Example

Investigating a spike in Azure App Service errors, Struct might run:

```kql theme={null}
AppServiceHTTPLogs
| where ScStatus >= 500
| where TimeGenerated > ago(1h)
| summarize count() by CsUriStem, bin(TimeGenerated, 5m)
| order by count_ desc
```

***

## Google Cloud Logging

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Google Cloud Logging" />

  <Step title="Follow the instructions to complete setup" />
</Steps>

### What Struct queries

* **Cloud Logging entries** — Application logs, request logs, system logs
* **Log-based queries** — Filtered by resource, severity, and time
* **GKE and Cloud Run logs** — Container and serverless application logs

### Example

Investigating a Cloud Run service crash, Struct might query:

```
resource.type="cloud_run_revision"
severity>=ERROR
timestamp>="2024-01-15T10:00:00Z"
```

<Tip>
  The more log sources Struct can access, the faster and more accurate root cause analysis becomes. Connect all relevant providers.
</Tip>

***

## How Struct Uses Cloud Logs

During every investigation, Struct:

1. **Identifies relevant log sources** based on the alert and affected services
2. **Builds targeted queries** to pull error logs, warnings, and contextual entries
3. **Correlates log patterns** with metrics, traces, and code changes
4. **Highlights key log lines** in the investigation report with timestamps and context

<Warning>
  Ensure your cloud provider credentials have sufficient permissions to read logs. Investigations will be less accurate without log access.
</Warning>

***

## Container & Orchestration

Struct can query your Kubernetes clusters directly to pull pod logs, events, and resource status during investigations.

| Platform                  | What Struct Pulls                     |
| ------------------------- | ------------------------------------- |
| [Kubernetes](#kubernetes) | Pod logs, events, namespace resources |

***

## Kubernetes

<Steps>
  <Step title="Go to Connections" />

  <Step title="Click Connect next to Kubernetes" />

  <Step title="Choose ServiceAccount Token (recommended) or kubeconfig YAML" />

  <Step title="Follow the setup instructions below" />
</Steps>

### What Struct uses from Kubernetes

* **Pod logs** — Pulls application logs directly from pods
* **Events** — Surfaces Kubernetes events (restarts, scheduling issues, OOM kills)
* **Namespace resources** — Lists pods and their status

### ServiceAccount Token Setup (Recommended)

This approach uses a secret-bound token that works with all Kubernetes clusters, including GKE, GKE Autopilot, EKS, and AKS:

```bash theme={null}
# Create the ServiceAccount
kubectl create serviceaccount log-reader -n default

# Create RBAC permissions
kubectl apply -f - <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: log-reader
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "namespaces", "events"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: log-reader-binding
subjects:
  - kind: ServiceAccount
    name: log-reader
    namespace: default
roleRef:
  kind: ClusterRole
  name: log-reader
  apiGroup: rbac.authorization.k8s.io
EOF

# Create a Secret-bound token (does not expire)
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
  name: log-reader-token
  namespace: default
  annotations:
    kubernetes.io/service-account.name: log-reader
type: kubernetes.io/service-account-token
EOF

# Retrieve the token
kubectl get secret log-reader-token -n default -o jsonpath='{.data.token}' | base64 -d
```

<Tip>
  Secret-bound tokens are long-lived and don't require rotation. This approach works on all clusters including GKE Autopilot, which enforces a 48-hour max on `kubectl create token`.
</Tip>

### Getting the API Server URL

Run this command to find your cluster's API server URL:

```bash theme={null}
kubectl cluster-info | grep "control plane"
```

### CA Certificate (Optional)

If your cluster uses a self-signed CA, you'll need to provide the CA certificate:

```bash theme={null}
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d
```

***

<Note>
  Need an integration we don't support yet? New integrations can be built in days — reach out at [help@struct.ai](mailto:help@struct.ai). Jira, ClickUp, and PagerDuty integrations are coming soon.
</Note>
