Skip to content

Commit ce0a90c

Browse files
Merge pull request #387 from pyupio/develop
Safety 2.0b5 patch
2 parents fd5e4cb + 7ac6461 commit ce0a90c

24 files changed

+1184
-94
lines changed

.github/workflows/build.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Safety Action Build And Publish
2+
3+
on: [push]
4+
5+
env:
6+
DOCKER_BUILDKIT: 1
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
environment: main
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
16+
- name: Build image
17+
run: docker build -t pyupio/safety-v2-beta:latest .
18+
19+
- name: Upload image
20+
env:
21+
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
22+
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
23+
run: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin &&
24+
docker push pyupio/safety-v2-beta:latest
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
######## Insecure test cases. All of these use insecure packages, and should fail - so they have `continue-on-error`
2+
######## set on the action step, and a further step to ensure the previous step failed (and actually fail if it _didn't_)
3+
name: Safety Action Insecure Tests
4+
5+
on: [push]
6+
7+
jobs:
8+
##### Auto mode tests
9+
### File scanning
10+
# Scans a requirements.txt in the repo; the simplest case. We contort one into existing for this test
11+
# case, to avoid confusion
12+
test-auto-requirements-txt-insecure:
13+
runs-on: ubuntu-latest
14+
environment: main
15+
16+
steps:
17+
- uses: actions/checkout@v2
18+
19+
- run: cp tests/action/requirements.txt-insecure requirements.txt
20+
21+
- uses: ./
22+
id: scan-1
23+
continue-on-error: true
24+
with:
25+
api-key: ${{ secrets.SAFETY_API_KEY }}
26+
27+
- if: steps.scan-1.outcome != 'failure' || steps.scan-1.outputs.exit-code != '64'
28+
run: exit 1
29+
30+
# Same as above, but for a poetry lock file
31+
test-auto-poetry-insecure:
32+
runs-on: ubuntu-latest
33+
environment: main
34+
35+
steps:
36+
- uses: actions/checkout@v2
37+
38+
- run: cp tests/action/poetry.lock-insecure poetry.lock && cp tests/action/pyproject.toml-insecure pyproject.toml
39+
40+
- uses: ./
41+
id: scan-2
42+
continue-on-error: true
43+
with:
44+
api-key: ${{ secrets.SAFETY_API_KEY }}
45+
46+
- if: steps.scan-2.outcome != 'failure' || steps.scan-2.outputs.exit-code != '64'
47+
run: exit 1
48+
49+
# Same as above, but for a Pipfile.lock
50+
test-auto-pipfile-insecure:
51+
runs-on: ubuntu-latest
52+
environment: main
53+
54+
steps:
55+
- uses: actions/checkout@v2
56+
57+
- run: cp tests/action/Pipfile.lock-insecure Pipfile.lock
58+
59+
- uses: ./
60+
id: scan-3
61+
continue-on-error: true
62+
with:
63+
api-key: ${{ secrets.SAFETY_API_KEY }}
64+
65+
- if: steps.scan-3.outcome != 'failure' || steps.scan-3.outputs.exit-code != '64'
66+
run: exit 1
67+
68+
### Env scanning:
69+
### Scans the runner environment. Here, the Github action `actions/setup-python@v3` actually
70+
### installs things in the root VM that the action runs on; this is what gets scanned.
71+
test-auto-environment-insecure:
72+
runs-on: ubuntu-latest
73+
environment: main
74+
75+
steps:
76+
- uses: actions/checkout@v2
77+
78+
- uses: actions/setup-python@v3
79+
with:
80+
python-version: '3.10'
81+
architecture: 'x64'
82+
83+
- run: python -m pip install -r tests/action/requirements.txt-insecure
84+
85+
- uses: ./
86+
id: scan-4
87+
continue-on-error: true
88+
with:
89+
api-key: ${{ secrets.SAFETY_API_KEY }}
90+
91+
- if: steps.scan-4.outcome != 'failure' || steps.scan-4.outputs.exit-code != '64'
92+
run: exit 1
93+
94+
### Docker scanning:
95+
### Scans a recently built Docker container. This uses a few heuristics, defined in entrypoint.sh
96+
test-auto-docker-insecure:
97+
runs-on: ubuntu-latest
98+
environment: main
99+
100+
steps:
101+
- uses: actions/checkout@v2
102+
103+
- name: Build image
104+
run: DOCKER_BUILDKIT=1 docker build -t my-insecure-image tests/action/docker-insecure
105+
106+
- uses: ./
107+
id: scan-5
108+
continue-on-error: true
109+
with:
110+
api-key: ${{ secrets.SAFETY_API_KEY }}
111+
112+
- if: steps.scan-5.outcome != 'failure' || steps.scan-5.outputs.exit-code != '64'
113+
run: exit 1

