Skip to main content
Package Firewall authenticates every request with one API key, so each event in the logs names that key rather than a person. User attribution adds a label to the credentials on each request, and Package Firewall records that label as the user on the event. Attribution is informational. Your API key ID and secret still control access. The label does not grant or restrict any permission, and rotating the key does not change how attribution works. You can view the attributed user on each event and query the logs by attributed user. See View Package Firewall logs to learn more.

How the label reaches Package Firewall

A client carries the label in the Basic-auth username, using the following format. The password stays your API secret.
Package Firewall decodes the username, restores your API key ID to authenticate the request, and records the label as the user on the event. The inner base64 layer keeps the label separate from the API key ID, so the label itself can contain any character. Package Firewall treats a username that fails to decode, or one whose decoded value does not begin with userattr:, as a plain API key ID. The request authenticates exactly as it would without attribution, and the log records no attributed user. Attribution happens at the credential layer, so any client that can vary the username per developer can attribute its traffic.

Where attribution is available

Sonatype Nexus Repository and Google Artifact Registry send the credentials you stored on the repository with every request, so requests through those integrations carry no per-developer label. Endor Patches requests are served from a different route than the firewall, so attribution does not apply to them.

Attribute requests from MDM deployments

The MDM scripts attribute traffic by default. They build a <console-user>@<machine> label at install time and encode it into the credentials they write for npm, pnpm, yarn, bun, pip, uv, Go, Maven, and NuGet on macOS and Linux. See MDM deployment to generate and deploy the scripts. To attribute traffic differently, for example by email address or by an asset tag from your device inventory, fork the MDM scripts repository and change the ENDOR_ATTR_LABEL assignment. It lives in package-firewall/bash/generate.sh for macOS and Linux, and in package-firewall/powershell/templates/envvars.ps1 for Windows. The two environment variables the scripts write hold the same value at two encoding stages, not two halves of the label. ENDOR_ATTR_LABEL holds the entire label, and ENDOR_ATTR_USER holds the Basic-auth username derived from it. Package Firewall never combines them, and the attributed user in the logs is always exactly the label.

Attribute requests from JFrog Artifactory

A remote repository stores one set of credentials and sends them on every request, so every developer looks the same to Package Firewall. A worker closes that gap. It runs inside Artifactory on each request, reads the Artifactory user who made the request, and rewrites the outgoing authorization header to carry that user as the label.

Before you begin

  • Workers service: Your JFrog subscription must include the Workers service. For availability, refer to Workers overview.
  • Individual developer accounts: Each developer must authenticate to Artifactory with their own account or token. The label comes from the Artifactory user on the request, so developers who share one service account all report the same label.
  • A configured remote repository: Set up the repository first. See Configure the Package Firewall with JFrog Artifactory to learn more.
  • An Endor Labs API key: Use the key ID and secret you created for the remote repository.

Reduce caching so requests reach Package Firewall

Artifactory serves a cached response without contacting Package Firewall, and a request that never arrives is never attributed. On each remote repository you route through Package Firewall, select Advanced and set Metadata Retrieval Cache Period (Sec) and Missed Retrieval Cache Period (Sec) to 0, which disables that caching.
Some Artifactory cloud deployments enforce a minimum metadata retrieval cache period on remote repositories. If your deployment rejects 0, use the lowest value it accepts. Requests that Artifactory answers from cache during that period are not attributed.

Create the worker

  1. In JFrog, create two worker secrets that hold your Endor Labs credentials. Name them ENDOR_API_KEY_ID and ENDOR_API_SECRET.
  2. Create a worker that uses the Before Remote Info event, which is the event that can add request headers before Artifactory contacts the remote source. For more information, refer to Configure Workers for custom flows.
  3. Attach the worker to each remote repository you route through Package Firewall.
  4. Enter the following code as the worker body.
  5. Install a package through the repository, then confirm the attributed user on the event. See View Package Firewall logs to learn more.
The worker sends the Artifactory username as the label, which it takes from the last segment of the user identifier on the request. When developers sign in to Artifactory through single sign-on, the username is usually their email address. To report on something else, such as a team name, map the username to that value inside the worker before you encode it.

Attribute requests from direct integrations

Direct integration writes the Package Firewall URL and credentials straight into each package manager configuration file, so you control the username on every client. Encode the label into the username using the format in How the label reaches Package Firewall, and write that value where the configuration file expects the user name. The MDM scripts do exactly this, so use them as the reference implementation if you build your own deployment tooling. See Configure the Package Firewall with direct integration to learn more.

Choose a label

The following labels are examples of conventions you can adopt, not a list the platform defines. Package Firewall stores the label as one string and never parses it, so the convention you pick is the one your reporting has to live with. Use a single convention across the fleet. A mix of formats means every query against spec.user has to account for each one. Keep the half of the label that stays stable for whatever you report on. If you report by person, hold the person half steady even when hardware changes. If you report by device, hold the device half steady even when the user changes. On a shared virtual machine the device half stops identifying anyone, so the person half has to carry the attribution alone.

Label constraints

Package Firewall treats the label as opaque. It stores and displays the value and never parses it, so no character in the label carries meaning to the platform. The @ in the default label is a convention of the MDM scripts, not a separator the platform interprets.
  • Character set: The label must be valid UTF-8. Package Firewall drops a label that is not valid UTF-8. The request still authenticates and the log still records the event, but with no attributed user.
  • Delimiters: Every character is safe, including :, @, /, and spaces, and no delimiter is unsupported. The label is base64-encoded before it reaches the wire, so no character can break the format. A label such as team:platform/doe@laptop-14 reaches the logs exactly as written.
  • Length: Package Firewall imposes no maximum label length, and the Endor Labs service accepts labels of at least 16 KB. The practical ceiling comes from the transport on your side. HTTP proxies commonly cap a single header line at 8 KB. Also, pip, uv, and Go carry the encoded label inside the index URL of every request, so a long label inflates all their traffic. Encoding roughly doubles the label on the wire. The Basic-auth username is about 1.8 times the label length, and the _auth value npm derives from it is about 2.4 times. A label under 1 KB stays far below an 8 KB header line in every lane.