# Drata

Drata is an evidence destination, not an MDM: once an MDM inventory source (Jamf Pro or Iru) is connected, the platform pushes one record per managed device into a Drata **Custom Connection** on a schedule, so "AI usage on endpoints is monitored" becomes a continuously-tested control instead of quarterly screenshots. Shared concepts (the coverage model and what the evidence attests) are on the [MDM installations](/docs/ai-control-plane/reference/device-agent/mdm-installations) page.

## 1. Create a scope-limited API key

In Drata, go to **Settings → API Keys** and create a key for this integration. Grant it only these Custom Connections scopes. It needs nothing else:

- **List Custom Connections** and **Create Custom Connection**: Speakeasy finds or creates the dedicated connection for you on connect.
- **Create Custom Connection Data** and **Create and Update Custom Connection Data**: the record uploads themselves.
- **Delete Custom Connection Data**: pruning departed devices and clearing an empty fleet.

The key is shown once; store it in your password manager.

## 2. Connect in the dashboard

1. Open **Device Agent → MDM Integrations**, then **Connect** on the Drata row.
2. Select your Drata **region** (`us`, `eu`, or `apac`), enter your **Workspace ID** (usually `1`, find it under **Settings → Workspaces**), and paste your **API key**. Leave **Custom Connection ID** blank. Credentials are stored encrypted and are never shown again after saving.
3. **Save.** Speakeasy creates a dedicated Custom Connection named "Speakeasy Device Agent Coverage" with the correct record schema and discovers its resource: no manual API setup, and no way to get the schema wrong. Re-saving reuses the same connection rather than creating a duplicate.
4. **Test connection**, then enable it. New connections start paused: the flow is save, test, then enable.

Once enabled, evidence pushes hourly (skipping cycles where nothing changed). Each push is a complete snapshot: departed devices drop out of the record set automatically, and retries can never duplicate records.

> **Bringing your own connection?** If you'd rather create the connection yourself (or already have one), paste its **connection id** into the field in step 2 and Speakeasy uses it instead of provisioning one. Create it with exactly this record schema (the record resource is created automatically with the connection; the integration discovers it):
>
> ```bash
> curl -s -X POST https://public-api.drata.com/public/v2/custom-connections \
> -H "Authorization: Bearer " -H "Content-Type: application/json" \
> -d '{
> "name": "Speakeasy Device Agent Coverage",
> "providerTypes": ["CUSTOM"],
> "workspaceIds": [],
> "displayNameKey": "hostname",
> "schema": {
> "type": "object",
> "required": ["id", "serialNumber", "hostname", "assignedUserEmail", "agentActive", "agentAttestation"],
> "properties": {
> "id": { "type": "string" },
> "serialNumber": { "type": "string" },
> "hostname": { "type": "string" },
> "assignedUserEmail": { "type": "string" },
> "agentActive": { "type": "boolean" },
> "agentAttestation": { "type": "string" },
> "agentLastSeenAt": { "type": "string" }
> }
> }
> }'
> ```
>
> The `required` list must stay exactly as shown. In particular, it must **not** include `agentLastSeenAt`. If `required` is omitted, Drata marks every property required, and records for devices whose agent has never reported (which omit `agentLastSeenAt` rather than fabricating a timestamp) fail schema validation on upload. The automatic provisioning gets this right for you.

## 3. Wire it to a control

In Drata, map the connection to a test on the relevant control (for example, your SOC 2 monitoring control). Phrase the test over `agentActive`: one device with no live agent fails the test and routes to an owner.

> Each record states its own attestation strength in `agentAttestation`, and both values can appear in one push:
>
> - `"device"`: that machine's own agent reported in, matched on hardware serial. `agentActive` means **this device** is running the agent.
> - `"user"`: matched on the MDM-assigned user's email. `agentActive` means only that **the assigned user** runs the agent on some machine, which is strictly weaker.
>
> A machine whose agent cannot read a hardware serial stays `"user"` even once your organization is on device-level matching, so the strength genuinely varies row by row. `agentLastSeenAt` is omitted entirely when no agent has ever reported, rather than sent as null or a zero timestamp.
>
> If your auditor requires per-device attestation, phrase the test to require both `agentActive` = true **and** `agentAttestation` = `"device"`. Testing `agentActive` alone accepts the weaker claim.