.github/workflows/test-secure.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
######## Secure test cases. All of these use secure packages, and shouldn't fail. Easier than our insecure
2+
######## case, as we don't need anything else. We test against Safety and its deps here; if these tests
3+
######## fail, the pinned version might need to be updated.
4+
name: Safety Action Secure Tests
5+
6+
on: [push]
7+
8+
jobs:
9+
##### Auto mode tests
10+
### File scanning
11+
# Scans a requirements.txt in the repo; the simplest case. We contort one into existing for this test
12+
# case, to avoid confusion
13+
test-auto-requirements-txt-secure:
14+
runs-on: ubuntu-latest
15+
environment: main
16+
17+
steps:
18+
- uses: actions/checkout@v2
19+
20+
- run: cp tests/action/requirements.txt-secure requirements.txt
21+
22+
- uses: ./
23+
id: scan-1
24+
with:
25+
api-key: ${{ secrets.SAFETY_API_KEY }}
26+
27+
# Same as above, but for a poetry lock file
28+
test-auto-poetry-secure:
29+
runs-on: ubuntu-latest
30+
environment: main
31+
32+
steps:
33+
- uses: actions/checkout@v2
34+
35+
- run: cp tests/action/poetry.lock-secure poetry.lock && cp tests/action/pyproject.toml-secure pyproject.toml
36+
37+
- uses: ./
38+
id: scan-2
39+
with:
40+
api-key: ${{ secrets.SAFETY_API_KEY }}
41+
42+
# Same as above, but for a Pipfile.lock
43+
test-auto-pipfile-secure:
44+
runs-on: ubuntu-latest
45+
environment: main
46+
47+
steps:
48+
- uses: actions/checkout@v2
49+
50+
- run: cp tests/action/Pipfile.lock-secure Pipfile.lock
51+
52+
- uses: ./
53+
id: scan-3
54+
with:
55+
api-key: ${{ secrets.SAFETY_API_KEY }}
56+
57+
### Env scanning:
58+
### Scans the runner environment. Here, the Github action `actions/setup-python@v3` actually
59+
### installs things in the root VM that the action runs on; this is what gets scanned.
60+
test-auto-environment-secure:
61+
runs-on: ubuntu-latest
62+
environment: main
63+
64+
steps:
65+
- uses: actions/checkout@v2
66+
67+
- uses: actions/setup-python@v3
68+
with:
69+
python-version: '3.10'
70+
architecture: 'x64'
71+
72+
- run: python -m pip install -r tests/action/requirements.txt-secure
73+
74+
- uses: ./
75+
id: scan-4
76+
with:
77+
api-key: ${{ secrets.SAFETY_API_KEY }}
78+
79+
### Docker scanning:
80+
### Scans a recently built Docker container. This uses a few heuristics, defined in entrypoint.sh
81+
test-auto-docker-secure:
82+
runs-on: ubuntu-latest
83+
environment: main
84+
85+
steps:
86+
- uses: actions/checkout@v2
87+
88+
- name: Build image
89+
run: DOCKER_BUILDKIT=1 docker build -t my-secure-image tests/action/docker-secure
90+
91+
- uses: ./
92+
id: scan-5
93+
with:
94+
api-key: ${{ secrets.SAFETY_API_KEY }}

