Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Harden GitHub Actions Workflow - publish.yml #27

Open
stepsecurity-int bot opened this issue Dec 18, 2024 · 1 comment
Open

Harden GitHub Actions Workflow - publish.yml #27

stepsecurity-int bot opened this issue Dec 18, 2024 · 1 comment

Comments

@stepsecurity-int
Copy link

GitHub Token Permissions Are Not Set to Minimum in Workflow

Summary

The GitHub token permissions in your workflow file (.github/workflows/publish.yml) exceed the minimum required. Reducing permissions to the minimum necessary enhances security by limiting the access scope of the token, thereby lowering the risk of accidental or malicious misuse.

Why This is Important

Using excessive permissions in GitHub workflows can expose your repository to potential security risks. The GitHub token grants access to repository resources, and any unnecessary permissions increase the likelihood of sensitive actions being performed without justification. By applying the principle of least privilege, you protect your repository from unintended data exposure and ensure that each job only has access to what it absolutely needs.

Suggested Fix

Below is the updated permissions configuration, which minimizes access for the GitHub token. Update your workflow file with this suggested configuration to resolve this issue:

  # Ultralytics YOLO 🚀, AGPL-3.0 license
  # Publish pip package to PyPI https://pypi.org/project/ultralytics/
  name: Publish to PyPI
  on:
    push:
      branches: [main]
    workflow_dispatch:
      inputs:
        pypi:
          type: boolean
          description: Publish to PyPI
+ permissions:
+   contents: read
  jobs:
    publish:
      if: github.repository == 'ultralytics/ultralytics' && github.actor == 'glenn-jocher'
      name: Publish
      runs-on: ubuntu-latest
      environment: # for GitHub Deployments tab
        name: Release - PyPI
        url: https://pypi.org/p/ultralytics
      permissions:
        id-token: write # for PyPI trusted publishing
      steps:
        - name: Checkout code
          uses: actions/checkout@v4
          with:
            token: ${{ secrets._GITHUB_TOKEN }}
        - name: Git config
          run: |
            git config --global user.name "UltralyticsAssistant"
            git config --global user.email "[email protected]"
        - name: Set up Python environment
          uses: actions/setup-python@v5
          with:
            python-version: "3.x"
        - uses: astral-sh/setup-uv@v4
        - name: Install dependencies
          run: uv pip install --system --no-cache ultralytics-actions build twine toml
        - name: Check PyPI version
          shell: python
          run: |
            import os
            from actions.utils import check_pypi_version
            local_version, online_version, publish = check_pypi_version()
            os.system(f'echo "increment={publish}" >> $GITHUB_OUTPUT')
            os.system(f'echo "current_tag=v{local_version}" >> $GITHUB_OUTPUT')
            os.system(f'echo "previous_tag=v{online_version}" >> $GITHUB_OUTPUT')
            if publish:
                print('Ready to publish new version to PyPI ✅.')
          id: check_pypi
        - name: Build package
          if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True'
          run: python -m build
        - name: Publish to PyPI
          continue-on-error: true
          if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True'
          uses: pypa/gh-action-pypi-publish@release/v1
        - name: Publish new tag
          continue-on-error: true
          if: (github.event_name == 'push' || github.event.inputs.pypi == 'true')  && steps.check_pypi.outputs.increment == 'True'
          run: |
            git tag -a "${{ steps.check_pypi.outputs.current_tag }}" -m "$(git log -1 --pretty=%B)"  # i.e. "v0.1.2 commit message"
            git push origin "${{ steps.check_pypi.outputs.current_tag }}"
        - name: Publish new release
          continue-on-error: true
          if: (github.event_name == 'push' || github.event.inputs.pypi == 'true')  && steps.check_pypi.outputs.increment == 'True'
          env:
            OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
            GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
            CURRENT_TAG: ${{ steps.check_pypi.outputs.current_tag }}
            PREVIOUS_TAG: ${{ steps.check_pypi.outputs.previous_tag }}
          run: ultralytics-actions-summarize-release
          shell: bash
        - name: Extract PR Details
          env:
            GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          run: |
            PR_JSON=$(gh pr list --search "${GITHUB_SHA}" --state merged --json number,title --jq '.[0]')
            PR_NUMBER=$(echo "${PR_JSON}" | jq -r '.number')
            PR_TITLE=$(echo "${PR_JSON}" | jq -r '.title')
            echo "PR_NUMBER=${PR_NUMBER}" >> "${GITHUB_ENV}"
            echo "PR_TITLE=${PR_TITLE}" >> "${GITHUB_ENV}"
        - name: Prune uv Cache
          run: uv cache prune --ci
        - name: Notify on Slack (Success)
          if: success() && github.event_name == 'push' && steps.check_pypi.outputs.increment == 'True'
          uses: slackapi/[email protected]
          with:
            webhook-type: incoming-webhook
            webhook: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}
            payload: |
              text: "<!channel> GitHub Actions success for ${{ github.workflow }} ✅\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* NEW `${{ github.repository }} ${{ steps.check_pypi.outputs.current_tag }}` pip package published 😃\n*Job Status:* ${{ job.status }}\n*Pull Request:* <https://github.com/${{ github.repository }}/pull/${{ env.PR_NUMBER }}> ${{ env.PR_TITLE }}\n"
        - name: Notify on Slack (Failure)
          if: failure()
          uses: slackapi/[email protected]
          with:
            webhook-type: incoming-webhook
            webhook: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}
            payload: |
              text: "<!channel> GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n*Job Status:* ${{ job.status }}\n*Pull Request:* <https://github.com/${{ github.repository }}/pull/${{ env.PR_NUMBER }}> ${{ env.PR_TITLE }}\n"

Next Steps

Please review and update the workflow file with these minimum permissions. If additional permissions are necessary for certain steps, specify only those permissions explicitly.

For further guidance, refer to the GitHub documentation on fine-grained permissions.

Severity: High

Copy link

👋 Hello there! We wanted to give you a friendly reminder that this issue has not had any recent activity and may be closed soon, but don't worry - you can always reopen it if needed. If you still have any questions or concerns, please feel free to let us know how we can help.

For additional resources and information, please see the links below:

Feel free to inform us of any other issues you discover or feature requests that come to mind in the future. Pull Requests (PRs) are also always welcomed!

Thank you for your contributions to YOLO 🚀 and Vision AI ⭐

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants