> For the complete documentation index, see [llms.txt](https://docs.stepsecurity.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stepsecurity.io/developer-machines/device-policy/profiles.md).

# Profiles

Profiles are bundles of policies that you assign to devices or export to your MDM. Create a policy first, then compose it into a profile. See [Policies](/developer-machines/device-policy/policies.md).

The **Profiles** page under **Developer Machines** > **Device Policy** lists all profiles with the policies they contain, their agent assignment, and their compliance status.

<figure><img src="/files/IeLH62dzheDZPt1kvcwW" alt=""><figcaption></figcaption></figure>

Click **New profile** to create one and select a policy

<figure><img src="/files/7gD8UmvwsSxOuFvA3qbM" alt=""><figcaption></figcaption></figure>

Each profile has two tabs: **Delivery**, where you deploy the profile to devices, and **Compliance**, where you track which devices have applied it.

<figure><img src="/files/swPNfFGr6i19mJh4UJ8q" alt=""><figcaption></figcaption></figure>

### Delivery

Deploying a profile is a two-step process:

1. **Deploy**: pick who enforces this profile, then assign it to the devices it covers.
2. **Verify**: devices pick this up the next time they connect, usually within hours. See which ones applied it in the Compliance tab.

#### Policies

The **Policies** section lists the policies in the profile. Each row shows the policy name, its type badge, and a summary line: category, target, and either the rule count or `secure registry`. Click a row to open the policy.

#### Enforcement

Every profile declares one enforcement type. This is the most important choice on the page, because it determines who writes the configuration and what the Dev Machine Guard agent does.

| Option                    | What happens                                                                                                                                                                                                                  | Badge            |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| **Verify MDM deployment** | Your MDM (Intune, Jamf, Iru) deploys the settings. The agent never writes. It reads each device, verifies it against this profile, and flags drift with an exact field-by-field diff. Devices still need the agent installed. | **Verify only**  |
| **DMG agent enforces**    | The Dev Machine Guard agent on each device writes the VS Code settings and the managed `.npmrc` block, then re-applies them whenever a user edits them.                                                                       | **Self healing** |

Choose **Verify MDM deployment** when your fleet is already managed in an MDM and you want the operating system to enforce the configuration, which makes it tamper-proof for the developer. Choose **DMG agent enforces** when you want enforcement without an MDM, or when you want configuration restored automatically rather than reported.

{% hint style="info" %}
Changing the enforcement type on an existing profile asks you to confirm, then moves every assigned device onto the new channel. Devices show **Pending** until each agent reports under the new channel. This is expected and clears itself, it is not an error.
{% endhint %}

#### Assignment

Assignment is required for both enforcement types. Under **Verify MDM deployment** it tells the agent which devices to verify your MDM rollout on; under **DMG agent enforces** it tells the agent which devices to enforce on.

<figure><img src="/files/yeeDS3D5KW4fHfHRRGmJ" alt=""><figcaption></figcaption></figure>

* **All devices**: every current and future registered device.
* **Specific devices**: pick devices from the fleet. Search by hostname, user, or device ID. Each row shows the platform, the signed-in user, and the installed agent version, which is useful for spotting devices whose agent is too old to verify the profile.

Click **Save assignment** to apply your selection. Agents pick the profile up on their next cycle, and at most one profile applies to any device.

#### MDM Artifacts

When your MDM enforces the profile, the **MDM artifacts** section generates the files to deploy. Pick a category in the left rail and a platform tab (**macOS**, **Windows**, **Linux**), then follow the numbered steps. Use **Download all (.zip)** to get every artifact for the profile at once.

The agent reads what your MDM deployed, verifies it against this profile, and reports any drift with an exact diff. That verification is why the artifacts are generated here rather than assembled by hand: the file StepSecurity gives you is the same definition it later checks the device against.

<figure><img src="/files/bTCgnKAIgA0iyIHFvze0" alt=""><figcaption></figcaption></figure>

**IDE Extensions Artifacts**

IDE extension policies deliver as configuration, so there is a single step: import the artifact and assign it to the same device group this profile targets. Configuration profiles stay applied without a schedule.

**macOS**

* **Configuration profile** (`.mobileconfig`): import into Intune, Jamf, or Iru as a custom configuration profile, then assign it to the target device group.
* **Preference file** (`com.microsoft.VSCode.plist`): import into Jamf via Application & Custom Settings, or into Intune as a preference file, using the preference domain `com.microsoft.VSCode`.

**Windows**

* **Remediation script** (`.ps1`): deploy through Intune as a platform script to enforce the policy across your managed Windows devices.

**Linux**

* **Policy file** (`policy.json`): save to `/etc/vscode/policy.json` and roll it out through your preferred MDM or configuration-management channel.

**Package Config Scripts**

Package config policies deliver as a set of scripts, because a `.npmrc` file is user-writable and can drift back at any time. Each platform tab provides three scripts, named for the platform, for example `npm-package-config-audit-macos.sh`.

<figure><img src="/files/GyM17m1LwBogmA7grpP3" alt=""><figcaption></figcaption></figure>

**1. Deploy the audit and remediation pair**

These two ship together. Audit checks whether the managed `.npmrc` block is present and correct; remediation writes or repairs it. Audit alone reports, it does not fix.

* **Audit script**: deploy it in the detection slot of a script pair, either the Intune Remediations detection script, or the Audit Script field of the same Iru Custom Script library item that carries the remediation. It exits non-zero when `~/.npmrc` does not currently point at Secure Registry, its token is stale, or its permissions are loose, which signals that the remediation script should run. It never modifies the file.
* **Remediation script**: deploy it in the remediation slot of the same pair, either Intune Remediations, which packages detection and remediation together, or a single Iru Custom Script library item carrying the audit script in its Audit Script field and this one in its Remediation Script field. It rewrites `~/.npmrc` to use Secure Registry and writes a per-device auth token.

Both scripts can run as root, in which case they drop to the signed-in user, or directly in the user context.

{% hint style="info" %}
The audit and remediation scripts embed your tenant registry key. Upload them straight to your MDM. Do not paste them into a ticket or commit them to a repository
{% endhint %}

**2. Let your MDM run them on a schedule**

These scripts are not one-shot installers. A device drifts back the moment someone edits their own `.npmrc`, so the pair has to keep running.

Set the interval where you already set intervals: in your MDM. Ship both as scripts in Jamf or Iru and let the MDM's own check-in cadence run them; Jamf checks in roughly every 15 minutes by default. Nothing in StepSecurity schedules these scripts, so the interval is whatever your MDM is set to.

**3. Optional: clean up if you ever unassign**

Only needed if you remove the npm policy from this profile. Unassigning does not clean the device: the managed `.npmrc` block and its registry tokens stay on disk, so push the uninstall script before you unassign.

* **Uninstall script**: removes the Secure Registry managed block from `~/.npmrc` and restores any registry line the block had commented out. It embeds no key or URL, so it remains runnable after the registry key is disabled or the policy is detached, which makes it safe to keep on hand for offboarding.

Stop the audit and remediation pair from running before you push the uninstall script. If the pair is still on its schedule, remediation will simply rewrite the block that uninstall just removed.

### Compliance

The **Compliance** tab shows every device the profile applies to and its current state, so you can verify the rollout. A progress bar per policy category summarizes how many assigned devices are verified, for example `1/1 verified`.

<figure><img src="/files/IXnTdRMtG1EYrriCQdD7" alt=""><figcaption></figcaption></figure>

The device table has these columns:

| Column                             | Description                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Device**                         | Hostname and signed-in user, or the device ID                                                     |
| **Platform**                       | macOS, Windows, or Linux                                                                          |
| **Channel**                        | Which enforcement type the device is reporting under                                              |
| **One column per policy category** | The state for that category on that device, for example **IDE extensions** and **Package config** |
| **Last seen (GMT)**                | When the device last reported in                                                                  |
| **Agent Version**                  | The installed agent version                                                                       |

Devices that have not connected recently are counted as offline.

#### Verification States

Each category cell carries one of the following states.

| State                     | Meaning                                                                                                                  |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **MDM verified**          | The agent read the device back and what your MDM deployed matches this profile's policy exactly.                         |
| **MDM drift**             | What your MDM deployed does not match this profile's policy. Open the diff to see every field that differs.              |
| **Pending**               | Waiting for the agent's first report under MDM verification.                                                             |
| **Not deployed**          | Your MDM has not pushed this configuration to the device yet, so there is nothing to verify.                             |
| **Verification failed**   | The agent reported a managed policy on this device, but the evidence it sent could not be read, so nothing was verified. |
| **Not assigned**          | No profile is assigned to this device for this category.                                                                 |
| **Agent update required** | The agent is too old to verify this policy on the device. Update it.                                                     |
| **Agent offline**         | The agent is not reporting in, so this status may be out of date.                                                        |

#### Reading a Drift Diff

When a category reports **MDM drift**, click **View diff** to open a field-by-field comparison of what the profile defines against what the device actually has. Two labels run throughout:

* **Desired**: the policy in StepSecurity, treated as the source of truth.
* **Observed**: what your MDM deployed.

<div><figure><img src="/files/vTkxRQgiJBQeoGUL9OpH" alt=""><figcaption></figcaption></figure> <figure><img src="/files/SzV7zt2q4SInuUl9vWYP" alt=""><figcaption></figcaption></figure></div>

The diff is grouped by setting. For `extensions.allowed`, entries are sorted into three buckets, each with a count:

* **Missing**: required by the policy, not deployed.
* **Extra**: deployed, but not in the policy. This is the bucket to read first, because it is where an unapproved extension appears.
* **Changed**: present in both, but the values differ. Each row shows the desired value, then the observed value.

Single-value settings such as `extensions.gallery.serviceUrl` are shown as a **Desired** and **Observed** pair. A mismatch here means devices are pointed at a different extension gallery than the policy specifies, which changes where every extension on the device comes from.

The diff footer records when the device was last verified and confirms that it is re-checked on every agent cycle. Resolve drift in one of two ways: fix the deployment in your MDM so it matches the policy, or click **Edit policy** to change the policy so it matches what you intended to deploy. The agent never writes in this channel, so drift will persist until you act on it.

### Manage Profiles with Terraform

You can manage profiles and their policies as code using the [StepSecurity Terraform provider](https://registry.terraform.io/providers/step-security/stepsecurity/latest). Click **Use with Terraform** on a profile to open a guided, one-time import flow with commands prefilled for that profile. You can also download the instructions as Markdown. The **Terraform** button on the Policies list page offers the same flow for policies.

1. **Set up the provider**: save the generated `provider.tf`, which configures the `step-security/stepsecurity` provider and authenticates via the `STEP_SECURITY_API_KEY` and `STEP_SECURITY_CUSTOMER` environment variables, then run `terraform init`.
2. **Add import blocks**: the panel generates one import block for the profile and one for each attached policy, prefilled with your IDs.
3. **Generate the config, review, apply**: run `terraform plan -generate-config-out=generated.tf`, review `generated.tf` before committing, then apply. From that point on, changes to the profile and its policies can be managed through Terraform.

<figure><img src="/files/BJ8gIpvzSG1SYlxKxIIi" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.stepsecurity.io/developer-machines/device-policy/profiles.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