Dockerfile

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1-
FROM python:3.6-slim
2-
RUN pip install --trusted-host pypi.python.org safety
3-
CMD ["python"]
1+
FROM python:3.10-slim
2+
3+
# Don't use WORKDIR here as per Github's docs
4+
RUN mkdir /app
5+
6+
RUN apt-get update && apt-get -y install docker.io jq && apt-get clean && rm -rf /var/lib/apt/lists/*
7+
8+
# Install poetry and pipenv; used for converting their respective lockfile formats to generic requirements.txt
9+
RUN cd /app && python3 -m pip install poetry==1.1.13 pipenv==2022.6.7
10+
11+
# Install this project dependencies
12+
COPY . /app
13+
RUN cd /app && python3 -m pip install -e .
14+
15+
ENV LC_ALL=C.UTF-8
16+
ENV LANG=C.UTF-8
17+
ENV PYTHONPATH="/app"
18+
19+
LABEL safety_autodetect=ignore
20+
21+
ENTRYPOINT ["/app/entrypoint.sh"]

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,28 @@
44
[![Travis](https://img.shields.io/travis/pyupio/safety.svg)](https://travis-ci.org/pyupio/safety)
55
[![Updates](https://pyup.io/repos/github/pyupio/safety/shield.svg)](https://pyup.io/repos/github/pyupio/safety/)
66

7-
Safety checks your installed Python dependencies for known security vulnerabilities and suggests the proper remediations for vulnerabilities detected. Safety can be run on developer machines, in CI/CD pipelines and on production systems.
7+
Safety checks Python dependencies for known security vulnerabilities and suggests the proper remediations for vulnerabilities detected. Safety can be run on developer machines, in CI/CD pipelines and on production systems.
88

99
By default it uses the open Python vulnerability database [Safety DB](https://github.com/pyupio/safety-db), which is **licensed for non-commercial use only**.
1010

1111
For all commercial projects, Safely must be upgraded to use a [PyUp API](https://pyup.io) using the `--key` option.
1212

13+
# Using Safety as a GitHub Action
14+
15+
Safety can be integrated into your existing GitHub CI pipeline as an action. Just add the following as a step in your workflow YAML file after setting your `SAFETY_API_KEY` secret on GitHub under Settings -> Secrets -> Actions:
16+
17+
```yaml
18+
- uses: pyupio/safety@v1
19+
with:
20+
api-key: ${{ secrets.SAFETY_API_KEY }}
21+
```
22+
23+
(Don't have an API Key? You can sign up for one with [PyUp](https://pyup.io).)
24+
25+
This will run Safety in auto-detect mode which figures out your project's structure and the best configuration to run in automatically. It'll fail your CI pipeline if any vulnerable packages are found.
26+
27+
If you have something more complicated such as a monorepo; or once you're finished testing, read the [Action Documentation](https://docs.pyup.io/docs/github-actions-safety) for more details on configuring Safety as an action.
28+
1329
# Installation
1430
1531
Install `safety` with pip. Keep in mind that we support only Python 3.6 and up.

action.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# action.yml
2+
name: 'pyupio/safety'
3+
description: 'Runs the Safety CLI against your project'
4+
inputs:
5+
api-key:
6+
description: 'PyUp API key'
7+
required: false
8+
default: ''
9+
scan:
10+
description: 'Scan mode to use. One of auto / docker / env / file (defaults to auto)'
11+
required: false
12+
default: 'auto'
13+
docker-image:
14+
description: 'Tag or hash of the Docker Image to scan (defaults to autodetecting the last built tagged image)'
15+
required: false
16+
default: ''
17+
requirements:
18+
description: 'Path of requirements file to scan (defaults to poetry.lock -> Pipfile.lock -> requirements.txt)'
19+
required: false
20+
default: ''
21+
continue-on-error:
22+
description: 'By default, Safety will exit with a non-zero exit code if it detects any vulnerabilities. Set this to yes / true to not error out.'
23+
required: false
24+
default: ''
25+
output-format:
26+
description: 'Output format for returned data. One of screen / text / json / bare (defaults to screen)'
27+
required: false
28+
default: 'screen'
29+
args:
30+
description: '[Advanced] Any additional arguments to pass to Safety'
31+
required: false
32+
default: ''
33+
34+
outputs:
35+
cli-output:
36+
description: 'CLI output from Safety'
37+
exit-code:
38+
description: 'Exit code from Safety'
39+
40+
runs:
41+
using: 'docker'
42+
image: 'docker://pyupio/safety-v2-beta:latest'
43+
env:
44+
SAFETY_API_KEY: ${{ inputs.api-key }}
45+
SAFETY_ACTION: true
46+
SAFETY_ACTION_SCAN: ${{ inputs.scan }}
47+
SAFETY_ACTION_DOCKER_IMAGE: ${{ inputs.docker-image }}
48+
SAFETY_ACTION_REQUIREMENTS: ${{ inputs.requirements }}
49+
SAFETY_ACTION_CONTINUE_ON_ERROR: ${{ inputs.continue-on-error }}
50+
SAFETY_ACTION_OUTPUT_FORMAT: ${{ inputs.output-format }}
51+
SAFETY_ACTION_ARGS: ${{ inputs.args }}
52+
SAFETY_ACTION_FORMAT: true
53+
COLUMNS: 120
54+
55+
branding:
56+
icon: 'lock'
57+
color: 'purple'

0 commit comments

Comments
 (0)