-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: first cut of credential helper plugin
- Loading branch information
1 parent
6aa82f6
commit 953a0ce
Showing
7 changed files
with
251 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: bash-checks | ||
|
||
on: | ||
pull_request: | ||
|
||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Lint | ||
run: docker-compose run --rm lint | ||
|
||
- name: Test | ||
run: docker-compose run --rm tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,53 @@ | ||
# github-app-auth-buildkite-plugin | ||
Combines a Git credential helper with a separate helper agent to allow Buildkite agents securely authorize Github repository access.. | ||
|
||
Combines a Git credential helper with a separate helper agent to allow Buildkite agents securely authorize Github repository access. | ||
|
||
## Example | ||
|
||
Add the following to your `pipeline.yml`: | ||
|
||
```yml | ||
steps: | ||
- command: ls | ||
plugins: | ||
- jamestelfer/github-app-auth#v0.1.0: | ||
vendor-url: "https://your-vendor-agent" | ||
audience: "github-app-auth:your-buildkite-organization" | ||
``` | ||
## Configuration | ||
### `vendor-url` (Required, string) | ||
|
||
The URL of the helper agent that vends a token for a pipeline. This is a | ||
separate (as yet unreleased) agent that is accessible to your Buildkite agents. | ||
|
||
### `audience` (string) | ||
|
||
**Default:** `github-app-auth:default` | ||
|
||
The value of the `aud` claim of the OIDC JWT that will be sent to the helper | ||
agent. This must correlate with the value configured in the vendor agent | ||
settings. | ||
|
||
A recommendation: `github-app-auth:your-github-organization`. This is specific | ||
to the purpose of the token, and also scoped to the GitHub organization that | ||
tokens will be vended for. The agent's GitHub app is configured for a particular | ||
GitHub organization/user, so if you have multiple organizations, multiple agents | ||
will need to be running. | ||
|
||
## Developing | ||
|
||
To run the tests: | ||
|
||
```shell | ||
docker-compose run --rm tests | ||
``` | ||
|
||
## Contributing | ||
|
||
1. Fork the repo | ||
2. Make the changes | ||
3. Run the tests | ||
4. Commit and push your changes | ||
5. Send a pull request |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/bash | ||
set -eou pipefail | ||
|
||
url="${1:?url parameter required}" | ||
audience="${2:?audience parameter required}" | ||
action="${2:?action parameter required}" | ||
|
||
# ignore unsupported actions without error | ||
if [[ "${action}" != "get" ]]; then | ||
exit 0 | ||
fi | ||
|
||
# read credential helper input from stdin | ||
args="$(< /dev/stdin)" | ||
|
||
oidc_auth_token="$(buildkite-agent oidc request-token --audience "${audience}")" | ||
|
||
# Request a token for the given repository from the remote server, using the | ||
# OIDC JWT from the agent. The output of this request is in the expected format, | ||
# so is sent to stdout to be read by git. | ||
curl --silent --show-error --fail \ | ||
--request POST "${url}/git-credentials" \ | ||
--data "${args}" \ | ||
--header "Authorization: Bearer ${oidc_auth_token}" \ | ||
--header "Content-Type: text/plain" \ | ||
--header "Accept: text/plain" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
services: | ||
lint: | ||
image: buildkite/plugin-linter | ||
command: ['--id', 'jamestelfer/github-app-auth'] | ||
volumes: | ||
- ".:/plugin:ro" | ||
|
||
tests: | ||
image: buildkite/plugin-tester | ||
volumes: | ||
- ".:/plugin:ro" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/bash | ||
set -euo pipefail | ||
|
||
vendor_url="${BUILDKITE_PLUGIN_GITHUB_APP_AUTH_VENDOR_URL:?vendor-url property required}" | ||
audience="${BUILDKITE_PLUGIN_GITHUB_APP_AUTH_AUDIENCE:-github-app-auth:default}" | ||
|
||
echo "~~~ :git: :github: Configuring git to authenticate via the vendor agent" | ||
|
||
plugin_root="$(cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd)" | ||
|
||
echo "Credential helper will run from plugin root ${plugin_root}" | ||
|
||
# set up the helper using environment variables for git config, as defined at | ||
# https://git-scm.com/docs/git-config#ENVIRONMENT | ||
|
||
git_config_add() { | ||
local key="$1" | ||
local value="$2" | ||
|
||
count="${GIT_CONFIG_COUNT:-0}" | ||
|
||
# count is incremented each time a setting is added | ||
(( count++ )) | ||
|
||
export GIT_CONFIG_COUNT="${count}" | ||
export "GIT_CONFIG_KEY_${count}=${key}" | ||
export "GIT_CONFIG_VALUE_${count}=${value}" | ||
} | ||
|
||
git_config_add "credential.https://github.com.usehttppath" "true" | ||
git_config_add "credential.https://github.com.helper" "${plugin_root}/credential-helper/buildkite-connector-credential-helper ${vendor_url} ${audience}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: Github App Auth | ||
description: | | ||
Adds a Git credential helper that authorizes a pipeline to access its Github | ||
using HTTPS and a time-limited token. | ||
The helper agent (separate) is accessed via HTTP, using the Buildkite Agent | ||
OIDC token as its authorization. | ||
author: https://github.com/jamestelfer | ||
requirements: [] | ||
configuration: | ||
properties: | ||
vendor-url: | ||
type: string | ||
description: The URL of the helper agent that vends a token for a pipeline. | ||
audience: | ||
type: string | ||
description: (Default `github-app-auth:default`.) The audience to use for the Buildkite OIDC JWT that is sent to the vendor agent. Must match the setting in the vendor agent. | ||
additionalProperties: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/usr/bin/env bats | ||
|
||
load "${BATS_PLUGIN_PATH}/load.bash" | ||
|
||
# | ||
# Tests for pre-command hook | ||
# | ||
|
||
# Uncomment the following line to debug stub failures | ||
# export [stub_command]_STUB_DEBUG=/dev/tty | ||
#export DOCKER_STUB_DEBUG=/dev/tty | ||
|
||
clear_git_config() { | ||
if [[ -n "${GIT_CONFIG_COUNT}" ]]; then | ||
for i in $(seq 1 "${GIT_CONFIG_COUNT}"); do | ||
unset "GIT_CONFIG_KEY_$i" | ||
unset "GIT_CONFIG_VALUE_$i" | ||
done | ||
|
||
unset ${GIT_CONFIG_COUNT} | ||
fi | ||
} | ||
|
||
setup() { | ||
clear_git_config | ||
} | ||
|
||
teardown() { | ||
unset BUILDKITE_PLUGIN_GITHUB_APP_AUTH_VENDOR_URL | ||
unset BUILDKITE_PLUGIN_GITHUB_APP_AUTH_AUDIENCE | ||
|
||
clear_git_config | ||
} | ||
|
||
run_environment() { | ||
run bash -c "source $* && (env | grep GIT_)" | ||
} | ||
|
||
@test "Fails without configuration" { | ||
# export BUILDKITE_COMMAND_EXIT_STATUS=0 | ||
|
||
run "$PWD/hooks/environment" | ||
|
||
assert_failure | ||
assert_line --partial "vendor-url property required" | ||
} | ||
|
||
@test "Adds config for default audience" { | ||
export BUILDKITE_PLUGIN_GITHUB_APP_AUTH_VENDOR_URL=http://test-location | ||
|
||
run_environment "${PWD}/hooks/environment" | ||
|
||
assert_success | ||
assert_line "GIT_CONFIG_COUNT=2" | ||
assert_line "GIT_CONFIG_KEY_1=credential.https://github.com.usehttppath" | ||
assert_line "GIT_CONFIG_VALUE_1=true" | ||
assert_line "GIT_CONFIG_KEY_2=credential.https://github.com.helper" | ||
assert_line --regexp "GIT_CONFIG_VALUE_2=/.*/credential-helper/buildkite-connector-credential-helper http://test-location github-app-auth:default" | ||
} | ||
|
||
@test "Adds config for non-default audience" { | ||
export BUILDKITE_PLUGIN_GITHUB_APP_AUTH_VENDOR_URL=http://test-location | ||
export BUILDKITE_PLUGIN_GITHUB_APP_AUTH_AUDIENCE=test-audience | ||
|
||
run_environment "${PWD}/hooks/environment" | ||
|
||
assert_success | ||
assert_line "GIT_CONFIG_COUNT=2" | ||
assert_line "GIT_CONFIG_KEY_1=credential.https://github.com.usehttppath" | ||
assert_line "GIT_CONFIG_VALUE_1=true" | ||
assert_line "GIT_CONFIG_KEY_2=credential.https://github.com.helper" | ||
assert_line --regexp "GIT_CONFIG_VALUE_2=/.*/credential-helper/buildkite-connector-credential-helper http://test-location test-audience" | ||
} | ||
|
||
@test "Adds to existing configuration if present" { | ||
export BUILDKITE_PLUGIN_GITHUB_APP_AUTH_VENDOR_URL=http://test-location | ||
|
||
export GIT_CONFIG_COUNT="3" | ||
export GIT_CONFIG_KEY_3="key-3" | ||
export GIT_CONFIG_VALUE_3="value-3" | ||
|
||
run_environment "${PWD}/hooks/environment" | ||
|
||
assert_success | ||
assert_line "GIT_CONFIG_COUNT=5" | ||
assert_line "GIT_CONFIG_KEY_3=key-3" | ||
assert_line "GIT_CONFIG_VALUE_3=value-3" | ||
assert_line "GIT_CONFIG_KEY_4=credential.https://github.com.usehttppath" | ||
assert_line "GIT_CONFIG_VALUE_4=true" | ||
assert_line "GIT_CONFIG_KEY_5=credential.https://github.com.helper" | ||
assert_line --regexp "GIT_CONFIG_VALUE_5=/.*/credential-helper/buildkite-connector-credential-helper http://test-location github-app-auth:default" | ||
} |