> 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/policies.md).

# Policies

## Policies

Policies are reusable rules that you bundle into profiles to control what is allowed on developer machines. Each policy targets one category:

* **IDE extensions**: targets one IDE and defines which extensions and versions developers can install.
* **Package config**: targets one package ecosystem and points developer machines at your tenant's Secure Registry.

The **Policies** page under **Developer Machines** > **Device Policy** lists every policy in the following columns:

| Column                 | Description                                                                                      |
| ---------------------- | ------------------------------------------------------------------------------------------------ |
| **Name**               | The policy name, with its description underneath if one is set                                   |
| **Type**               | **Secure registry**, **Allow-list**, or **Block-list**                                           |
| **Category**           | **IDE extensions** or **Package config**                                                         |
| **Rules**              | The number of rules in the policy. Package config policies show a dash, since they have no rules |
| **Profiles**           | How many profiles the policy is attached to                                                      |
| **Last updated (GMT)** | When the policy last changed                                                                     |

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

**Follow this interactive demo to see how it works:**

{% embed url="<https://app.storylane.io/share/uivtaxit0ole>" %}

### Create a Policy

* Click **New policy**, then complete the **Basics** section:

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

Give the policy a name (for example, "Approved VS Code extensions") and an optional description of what it controls and why. Then select the **Category**. Your choice determines both the remaining fields and the target selector next to it:

| Category                                                                      | Target selector                                                  |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| **IDE extensions**, described as "Editor / IDE plugins"                       | **IDE**: VS Code                                                 |
| **Package config**, described as "Route installs through the secure registry" | **Ecosystem**: npm, shown as `~/.npmrc · registry + auth token`. |

A **Compiled preview** panel is shown alongside the editor throughout. It renders the exact configuration that will be delivered to devices, and updates as you make changes. Use the copy button to copy it at any time.

When you are done, click **Create policy**. To enforce the policy on devices, add it to a profile. See [Profiles](/developer-machines/device-policy/profiles.md).

### IDE Extension Policies

An IDE extension policy defines which extensions and versions developers can install in a given IDE. VS Code is supported today.

#### Mode

Choose whether the listed extensions are the only ones allowed, or the ones blocked:

* **Allow-list**: block everything except the listed extensions
* **Block-list**: allow everything except the listed extensions

#### Rules

Rules define the extensions and publishers the policy applies to. The section heading shows the current rule count, and its description reflects the mode you chose: an allow-list lists what developers are allowed to install, a block-list lists what they are blocked from installing.

You can add rules in two ways.

**Add rules from inventory or manually**

Click **Add rules** to open the rule picker.

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

* **From inventory**: search the extensions Dev Machine Guard has already observed across your fleet, by name or publisher. Each entry shows the extension ID, the IDE, and the number of devices where it is installed, so you can build the policy from real usage.
* **Add manually**: add an extension that has not been observed in your fleet yet. Enter the publisher (for example, `ms-python`) and optionally the extension ID (for example, `python`). Leave the extension ID empty to write a publisher-wide rule. Manual rules use their own version strategy setting: allow any version, stable releases only, or pin specific versions.

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

Before adding the selection, choose a **default version strategy**. It applies to every selected extension, and you can change individual rules afterwards:

* **Allow any version**: any published version is permitted.
* **Stable releases only**: pre-release and preview builds are rejected.
* **Pin specific versions**: add the extensions first, then pin exact versions on each rule from the rules table.
* **Allow everything from the publisher**: creates one publisher-wide rule per distinct publisher in the selection.

You can also add an optional **comment**. It is recorded on every rule you add, for audits and reviews, and is never delivered to devices.

**Import an existing configuration**

Click **Import** to upload an existing configuration and turn its entries into rules. Supported formats are an `extensions.allowed` JSON file, a `.mobileconfig`, or a preferences plist, up to 5 MB.

#### Rules Table

Added rules appear in a table with these columns:

| Column        | Description                                                                                                                                     |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **Publisher** | The extension publisher, for example `hashicorp`                                                                                                |
| **Extension** | The specific extension, or `whole publisher` for a publisher-wide rule                                                                          |
| **Scope**     | The version constraint that applies. In a block-list policy, a publisher-wide rule shows `n/a · deny blocks all`, because the block is absolute |
| **Comment**   | The optional audit comment. Click **Add comment** to set one                                                                                    |

You can change the scope per rule, or remove a rule with the **X** at the end of its row.

<figure><img src="/files/9meQCAgrZKDSvP9vlUSV" alt=""><figcaption></figcaption></figure>

#### Private Marketplace

By default, assigned devices install extensions from the public Visual Studio Marketplace. If your organization hosts its own extension gallery, enter its URL in the optional **Private marketplace** section to point assigned devices at that gallery instead.

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

Leave the field blank to keep the public Marketplace. Rule enforcement is identical either way: the allow-list or block-list you defined above applies to whichever gallery the device uses, so switching galleries does not weaken or change your rules.

When a URL is set, it is added to the compiled configuration as `extensions.gallery.serviceUrl`, and delivered in the same artifact as the rest of the policy. Because the gallery URL determines where every extension on the device comes from, it is also verified: if your MDM deploys a different gallery URL than the policy defines, the profile reports drift and the diff shows both values. See Profiles.

#### Compiled Preview

For VS Code, the policy compiles to the `extensions.allowed` setting inside `settings.json`. The preview is labelled with the effect of your chosen mode, so you can confirm the logic at a glance: **Allow only these, block the rest** for an allow-list, or **Block these, allow the rest** for a block-list.

An allow-list policy denies everything with a `"*": false` wildcard, then permits each listed entry:

```json
{
  "extensions.allowed": {
    "*": false,
    "bradlc.vscode-tailwindcss": true,
    "github.vscode-github-actions": true,
    "ms-vscode-remote.remote-ssh": true,
    "ms-vscode-remote.remote-ssh-edit": true
  }
}
```

A block-list policy inverts the wildcard, permitting everything and denying only the listed entries:

```json
{
  "extensions.allowed": {
    "*": true,
    "hashicorp": false,
    "ms-python.python": false
  }
}
```

If a private marketplace URL is set, an `extensions.gallery.serviceUrl` key is included alongside `extensions.allowed`.

These settings are enforced on assigned devices through both your MDM and the Dev Machine Guard agent. A device reports compliant once the settings are applied.

### Package Config Policies

A package config policy configures the package manager on each assigned device to resolve packages through your tenant's Secure Registry instead of the public registry. npm is supported today, writing the registry URL and authentication token into `~/.npmrc`. PyPI, covering the pip and uv index, is listed in the ecosystem selector as coming soon.

This removes the per-machine setup work described in the Secure Registry setup guide: rather than each developer editing their own configuration, you define the policy once and deliver it to the fleet.

#### Enforcement

Package config policies have no mode or rules to configure. Routing npm installs through your tenant's Secure Registry is **always on** for this category, so the **Enforcement** section is informational and summarizes what will happen on each device:

* **Writes** a clearly marked managed block into the user's `~/.npmrc`, containing the registry URL and an authentication token.
* **Verifies** it on every check-in. If a developer edits the block, the agent restores it and reports drift.
* **Removes** the block cleanly when the policy is detached from the profile or the tenant offboards, leaving no residue.

{% hint style="info" %}
The last two behaviors describe the Dev Machine Guard agent. If you deliver this policy through your MDM instead, the equivalent work is done by the audit, remediation, and uninstall scripts that the profile generates for you. See Profiles.&#x20;
{% endhint %}

#### Compiled Preview

The compiled preview shows the managed block the agent writes to `~/.npmrc` on each device, in place, around any existing configuration:

```
# ... your existing .npmrc configuration ...
# BEGIN StepSecurity Secure Registry -- managed by dmg
registry=https://registry.stepsecurity.io/javascript
//registry.stepsecurity.io/javascript/:_authToken=step_xxxxxxxx::dev:<DEVICE-SERIAL-ID>
# END StepSecurity Secure Registry
```

The `BEGIN` and `END` markers delimit the managed region. Configuration outside the markers is left untouched, which is what allows the block to be updated or removed later without disturbing a developer's own settings.

The registry authentication token is shared across your tenant. The agent appends a per-device `:dev:` suffix to it, so registry access from each device is attributed separately even though the underlying token is the same.

#### Verifying the Result

Once the policy is delivered, the Package Configs page under **Developer Machines** > **Packages** audits which registry each machine actually resolves from. Use it to confirm the policy took effect across the fleet, and to find machines still resolving from the public registry.


---

# 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/policies.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.
