Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/hashicorp/vault-ac…
Browse files Browse the repository at this point in the history
…tion-2.7.3
  • Loading branch information
Paulo Gomes da Cruz Junior authored Nov 16, 2023
2 parents 9aba4b4 + 479c13a commit 5ae6839
Show file tree
Hide file tree
Showing 683 changed files with 229,599 additions and 185 deletions.
29 changes: 23 additions & 6 deletions .github/workflows/pr-close.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
contents: write
discussions: write
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main'
runs-on: ubuntu-22.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3

- name: Backing up Changelog
run: |
mv CHANGELOG.md OLD.CHANGELOG.md
Expand All @@ -35,15 +35,15 @@ jobs:
skip-version-file: 'true'
skip-commit: 'false'
git-push: 'true'

- name: Merging Changelog
if: ${{ !steps.changelog.outputs.skipped }}
run: |
mv CHANGELOG.md RELEASE.md
cat RELEASE.md OLD.CHANGELOG.md > CHANGELOG.md
- name: Update resources
uses: test-room-7/action-update-file@v1.6.0
uses: test-room-7/action-update-file@v1.8.0
if: ${{ !steps.changelog.outputs.skipped }}
with:
file-path: CHANGELOG.md
Expand All @@ -59,4 +59,21 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.changelog.outputs.tag }}
name: ${{ steps.changelog.outputs.tag }}
body: ${{ steps.changelog.outputs.clean_changelog }}
body: ${{ steps.changelog.outputs.clean_changelog }}

# Clean up OpenShift when PR closed, no conditions
cleanup-openshift:
name: Cleanup OpenShift
env:
name: ${{ github.event.repository.name }}-${{ github.event.number }}
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
- name: Remove OpenShift artifacts
run: |
oc login --token=${{ secrets.OC_TOKEN }} --server=${{ vars.OC_SERVER }}
oc project ${{ vars.OC_NAMESPACE }}
# If found, then remove
helm status ${{ env.name }} && helm uninstall --no-hooks ${{ env.name }} || \
echo "Not found: ${{ env.name }}"
27 changes: 17 additions & 10 deletions .github/workflows/pr-open.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,34 +64,41 @@ jobs:
${{ steps.changelog.outputs.clean_changelog }}
comment_tag: '# Current changelog'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

retags:
name: Test action
permissions:
packages: write
runs-on: ubuntu-22.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3

- uses: actions/checkout@v4
- name: Test Retags
id: broker
uses: ./
with:
broker_jwt: ${{ secrets.BROKER_JWT }}
provision_role_id: ${{ secrets.PROVISION_ROLE }}
project_name: client
app_name: app-client
project_name: nr-oracle
app_name: nr-oracle-service
environment: development

