'sudo: no tty present and no askpass program specified in github actions

Hey so I have this github action for saving a package-lock and package.json file like so:

# workflow that generates the package files for my webapp :)

name: generate-package-files

# Controls when the action will run.
on:
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
    inputs:
      myWebappBranch:
        description: 'my webapp branch'
        required: true
        default: 'someBranch'
      packageRepos:
        description: 'repos built out for the job.'
        required: true
        default: aPackage

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  generate_files:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x]

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:

      #set up node js
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install build essentials
        run: sudo apt-get -y install build-essential

      #sets up SSH so we can checkout the needed repos.
      - name: Setup SSH
        uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }}

      - name: Check out the webapp for building and make sure it exists first.
        run: (test -d my-app) || git clone [email protected]:my-repo/my-webapp.git

      # Runs a set of commands using the runners shell
      - name: build package files
        working-directory: my-webapp
        run: |
          git checkout ${{ github.event.inputs.myWebappBranch }}
          git pull
          npm ci
          npm install ${{ github.event.inputs.packageRepos }}

      - name: save files
        uses: actions/upload-artifact@v2
        with:
          name: package-lock
          path: package*

Seems ok, unfortunately, when I run it, I get:

Run sudo apt-get -y install build-essential
sudo: no tty present and no askpass program specified
Error: Process completed with exit code 1.

I'm not too sure what I am doing wrong. When I google around, the syntax for the install should work, from what I've seen in:

https://code-maven.com/slides/github-ci/install-packages-on-ubuntu-linux-in-github-actions

and https://docs.github.com/en/actions/using-github-hosted-runners/customizing-github-hosted-runners#installing-software-on-ubuntu-runners

This seems to be the right solution. I've tried editting the sudoers file, but I get access denied. Any help would be awesome! :)



Solution 1:[1]

For this to work, you will need sudo without password to be allowed.

sudo prints this error message, if it tries to prompt for a password but can't.

Solution 2:[2]

This will happen with any GitHub action that runs a program that invokes Sudo. Most of the other answers both here and in other similar questions basically turn off sudo, which is dangerous, obviously. Also, this will only work for self-hosted GitHub runners, as you can't modify the regular GitHub VM's.

One way to do it is to turn off the ask password prompt for the specific commands you need to invoke. I did this with:

sudo visudo

NOTE: if you mess up this file, you will break your system. Be wery, wery careful; we're hunting wabbits.

Then add a line that looks like this for the specific command in your github action:

webmaster ALL = NOPASSWD: /exact/path/to/your/command and_then_any_params

In this case, I was just doing a restart of a web service, so I didn't have any issue turning this off for anyone on the local terminal as well.

The visudo approach worked and is still moderately secure.

Things that didn't work: Apparently, you can use -S to force Sudo to read from stdin, so something simple like piping a GitHub secret to the sudo command should work. This would be nice as you would not have to modify every blasted server.

So I tried this in my GitHub YAML:

printf "${{ secrets.WEB_SU_PASSWORD }}\n" | sudo -S myscript myparams 

This is what it looked like in the GitHub action log:

# printf "***\n" | sudo -S myscript myparams
shell: /bin/bash -e {0}
sudo: no tty present and no askpass program specified

So, the same fundamental problem. In the interests of time, I'm just doing the visudo approach listed above. To keep things secure, I'm not doing the ALL command that sysadmins that haven't been hacked yet recommend.

Update:

The actual lines in your visudo file will probably be much more complicated, and may take some fiddling. For example, I just needed one command run and ended up changing it to this:

erp ALL = NOPASSWD: /usr/sbin/service
erp ALL = NOPASSWD: /usr/sbin/service nginx *
erp ALL = NOPASSWD: /usr/sbin/service supervisord *
erp ALL = NOPASSWD: /bin/systemctl
erp ALL = NOPASSWD: /bin/systemctl * nginx
erp ALL = NOPASSWD: /bin/systemctl * supervisord
erp ALL = NOPASSWD: /usr/bin/supervisorctl
erp ALL = NOPASSWD: /usr/sbin/nginx

The command was a python shell script that ran some of the above commands; just adding the script name itself wasn't enough.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sborsky
Solution 2