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

Enforce permissions for releases and patches #25

Open
wants to merge 1 commit into
base: safesecret
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/patch-backend-app-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -37,6 +41,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- uses: actions/create-github-app-token@v1
id: app-token
name: Generate app token
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/patch-backend-lib-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -22,6 +26,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- name: Validate branch name format
run: |
if [[ ! "${{ inputs.branchRef }}" =~ ^release-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/patch-base-docker-image-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -29,6 +33,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- uses: actions/create-github-app-token@v1
id: app-token
name: Generate app token
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/patch-frontend-app-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -37,6 +41,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/release-backend-app-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -40,6 +44,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- uses: actions/create-github-app-token@v1
id: app-token
name: Generate app token
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/release-backend-lib-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -22,6 +26,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- name: Validate Version Type
run: |
if [[ ! "${{ inputs.versionType }}" =~ ^(major|minor)$ ]]; then
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/release-base-docker-image-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ on:
required: false
default: 'release'
type: string
permission:
required: false
default: 'maintain' # "pull" or "triage" or "push" or "maintain" or "admin"
type: string
secrets:
VERSIONBUMP_GHAPP_PRIVATE_KEY:
required: true
Expand All @@ -32,6 +36,32 @@ jobs:
environment:
name: ${{ inputs.environment }}
steps:
# don't allow to disable this check, and for security only succeed if everything goes perfectly and outputs "true"
# TODO deduplicate this code when github actions allows to easily share a script used
# by reusable workflows. Currently only the workflow file is checked out at the caller
# There are no good workarounds to checkout a companion file (script or composite action)
- name: Check Actor Permission
env:
# Need to properly pass permission all the way down to jq as data to avoid script injections
PERMISSION: ${{ inputs.permission }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "checking permission=$PERMISSION on repo=$GITHUB_REPOSITORY for user=$GITHUB_ACTOR"
# no need to escape GITHUB_REPOSITORY and GITHUB_ACTOR because github
# names can only contain ASCII letters, digits, and the characters ., # -, and _.
# permission: legacy, is actually a role (one per user) and doesn't
# have "maintain" role, only ["none", "read", "write", "admin"]
# role_name: one per user, new standard roles, custom roles, "" and
# "push" and "pull" instead of "none" and "read" and "write": "",
# "read", "triage", "write", "maintain", "admin" and also non
# standard custom roles
# user.permissions: boolean status only for each standard permissions "pull", "triage", "push", "maintain", "admin"
# So the best for now is to use user.permissions I think.
# Not using gh --jq gojq because we can't use variables with it and also it automatically removes quotes from strings which could be an attack vector
# the gh api returns a JSON boolean so jq can only output true or false without quotes.
allowed=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$GITHUB_ACTOR/permission" | jq --arg PERMISSION "$PERMISSION" '.user.permissions[$PERMISSION]')
[[ "$allowed" == "true" ]] || exit 1

- uses: actions/create-github-app-token@v1
id: app-token
name: Generate app token
Expand Down
Loading