- name: Import Secrets
id: secrets
uses: hashicorp/vault-action@v2.7.3
uses: hashicorp/vault-action@v2.7.4
with:
url: https://vault-iit.apps.silver.devops.gov.bc.ca
token: ${{ steps.broker.outputs.vault_token }}
exportEnv: 'false'
secrets: |
apps/data/${{ secrets.SECRET_PATH}} sample | SAMPLE;
apps/data/${{ secrets.SECRET_PATH}} test | TEST;
- name: Checks
run: echo ${{ steps.secrets.outputs.SAMPLE }}
- name: Add the secret to OpenShift
shell: bash
run: |
oc login --token=${{ secrets.oc_token }} --server=${{ vars.oc_server }}
oc project ${{ vars.oc_namespace }}
cd charts/${{ github.event.repository.name }}
helm upgrade \
--set-string global.secrets.test=${{ steps.secrets.outputs.TEST }} \
--install --wait --atomic ${{ github.event.repository.name }}-${{ github.event.number }} \
--timeout 1m -f values.yaml .
66 changes: 13 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@
[![MIT License](https://img.shields.io/github/license/bcgov-nr/action-vault-broker-approle.svg)](/LICENSE)
[![Lifecycle](https://img.shields.io/badge/Lifecycle-Experimental-339999)](https://github.com/bcgov/repomountie/blob/master/doc/lifecycle-badges.md)

# Vault Approle Token extractor through Vault Broker API
# Vault App role Token extractor through Vault Broker API

This action acquires an approle token from vault through the Broker API. This allows the team to access and generate tokens through the github action pipeline.
This action acquires an approle token from vault through the Broker API. This allows the team to read secrets through the GitHub action pipeline.

This is useful in CI/CD pipelines where you need to access a secret, get a vault token or anything vault related.

This tool is currently based on the existing documentation provided by 1team.

# Usage
## Prerequisites
1. Discussion with 1team/DBA to start the onboarding process on vault.
2. Project setup is done for 3 envs development, test and production.
3. The provision_role_id is environment specific and should be stored in as secrets in the github repository.
4. The broker_jwt is global and NOT environment specific and should be stored in as secrets in the github repository.


## Usage

```yaml
- uses: bcgov-nr/action-vault-broker-approle@main
Expand Down Expand Up @@ -97,58 +104,11 @@ jobs:
token: ${{ steps.broker.outputs.vault_token }}
exportEnv: 'false'
secrets: |
apps/data/dev/super_secrets username | SECRET_USER;
apps/data/dev/super_secrets password | SECRET_PWD;
apps/data/${environment}/${project_name}/${app_name}/super_secrets username | SECRET_USER;
apps/data/${environment}/${project_name}/${app_name}/super_secrets password | SECRET_PWD;
```
# Example, Matrix Token Reads
Read from multiple environments.
Create or modify a GitHub workflow, like below. E.g. `./github/workflows/pr-open.yml`

```yaml
name: Pull Request
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
builds:
permissions:
packages: write
runs-on: ubuntu-22.04
strategy:
matrix:
env: [dev, test]
steps:
- uses: actions/checkout@v3
- name: Broker
id: broker
uses: bcgov-nr/action-vault-broker-approle@main
with:
broker_jwt: ${{ secrets.BROKER_JWT }}
provision_role_id: ${{ secrets.PROVISION_ROLE }}
project_name: super
app_name: app-super
environment: development
- name: Import Secrets
id: secrets
uses: hashicorp/vault-action@v2.5.0
with:
url: https://vault-iit.apps.silver.devops.gov.bc.ca
token: ${{ steps.broker.outputs.vault_token }}
exportEnv: 'false'
secrets: |
apps/data/${{ matrix.env }}/super_secrets username | SECRET_USER;
apps/data/${{ matrix.env }}/super_secrets password | SECRET_PWD;
```
# Output
Expand All @@ -158,4 +118,4 @@ See examples above.

<!-- # Acknowledgements

This Action is provided courtesty of the Forestry Suite of Applications, part of the Government of British Columbia. -->
This Action is provided courtesy of the FDS Team and Architecture Team, part of the Government of British Columbia. -->
118 changes: 2 additions & 116 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,122 +39,8 @@ inputs:
outputs:
vault_token:
description: The vault token acquired by the action
value: ${{ steps.broker.outputs.vault_token }}

runs:
using: composite
steps:
- uses: actions/checkout@v3
using: "node20"
main: "index.js"

# Process variables and inputs
- id: broker
name: Vault Broker
shell: bash
run: |
read_and_delete(){
if [[ -e $1 ]]; then
local FILE_CONTENT=$(cat $1)
rm -f $1
echo $FILE_CONTENT
else
echo "Cannot find file $1"
exit 19
fi
}
#Creating the intention template inline
TEMPLATE="{
\"event\": {
\"provider\": \"\",
\"reason\": \"Job triggered\",
\"url\": \"\"
},
\"actions\": [{
\"action\": \"package-provision\",
\"id\": \"provision\",
\"provision\": [\"approle/secret-id\"],
\"service\": {
\"name\": \"\",
\"project\": \"\",
\"environment\": \"\"
}
}],
\"user\": {
\"id\": \"\"
}
}"
# Read the intention file and replace the event url and the user id
PAYLOAD=$(echo ${TEMPLATE} | \
jq ".event.url=\"${GITHUB_SERVER_URL}${GITHUB_ACTION_PATH}\" | \
.user.id=\"${GITHUB_ACTOR}\" | \
.event.provider=\"${{ github.repository }}-github-action\" | \
.actions[0].service.name=\"${{ inputs.app_name }}\" | \
.actions[0].service.project=\"${{ inputs.project_name }}\" | \
.actions[0].service.environment=\"${{ inputs.environment }}\"")
# Open an intention to the broker
INTENTION=$(curl -o intention.txt -w "%{http_code}" -s -X POST ${{ inputs.broker_url }}/v1/intention/open \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${{ inputs.broker_jwt}}" \
--data-raw "${PAYLOAD}")
if [[ $INTENTION -eq 201 ]]; then
INTENTION=$(read_and_delete intention.txt)
else
echo "::error title=Intention,line=96::Intention cannot be opened with provided jwt token"
exit 19
fi
# Extract both the action and the intention token
INTENTION_TOKEN=$(echo "${INTENTION}" | jq -r '.token')
ACTION_TOKEN=$(echo "${INTENTION}" | jq -r '.actions.provision.token')
# With the action token in hand, provision a secret id for our app role
WRAPPED_DATA=$(curl -o wrappeddata.txt -w "%{http_code}" -s -X POST ${{ inputs.broker_url }}/v1/provision/approle/secret-id \
-H "x-broker-token: "${ACTION_TOKEN}"" \
-H "x-vault-role-id: "${{ inputs.provision_role_id }}"")
if [[ $WRAPPED_DATA -eq 201 ]]; then
WRAPPED_DATA=$(read_and_delete wrappeddata.txt)
else
echo "::error title=Approle Secret,line=113::Approle secret cannot be acquired, invalid token"
exit 19
fi
WRAPPED_TOKEN=$(echo ${WRAPPED_DATA} | jq -r '.wrap_info.token')
# Unwrap the token to get the secret id
SECRET_ID=$(curl -o secret.txt -w "%{http_code}" -s -X POST ${{ inputs.vault_addr }}/v1/sys/wrapping/unwrap \
-H "X-Vault-Token: ${WRAPPED_TOKEN}")
if [[ $SECRET_ID -eq 200 ]]; then
SECRET_ID=$(read_and_delete secret.txt)
SECRET_ID=$(echo ${SECRET_ID}|jq '.data.secret_id')
else
echo "::error title=Secret ID,line=127::Secret ID cannot be unwrapped"
exit 19
fi
# Log into vault using the app role url, this will give us back the vault token we need to read the secrets
LOGIN=$(curl -o login.txt -w "%{http_code}" -s -X POST ${{ inputs.vault_addr }}/v1/auth/vs_apps_approle/login \
--data-raw '{ "role_id": "'${{ inputs.provision_role_id }}'", "secret_id": '${SECRET_ID}' }' \
--header 'Content-Type: application/json')
if [[ $LOGIN -eq 200 ]]; then
LOGIN=$(read_and_delete login.txt)
LOGIN=$(echo ${LOGIN} | jq -r '.auth.client_token')
else
echo "::error title=Vault Login,line=139::Cannot log into vault due to provision error"
exit 19
fi
# Close the broker intention
curl -s -X POST ${{ inputs.broker_url }}/v1/intention/close \
-H 'Content-Type: application/json' \
-H "x-broker-token: ${INTENTION_TOKEN}"
# Forward the vault token to be consumed
echo vault_token=${LOGIN} >> $GITHUB_OUTPUT
- name: Checkout Action repo to pass tests
uses: actions/checkout@v3
17 changes: 17 additions & 0 deletions charts/action-vault-broker-approle/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v2
name: action-vault-broker-approle
description: A Helm chart for Kubernetes deployment.
icon: https://www.nicepng.com/png/detail/521-5211827_bc-icon-british-columbia-government-logo.png

type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.1"
48 changes: 48 additions & 0 deletions charts/action-vault-broker-approle/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "name.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "labels" -}}
helm.sh/chart: {{ include "name.chart" . }}
{{ include "selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "selectorLabels" -}}
app.kubernetes.io/name: {{ include "fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}


Loading

0 comments on commit 5ae6839

Please sign in to comment.