Block malicious components with OSA Proxy¶
Context¶
If an unsafe package reaches the internal repository manager first and the check only happens afterwards, the team has to investigate the issue later and clean the cache separately. A safer approach is to stop such components before they enter the perimeter and become available to developers and build pipelines.
OSA Proxy is the CodeScoring proxy service that intercepts package-manager requests to remote repositories, checks the requested components, and blocks them when needed. In this scenario it is deployed in front of JFrog Artifactory so that the internal PyPI repository receives only the packages that pass the configured security policies.
What you get¶
After completing the scenario:
- OSA Proxy will be deployed and configured for PyPI in
strictmode; - JFrog Artifactory will fetch packages through OSA Proxy instead of reaching the external source directly;
- a blocking policy at the
proxystage will stop malicious components by the Dependency is dangerous condition; - the result can be checked in
OSA -> Requests.
Requirements¶
Before you start, make sure you have:
- a host or test environment where OSA Proxy can be deployed;
- access to Docker or Kubernetes together with the OSA Proxy image for the selected installation path;
- access to the OSA Proxy
application.ymlfile and the ability to restart the service after configuration changes; - JFrog Artifactory with a remote PyPI repository that can be reconfigured;
- a CodeScoring license with the OSA module enabled;
- access to CodeScoring with permissions to create policies and review OSA data;
- a pilot package flow that can be used to validate the setup before rolling it out to all teams.
Steps¶
Step 1. Deploy OSA Proxy¶
If the service is not installed yet, start by deploying it in a separate environment. For an initial validation, the Docker option is the simplest one.
Example OSA Proxy run in Docker
If Kubernetes is used in your environment, the service can also be deployed with a Helm Chart. Both installation options are described in the OSA Proxy deployment guide.
After deployment, the service should be reachable by URL and ready to load its configuration.
Step 2. Configure OSA Proxy for PyPI and enable strict mode¶
Now configure the service so that unscanned and forbidden components do not pass any further into the internal repository manager.
Example OSA Proxy configuration for PyPI
codescoring:
host: https://codescoring.example.com
token: <token>
work-mode: strict
enable-status-line: true
block-status-code: 403
pypi:
enabled: true
repository:
- name: internet-pypi
scan-manifest: true
scan-package: true
url-encoded-config: true
registry: https://pypi.org
packages-registry: https://files.pythonhosted.org
What matters in this configuration:
work-mode: strictblocks unscanned components;scan-manifest: trueallows OSA Proxy to remove forbidden versions from the Simple API response;scan-package: trueenables package archive scanning;enable-status-line: truemakes diagnosis easier when the client sees a blocked response;url-encoded-config: trueis needed when OSA Proxy receives internal repository context through the URL.
After updating application.yml, restart OSA Proxy.
Roll out strict mode gradually
New requests are filtered immediately, but packages that already reached the JFrog Artifactory cache earlier do not disappear on their own. It is safer to validate the setup on a separate remote repository first and only then move the main traffic to strict.
Step 3. Put OSA Proxy in front of JFrog Artifactory¶
Now the remote PyPI repository in JFrog Artifactory has to stop reaching the external source directly and fetch packages only through OSA Proxy.
- Open Administration -> Repositories -> Remote in JFrog Artifactory.
- Find the remote PyPI repository used by your teams for external Python packages.
- Replace the direct PyPI URL in the URL field with the OSA Proxy address.
-
If the remote repository in JFrog Artifactory points directly to the public PyPI source, pass the internal repository context to OSA Proxy through Base64 parameters and use a URL like this:
https://osaproxy.example.com/internet-pypi/eyJyZXBvTWFuYWdlckhvc3QiOiJodHRwczovL3B5cGkub3JnL3NpbXBsZSIsInJlcG9OYW1lIjoiaW50ZXJuZXQtcHlwaSJ9In this example the Base64 string contains the following JSON:
OSA Proxy uses these parameters to understand which internal repository the request belongs to and which security policies should be applied to it.
-
In the additional JFrog Artifactory settings, enable Bypass HEAD requests.
- Save the changes.
After that new requests for external PyPI packages will go through OSA Proxy.
Step 4. Create a blocking policy for malicious components¶
Now create a rule that works at the proxy stage and blocks a component when it matches the Dependency is dangerous condition.
- Go to
Settings -> Policies. - Click Create.
- Fill in the main fields:
- Name — for example,
Dangerous dependency at the proxy stage; - Stages —
proxy; - OSA Components —
Packages; - Is Active — enabled;
- Blocker — enabled.
- Name — for example,
- If the rule should apply only to a single delivery channel, choose the corresponding repository. If it should protect all proxy repositories, leave the repository field empty.
- Add the condition:
- Dependency is dangerous.
- Click Create.
Validate blocking rules on a pilot repository first
At the proxy stage, a blocker affects the actual package retrieval rather than just producing a report. If the rule is attached to the main repository without a pilot check, everyday developer and CI requests can suddenly stop.
After the policy is saved, OSA Proxy can apply it to new package requests.
Step 5. Verify that the client no longer sees forbidden versions¶
For this check it is more useful to look at the index response returned to the client than to simulate an installation of a single package version.
In this example the client requests the list of available requests versions through OSA Proxy and receives an already filtered Simple API response. If a dangerous version is absent from that response, the package manager cannot choose it for installation.
Step 6. Check the result in OSA -> Requests¶
The final step is needed to confirm that the platform recorded the request and its status, rather than only changing the package-manager response.
- Open
OSA -> Requests. - Switch to the Packages tab.
- Find the request made through the pilot PyPI repository.
- Check that the table shows:
- the package name;
- the operation mode;
- the block status;
- the request date;
- the request initiator.
At this point you can verify not only the client-side behavior, but also that the event is visible in the platform itself.
Result¶
You can consider the scenario complete if:
- OSA Proxy is deployed and runs in
strictmode for the PyPI source; - JFrog Artifactory fetches packages through OSA Proxy;
- CodeScoring contains an active blocking policy at the
proxystage with the Dependency is dangerous condition; - the client receives a filtered index response, and
OSA -> Requestsshows the recorded request and its status.
After that malicious and forbidden components can be stopped before they enter the internal repository and become available to development teams.
What next¶
- review request details and block statuses in OSA;
- refine OSA Proxy work modes and block response settings;
- extend the same pattern to other package managers.