inedo-engineer

Private

Posts

  • RE: ProGet Basic: what counts as an "active build"?

    Hi @msicc ,

    Great question; so it's the same product/software (ProGet Enterprise), just with different packaging/quantity:

    • Essentials consists of a single license of ProGet Enterprise
    • Complete consists of two licenses of ProGet Enterprise plus Services

    It's not uncommon to have multiple licenses for non-production scenarios:
    https://docs.inedo.com/docs/proget/administration/license#licenses-for-non-production-testing-environments

    Licensing is per instance, which can be a single-server installation or a clustered (multi-server) installation.

    -- Dean

  • RE: ProGet Basic: what counts as an "active build"?

    Hi @msicc ,

    I would definitely budget for ProGet Enterprise, as you 100 devs is generally where a load-balanced setup really starts to make sense. It depends on so many factors, but a handful of simultaneous package restores can yield thousands of simultaneous requests by machines more powerful than a typical ProGet server (i.e. developer workstations), each which generally has to reach to connectors.

    That basically leads to a DDoS against your server. See How to Prevent Server Overload in ProGet to learn more.

    As for active builds,

    • a build is an entry under SCA > Projects > Builds; typically one build per CI run, but you might do more
    • only the first 1000 active builds are analyzed; so everything else will show as inconclusive
    • you can configure different stages to automatically archive other builds upon promotion; this is what we recommend

    To estimate, I would do a multiple of your active, nonlibrary projects. It's certainly feasible to have multiple active builds per project (e.g. one in build stage, one in testing, another in production), but a lot of that depends on your configuration.

    Hope that helps,
    Alana

  • RE: Audit logging and export to centralized logging (ProGet / BuildMaster)

    Hi @dbojak,

    Great questions, and we're happy to help.

    We're currently working on developing our best practices for application activity, and I'd like to share our current guidance, which is a work in progress. This is based on working closely with customers over many years, both proactively (developing policies) and reactively (actively helping investigate after an incident).

    (Work in Progress)

    Before looking to "ingest all the logs", identify a clear scenario that's contextualized to the product. For example, what does the Information Security team have in mind for monitoring, incident investigation, and compliance? What kind of incidents? What monitoring do they anticipate? And compliance with what?

    ProGet attempts to provide appropriate "visibility into user activity and administrative actions", so if there are gaps I would start there. What is missing? How does duplicating data help? Etc.

    For example, knowing which users download which Microsoft-owned packages on which day/time is not only impractical, but it serves no conceivable business benefit nor reduces any risk. But it could impact developer productivity and will increase costs across the board.

    In addition, Microsoft Sentinel doesn't provide any contextualized visibility and, chances are, you will just end up back in ProGet searching for data anyway. So all the time and bandwidth spent exporting/duplicating data just ends up being waste.

    That said, we don't have any built-in functionality to export this data, but it's relatively easy to export/ingest from the EventOccurrences table. These work differently in each product, but are similar in design.

    [1] We do not have a documented, exhaustive list of audited event types exists per product, but it's relatively easy to attain through SELECT * FROM EventTypes type of query. That's the "source of truth" for events

    [2] Direct database is the only option; we consider it quite stable, and it hasn't changed since like 1.0 of the products; there hasn't been any real demand to redesign or enhance it

    [3] Audit events are never automatically purged, nor can they be deleted from the UI/API; they can only be manually purged from the database

    As for the gaps you identified, those are things we can certainly consider addressing, provided it's within the confines of the existing design. It's relatively easy to add a new event type (if needed) or add additional audit data.

    Overall, it's meant to be an "audit trail" instead of "change log" -- so it's not always the most user-friendly, uses more system-level concepts, and prefers immutable IDs over names.

    Hope that helps!

    STeve

  • RE: Feature Request: Evaluate package based on policies before they are pulled with connector

    Hi @gisleso ,

    What you're describing has come up lately, though with a slightly different angle.

    I'm going to quote a variant of this, from a recent support ticket.

    We are trying to establish a policy where packages newer than 30 days are blocked on the package server level.

    Unfortunately, we are unable to use the feature they way it currently works, unless we are missing something.

    As soon as we block packages in any capacity, we are unable to do even the most rudimentary pip install or uv sync operations, as transitive dependencies cannot be downloaded (same for npm actually, but that is not an important package manager for us).

    I assume it has to do with how these package managers generally work:

    1. They construct a dependency graph from the available versions, taking various rules like locks and version ranges into account.
    2. After they built the graph, they will try and download the versions they have selected, which fails in most cases on ProGet, because the versions that are advertised by the index may not be available.

    We're a bit surprised by this behavior, because it seems like versions that cannot possibly be downloaded should not be present in the index.

    We think ProGet should not advertise versions in the index that it blocks.

    There are options with some package managers to take a cut-off date into account when calculating the dependency graph, but defining that in code on every single piece of code we have throughout the org defeats the purpose of having a central repository that should be able to do that.

    Are we missing something? Can we hide the versions that are noncompliant from the PyPI package index, or could that be enabled? This is a rather critical feature for us.

    And for more context, here's some of our response:

    This is a somewhat frustrating technical limitation; it comes down to the fact that we often can't know if a package is Noncompliant until we have the full metadata and even the package file.

    The API examples you shared illustrate this exact problem; consider what happens when you make that same request to PyPi.org (i.e. curl https://pypi.org/simple/certifi/). It's a long list of versions of that package, but there's no additional metadata.

    That means ProGet wouldn't be able to filter that list without querying the metadata of each version -- and that's just not technically feasible to do. Some clients can actually be configured to do that (like pnpm), but they can take a more context-sensitive approach. For example, they'll start by downloading B-1.2; then, if it's too new, it downloads B-1.1, and so on. Obviously a server can't know what the client wants with the data.

    Anyway, this is a known issue it's something we're researching. We call it "Metadata Suppression", but there are a few other major Developer Experience issues as well. The biggest one is that there's simply just no indication that these packages are being hidden by ProGet. So a Package Restore through ProGet will behave drastically different to the public repository, and eventually that will just lead to developers not trusting or using ProGet due to erratic behavior. That's a not a situation either of us (i.e. us as the software vendor, you as the platform ops team) want.

    Our general guidance is to simply not block downloads at all actually; we consider that an anti-pattern. It adds no protection whatsoever while substantially increasing risk by lowering the organizational security posture.

    Quite simply, developers will work-around what they consider "braindead policies" to get their job done. Upper management will not intervene nor punish them for delivering on time, etc. Ultimately the only consequence will be that no one will take your team (i.e. those enforcing policies) seriously. We've seen this happen time and time again; it's a version of "shadow IT".

    Instead, you should use pgutil builds scan and then consider these on a case-by-case basis if they are issues: https://guides.inedo.com/vulnerability-management/containment/

    To summarize, the "version dance" isn't realistic to do at the server level, for the reasons articulated above. Even if it were technically feasible, It would create a poor developer experience.

    THAT SAID -- we are considering an experimental approach. ProGet could "auto-yank" noncompliant packages. I'm envisioning something with three options for Noncomplaint packages:

    • Block File Download (not recommended)
    • Emit Deprecated in the API (experimental)
    • Allow Downloads (default)

    Will clients like pip and uv avoid deprecated, newer packages? We aren't users of these tools (or python at all), and we'd love if you could help us "test" this by manually deprecating some newer versions, and see how it handles dependency resoltuion.

    -- Dean

  • RE: Proget Installation as container with external Postgres

    Hi @hardik.turakhia,

    When you say external (org) PostgreSQL database, are you referring to a PostgreSQL database you are already hosting in your network and the one that is in the docker compose was for testing? Or are you just trying to host PostgreSQL in a separate container than ProGet, but both controlled by that single Docker compose file? If you are not using HA/Load Balancing, we recommend using the Embedded database. In a HA/Load Balancing environment, we recommend using InedoDB.

    If you are still planning to use an external PostgreSQL database (InedoDB or PostgreSQL directly), here are some things to get you started. First, only InedoDB or ProstgreSQL 17 is supported. With that said, your ProGet service in your compose file is not quite right. You have duplicate volumes and your environment variables are using unsupported keys. A good starting point for you should be to review our Docker Compose guide and our Docker guide. Based on that, here is a better ProGet service node that can get you started.

      pg:
        image: proget.inedo.com/productimages/inedo/proget:26.0.9
        container_name: proget
        restart: unless-stopped
        ports:
          - "8624:80"
        volumes:
          - ./proget-packages:/var/proget/packages
        networks:
          - proget
        environment:
          - PROGET_POSTGRES_CONNECTION_STRING: Server=postgres;Port=5432;Database=proget;Password=Pass@123;Username=root;
          - PROGET_ENCRYPTION_KEY: ${ENC_KEY}
    

    I removed the volumes for database and backups since you are planning to use an external database. I'm also using ./proget-packages/ for the volume mount. You had duplicates specified in your volume mounts, so update that path if you want to store it elsewhere. Then you need to specify the connection string for your PostgreSQL database in the PROGET_POSTGRES_CONNECTION_STRING environment variable. Lastly, I added the encryption key environment variable. You can generate this initially using head -c16 /dev/urandom | xxd -p -c32, then you will want to make sure you do not change it going forward. That should be enough to get you up and running.

    For other volumes you might want to use see our other volumes section in our Docker guide. For other supported environment variables, see our supported environment variables section in our Docker guide.

    Thanks,
    Rich

  • RE: Understanding Accepted Debian Repository Formats

    Hi @amy.j ,

    The URL doesn't appear to be a valid Debian repository.

    Navigating to the root gives an AccessDenied error. In a normal repository, there is usually a kind of file list/system. But that's not required.

    The root of a Debian repository has a dists folder, and then a folder for each contained distro, and a Release index file. I tried to navigate to $ROOT_URL/dists/trixie/Release but received the same error message. I also tried stable, but it didn't work. Maybe there's a dist that will work, but I don't know what it would be.

    Thanks,
    Steve

  • RE: [ProGet] Understanding Assessments

    Hi @caterina ,

    The "manually blocked" workflow you described is not recommended anymore; the sheer number of new vulnerabilities (including all the AI-generated, non-exploitable "vulnslop" entries) make that workflow imprudent. In addition, most vulnerabilities will be discovered long after you add the package to your product.

    If you haven't read it already, I'd check out Vulnerability Management Done Right with ProGet, which helps prioritize.

    That said, it's possible to configure a similar workflow; we describe it a "triaged approach" in Overriding Assessments & Default Behavior.

    It's also possible to assess a vulnerability even though no packages are impacted; in the above screenshot, you would just click "Monitor" and then override the assessment to something else.

    Hope that helps,
    Steve

  • RE: Invalid Content-Range header for HTTP range requests when downloading files from asset directories

    Hi @joris.guex

    You're right! It looks like ProGet is reporting the second value of the range as if it was an exclusive bound rather than inclusive. Somehow it has been like this for years.

    Anyway, it looks to be a trivial fix, so we should be able to get this in this Friday's release of 2026.9. I've created PG-3350 as the tracking issue for it.

    Thanks for reporting the problem!
    -Greg

  • RE: [ProGet] Incorrect package publish date affecting policies

    Hi @amy.j ,

    If the package is already cached in ProGet, then the publish date is already set. So, i would make sure to delete the package and try it again.

    Otherwise, can you share more specifics? That way we can create a reproduction case.

    Thanks,
    Alana

  • RE: Adding an encryption key to an existing ProGet instance that never had one

    Hi @carl.westman_8110,

    There's no problem adding an encryption key to an existing instance without one.

    The data will still be stored in plain text and can be read without a problem.

    The next time you edit (save) the connector data, the secrets (password) will be stored as encrypted. Obviously, if you removed or changed the encryption key, you wouldn't be able to read the data again.

    For this, there's really no preferred operation when it comes to SQL Server vs PostgreSQL.

    Thanks,
    Steve