Before you begin
Create an API key dedicated to the Package Firewall so that the deployment scripts can authenticate to it. You can create it through one of the following methods:- Using the Endor Labs user interface, with the Package Firewall User role. See API keys to learn more.
- Using endorctl, with the
SYSTEM_ROLE_PACKAGE_FIREWALLrole. Make sure to install and configure endorctl before you create the key.
<namespace>with your namespace.<API key name>with the name of the API key for the Package Firewall use case.<YYYY-MM-DDTHH:MM:SSZ>with the API key expiration in ISO 8601 UTC format, for example2026-12-31T23:59:59Z.
Generate the MDM scripts
Clone the generator repository and run it with your namespace and Package Firewall credentials. Select your platform for the matching commands.The generated scripts default to
https://factory.endorlabs.com. If you use Endor Labs with an EU tenant, set ENDOR_FQDN=https://factory.eu.endorlabs.com when you run the generator. The browser generator has a region picker for the same setting.- macOS / Linux
- Windows
-
Clone the generator repository: Clone the repository and change into the bash generator directory.
-
Generate the scripts: Pass your credentials as environment variables. This keeps them out of your shell history.
Alternatively, store the variables in a
.envfile, add.envto.gitignore, and source it.
endor-js.sh, endor-python.sh, endor-go.sh, endor-maven.sh, endor-nuget.sh, endor-ruby.sh, endor-vscode.sh, endor-all.sh, and endor-remove.sh to out/<namespace>/. It also writes endor-vscode-disable-patch.sh and endor-vscode-disable-policy.sh, which each turn off one VS Code method. Re-running generate.sh overwrites the same directory.endor-vscode.sh and endor-all.sh leave VS Code unchanged unless you add ENDOR_VSCODE_ENABLE_PATCH=true, ENDOR_VSCODE_ENABLE_POLICY=true, or both to the generator command. Compare the two methods before you set them. With ENDOR_VSCODE_ENABLE_POLICY=true, the generator also writes endor-vscode.mobileconfig and endor-vscode-policy.plist, the VS Code policy for macOS. See Deliver the gallery policy on macOS.Upload the scripts to your MDM tool
Each generated script is self-contained, so you upload it directly to your MDM tool. On macOS and Linux the scripts use the.sh extension. On Windows, they use .ps1.
- macOS / Linux
- Windows
Run the scripts as
root. The script detects the logged-in console user and writes configuration files to the correct home directory.When no user is logged in, such as at the login window or during Setup Assistant, the package manager scripts and endor-all.sh exit with code 1 and change nothing. Run them at login or at a recurring check-in. endor-vscode.sh and the VS Code disable scripts do not need a logged-in user.Kandji
Kandji
- Add the script: Go to Library > Custom Scripts > Add Script.
- Provide the script: Paste the script content or upload the file.
- Set the run context: Set Run as to Root.
- Set the frequency: Set Execution Frequency to Run once per device, or to every check-in for ongoing enforcement.
- Assign the script: Assign the script to the relevant device blueprint.
Jamf Pro
Jamf Pro
- Add the script: Go to Settings > Scripts > New and paste the script content.
- Create a policy: Go to Policies > New Policy > Scripts and add your script.
- Set the frequency: Set the Execution Frequency as appropriate.
- Scope the policy: Scope the policy to the target devices.
Generic MDM
Generic MDM
Upload the script file and run it as root. The script detects the logged-in console user and writes configuration files to the correct home directory.
How credentials are stored
The scripts write your credentials to a single source on each device and reference them from the package manager client configuration files. The storage mechanism depends on your platform.- macOS / Linux
- Windows
The scripts write all credentials to Each shell profile (
~/.config/endor/env.sh and set the file permissions to 600..zshrc, .bash_profile, and .bashrc) gets a one-line block that sources this file. The configuration files reference these variables instead of embedding credentials, except pip.conf, uv.toml, and the go env file, which cannot expand variables and get a literal index URL baked in at install time.To rotate credentials, redeploy the MDM script to update env.sh on the target machines. You do not need to change any configuration files.User attribution
The generated scripts label each machine’s Package Firewall traffic with the developer who owns it. The firewall logs then attribute activity to a person and machine rather than to a shared API key. By default the label is<console-user>@<machine>, built at install time from the logged-in console user and the machine name.
The scripts encode the label into the Basic-auth username they write for every package manager client they configure. They store the encoded username as ENDOR_ATTR_USER in the credential store, which is env.sh on macOS and Linux and HKCU:\Environment on Windows.
See User attribution to choose a different label, learn how the encoding works, or attribute traffic from the other deployment models.
What the scripts do
Each install script writes the credential store and an Endor-managed block to the package manager client configuration files. The file locations depend on your platform.- macOS / Linux
- Windows
The
endor-js.sh script writes ~/.config/endor/env.sh and an Endor-managed block to the following files.The endor-go.sh script writes ~/.config/endor/env.sh and an Endor-managed block to the following file.The endor-python.sh script writes ~/.config/endor/env.sh and an Endor-managed block to the following files.The endor-maven.sh script writes ~/.config/endor/env.sh and an Endor-managed block to the following file.The endor-nuget.sh script writes ~/.config/endor/env.sh and Endor-managed blocks to the following file.Configure each package manager client
The scripts apply a few package manager client-specific behaviors that are the same on every platform unless noted otherwise.JavaScript
JavaScript
The scripts write
_auth (base64) instead of _authToken, which bun requires. Yarn classic reads authentication from .npmrc, so the .npmrc write covers it. The scripts do not write the project-level bunfig.toml.Go
Go
- The scripts find the go env file with
go env GOENVand writeGOPROXYto it. - If
gois not installed, they use the default path:~/Library/Application Support/go/envon macOS,~/.config/go/envon Linux, or%APPDATA%\go\envon Windows. - Credentials are written as is, because go env files cannot expand environment variables.
GOPROXYends in,direct, so Go downloads a module from its source if the firewall does not serve it.- The go env file applies to every
gocommand in any shell. AGOPROXYenvironment variable takes precedence, so project-level overrides still work.
Python (pip)
Python (pip)
The scripts write the pip settings in a
[global] section. If the file already has a [global] section, they merge the Endor keys into it, because pip rejects duplicate [global] sections. The scripts disable any conflicting keys, such as an existing index-url, with an #endor-bak# prefix and restore them when the remove script runs.Python (uv)
Python (uv)
uv ignores
pip.conf, so the scripts write the user-level uv.toml with the firewall index URL. The scripts bake the URL in literally because uv cannot expand environment variables in its config, so it carries the attributed username.Python (Poetry)
Python (Poetry)
Poetry reads credentials from the
POETRY_HTTP_BASIC_ENDOR_FIREWALL_* environment variables, so you do not need a separate write step. Add the source to your pyproject.toml:Poetry reads the registry URL from pyproject.toml and the credentials from environment variables. Add the Package Firewall as a source in each project. The source includes the URL only, never the credentials.Maven
Maven
- The scripts write a user-level
settings.xml(~/.m2/settings.xml, or%USERPROFILE%\.m2\settings.xmlon Windows) with a<mirror>of*that points at the firewall, plus a matching<server>. - Credentials are not stored in the file. The
<server>references${env.ENDOR_ATTR_USER}and${env.ENDOR_API_SECRET}, which Maven reads at runtime from the environment variables the credential store sets. - Gradle uses the same settings when it reads
~/.m2/settings.xml.
.NET (NuGet)
.NET (NuGet)
- The macOS and Linux scripts merge the Endor source into
<packageSources>in~/.nuget/NuGet/NuGet.Config. - The block starts with
<clear />, so the firewall replacesnuget.organd every source listed before it. - If the file lists a private feed, such as Artifactory or Azure Artifacts, the script warns and exits with code 1. Re-add that feed in a repository-level
nuget.config, or use the JFrog Artifactory integration instead. - Credentials are not stored in the file.
<packageSourceCredentials>references%ENDOR_ATTR_USER%and%ENDOR_API_SECRET%, which NuGet reads at runtime from the environment variables thatenv.shsets. - IDEs launched outside a shell, such as from the macOS Dock, do not inherit
env.sh. Their restores fail with a401error instead of bypassing the firewall.
A repository-level
nuget.config overrides the user-level file for that repository. A repository that commits <clear /> followed by nuget.org bypasses the firewall. For full enforcement, commit endor-firewall as the only public source in each repository. The key must be exactly endor-firewall so that the user-level credentials apply. A repository nuget.config that only adds a source keeps that source active next to the firewall.Preserve existing configuration
The scripts use a sentinel block pattern. Each script writes only a clearly delimited section to a configuration file and leaves everything else untouched, so existing settings survive every deployment. The following example shows an.npmrc file that already contains administrator settings. The script adds only the Endor-managed block between the BEGIN and END markers.
Remove the configuration
To offboard a machine, deploy the remove script. It strips the Endor block from every managed file and removes the credentials the install scripts added. To turn off only one VS Code method and keep the package manager configuration, deploy a VS Code disable script instead. See Switch or turn off a VS Code method.- macOS / Linux
- Windows
Deploy
endor-remove.sh. It removes the Endor block from each configuration file, removes the credentials from ~/.config/endor/env.sh, and removes both VS Code methods. See Remove the VS Code configuration for details. For the macOS VS Code daemon, it also restores Microsoft’s original app when available and removes the signing identity. See Remove the daemon for the fallback when no original is available.When no user is logged in, endor-remove.sh removes the machine-wide configuration, such as the VS Code methods, and leaves the user’s files. It then exits with code 1. Deploy it again after a user logs in.Security notes
The scripts store credentials on each device. Review the following before you deploy.Generate your MDM script in the browser
Select your platform, ecosystem, MDM tool, and region, then enter your namespace and API key. The remove and VS Code disable scripts need only the namespace. Select US or EU based on where your Endor Labs tenant is hosted. The region sets the Package Firewall URL. The generator builds the script entirely in your browser. It never sends your credentials to Endor Labs or GitHub, and only bakes them into the script you download. For scripts that include VS Code, select Patch VS Code’sproduct.json, Set VS Code’s gallery policy, or both. Neither is selected by default, and without one the script leaves VS Code unchanged. Compare the two methods before you deploy.