Skip to content

Commit

Permalink
Document unprivileged user in GitHub workflows
Browse files Browse the repository at this point in the history
At some point GitHub changed things so that the entrypoint script does
not run, so the `AS_USER` variable does nothing. Which is just as well,
becaues that user would have no permissions, so even a checkout will
fail.

So remove the GitHib-specific stuff from `entrypoint.sh` and document
how to use `gosu` directly in a GitHub workflow to execute commands as
an unprivileged user.

Thanks to @pgguru for figuring out the technique.
  • Loading branch information
theory committed Feb 5, 2024
1 parent 475d691 commit f10ccf7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
# Test with Git repo
- name: Test Git as root
run: "docker run -w /repo --rm --volume \"$(pwd):/repo\" pgxn-tools-test ./test/runtest.sh ${{ matrix.pg }} git"
- name: Test Git as postgres
run: "docker run -w /repo --rm --volume \"$(pwd):/repo\" -u postgres pgxn-tools-test ./test/runtest.sh ${{ matrix.pg }} git"
- name: Test Git as non-root
run: "docker run -w /repo --rm --volume \"$(pwd):/repo\" -e AS_USER=worker pgxn-tools-test ./test/runtest.sh ${{ matrix.pg }} git"
- name: Test Git with extra file
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ RUN chmod +x /usr/local/bin/apt.postgresql.org.sh \
&& ./cpanm --notest PGXN::Meta::Validator \
&& rm -r cpanm ~/.cpanm \
&& echo Defaults lecture = never >> /etc/sudoers \
&& perl -i -pe 's/\bALL$/NOPASSWD:ALL/g' /etc/sudoers \
&& echo 'postgres ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& usermod -a -G sudo postgres \
# Ensure Git can do stuff in the working directory (issue #5).
&& git config --system --add safe.directory '*' \
# Install git-archive-all
Expand Down
53 changes: 34 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ The image is based on the Debian Bookworm Slim image, and uses the
Unprivileged User
-----------------

By default the container runs as `root`. To run as an unprivileged user, pass
the `AS_USER` environment variable, and a user with that name will be created
with `sudo` privileges (already used by `pg-start` and `pg-build-test`):
By default the container runs as `root`. To run as an unprivileged user (unless
the runtime environment requires the the user to be root, in which case [see
below](#unprivileged-user-workflow)), pass the `AS_USER` environment variable
and a user with that name will be created with `sudo` privileges (already used
by `pg-start` and `pg-build-test`):

``` sh
docker run -it --rm -w /repo -e AS_USER=worker \
Expand All @@ -46,11 +48,6 @@ docker run -it --rm -w /repo -e AS_USER=worker -e LOCAL_UID=$(id -u) \
sh -c 'sudo pg-start 14 && pg-build-test'
```

If no `LOCAL_UID` is set but `GITHUB_EVENT_PATH` is set (as it is in GitHub
workflows), the UID will be set to the same value as the owner of the
`GITHUB_EVENT_PATH` file. This allows the user to have full access to the
GitHub project volume.

### Postgres User

The `postgres` user, created by `pg-start`, also has full permission to use
Expand All @@ -77,20 +74,11 @@ jobs:
- name: Start PostgreSQL ${{ matrix.pg }}
run: pg-start ${{ matrix.pg }}
- name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Test on PostgreSQL ${{ matrix.pg }}
run: pg-build-test
```
If you need to run the tests as an unprivileged user, pass the `AS_USER`
variable as a container option:

``` yaml
container:
image: pgxn/pgxn-tools
options: -e AS_USER=randy
```

This example demonstrates automatic publishing of a release whenever a tag is
pushed matching `v*`. It publishes both to GitHub (using the [create-release]
and [upload-release-asset] actions) and to PGXN:
Expand All @@ -111,7 +99,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Check out the repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Bundle the Release
id: bundle
run: pgxn-bundle
Expand Down Expand Up @@ -141,6 +129,31 @@ jobs:
asset_content_type: application/zip
```

### Unprivileged User Workflow

If you need to run take action as an unprivileged user, the `AS_USER` variable
[documented above](#unprivileged-user) will not work, both because GitHub
actions [require the root user] to work with the workspace and because GitHub
does not execute `entrypoint` script.

Instead, set things up as the root user, then use [gosu] to execute a command as
the `postgres` (can still run `sudo`) or `nobody` (no privileges at all) user.
For example:

``` yaml
container: pgxn/pgxn-tools
steps:
- uses: actions/checkout@v4
- run: pg-start ${{ matrix.pg }}
- run: chown -R postgres:postgres .
- run: gosu postgres pg-build-test
```

The checkout action, `pg-start`, and `chown` commands run as `root`. Then, with
the current directory's files all owned the `postgres` user, the last `run`
commands executes `pg-build-test` as `postgres`, with the necessary permissions
to write files to the workspace directory.

Tools
-----

Expand Down Expand Up @@ -388,7 +401,9 @@ Copyright (c) 2020-2024 The PGXN Maintainers. Distributed under the
[`pgxn-release`]: bin/pgxn-release
[PostgreSQL Apt]: https://wiki.postgresql.org/wiki/Apt
[back to 8.2]: http://apt.postgresql.org/pub/repos/apt/dists/bookworm-pgdg/
[require the root user]: https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#user
[GithHub Workflow]: https://help.github.com/en/actions/configuring-and-managing-workflows
[gosu]: https://github.com/tianon/gosu
[create-release]: https://github.com/actions/create-release
[upload-release-asset]: https://github.com/actions/upload-release-asset
[git-archive-all]: https://github.com/Kentzo/git-archive-all
Expand Down
10 changes: 1 addition & 9 deletions bin/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,9 @@ set -e
# Just continue if unprivileged user not requested.
[ -z "$AS_USER" ] && exec "$@"

USER_ID=${LOCAL_UID:-0}
USER_ID=${LOCAL_UID:-1001}
USERNAME=worker

if [ $USER_ID == 0 ]; then
if [ -n "${GITHUB_EVENT_PATH}" ]; then
USER_ID=$(stat -f %u "${GITHUB_EVENT_PATH}")
else
USER_ID=1001
fi
fi

echo "Starting with UID $USER_ID"
useradd --system --create-home --shell /bin/bash -g root -G sudo -u $USER_ID "$AS_USER"
export HOME="/home/$AS_USER"
Expand Down

0 comments on commit f10ccf7

Please sign in to comment.