When building CI/CD pipelines, developers are responsible for managing the credentials used by these pipelines for authentication to external systems. This traditionally requires developers to take care of the lifecycle of the credentials, including secure storage and regular rotation of the credentials, which comes with repeated efforts and might be error-prone.
This blog post demonstrates how to authenticate to the SAP BTP, Cloud Foundry environment from a GitHub Actions workflow using GitHub-issued short-lived JSON Web Tokens (JWTs), thereby eliminating the need for manual secret management and enabling secure, efficient CI/CD workflows. In particular, it provides a step-by-step guide to configuring the SAP Cloud Identity Services and the SAP BTP, Cloud Foundry environment, along with a practical example showing how to deploy an application to the Cloud Foundry environment using a GitHub Actions workflow.
While the blog post gives an example in the context of GitHub and GitHub Actions, the concepts can be applied to other environments providing environment-issued JWTs to their workloads or pipelines as well.
In modern computing environments, workloads running in those environments can retrieve short-lived credentials representing the workload's identity (and conveying workload-related attributes) via means built into the environment without the need for a developer-managed secret. In the context of GitHub, this pattern enables GitHub Actions workflows to retrieve short-lived JWTs from GitHub’s OpenID Connect Provider containing information about the context in which the workflow is running (e.g., GitHub organization and repository).
With the recent enhancements of the SAP BTP, Cloud Foundry environment and the SAP Cloud Identity Services, the GitHub-issued JWTs can be used to authenticate workflows when deploying to Cloud Foundry, eliminating the need for providing (and managing) a password.
The setup of the main components and their interactions is as follows (see also diagram below):
Note: In this blog post, github.example.com refers to a fictional GitHub Enterprise server. Please adjust these references to match your own GitHub server or CI/CD environment.
To follow the steps provided in this blog post, you need to have access to the SAP BTP, Cloud Foundry environment (see: Getting Started in the Cloud Foundry Environment | SAP Help Portal) and administrative access to a tenant in SAP Cloud Identity Services (see: Get Your Tenant | SAP Help Portal). Furthermore, you need to be able to set up a GitHub repository that can run GitHub Actions workflows.
Open the admin console of your SAP Cloud Identity Services tenant in the browser.
When defining the attributes of the (helper) user for GitHub Actions workflows, consider this proposal:
Following this proposal, create a user that represents the GitHub Actions workflows running in a given GitHub organization and repository as described below:
Go to 'Users & Authorizations' -> 'User Management' -> Click '+ Add', and configure the required parameters as:
Go to 'Users & Authorizations' → 'Groups'
On the newly created group, under 'user members' click '+ Add' and add the previously created user to this group.
Go to 'Identity Providers' → 'Corporate Identity Providers' → Click '+ Create'
Create a new Identity Provider with Display Name <githubServerDomain> (e.g., github.example.com) and type 'OpenID Connect Compliant'.
Do the following steps on the 'list items' belonging to the newly created corporate identity provider.
Go to the list item 'Trust' → 'OpenID Connect Configuration' and provide the discovery URL of the OpenID Connect Provider of the GitHub environment. The discovery URL is specific to your GitHub environment:
After providing the discovery URL, click 'Load' and 'Save'.
Go to the list item 'Trust' → 'Enriched Token Claims' and add the following claim-value pair:
This enables the mapping of the incoming GitHub-issued JWT using the repository claim provided in the token to a user with an email address with the pattern repo/<orgName>/<repoName>@<emailDomain>.
For additional information see:
Go to the list item 'Single Sign On' → 'Identity Federation'.
Go to the tile 'Applications & Resources' → 'Applications'.
Select the application named 'SAP Business Technology Platform' (representing the SAP BTP, Cloud Foundry environment in your tenant). Note: If the application 'SAP Business Technology Platform' does not show up in the list of applications, you need to establish trust between the BTP Global Account and your SAP Cloud Identity Services tenant first (see step 2 below) and then complete this step.
Go to the list item 'Trust' → 'Conditional Authentication' and click 'Add Rule', and add a new rule with:
Finally, click 'OK' on the new rule, and click 'Save' on 'Conditional Authentication' (top right corner).
Open the SAP BTP cockpit in the browser.
In the following it is assumed that you already have a global account and subaccount on SAP Business Technology Platform (SAP BTP), as well as access to the SAP BTP, Cloud Foundry environment, such that an authorized user can successfully deploy an application. If this is not the case, please see the documentation at: SAP Business Technology Platform (SAP BTP) | SAP Help Portal and Getting Started with an Enterprise Account in the Cloud Foundry Environment | SAP Help Portal.
Establish trust between your global account and your SAP Cloud Identity Services tenant as 'Custom Identity Provider for Platform Users' (see Establish Trust and Federation of Custom Identity Providers for Platform Users).
Note: Remember to complete step 1.4, if not yet done.
Select a subaccount and navigate to 'Cloud Foundry->Spaces'. Then, select the space that the GitHub Actions workflow should have access to (create a new space first, if required).
Add the (helper) user as member to the space with role 'Space Developer':
Note: The role 'Space Developer' enables the user to push to this space.
For pushing an application using a GitHub Actions workflow, you need a repository (e.g., myOrg/myRepo) on a GitHub server (e.g. github.example.com) which contains a GitHub Actions workflow that fetches a short-lived JWT from GitHub and uses this token for authentication in the login to the SAP BTP, Cloud Foundry environment.
A GitHub repository with a simple 'Hello World Sample' may look as described below. Note: Make sure that the GitHub repository has GitHub Actions enabled and make sure that the configuration of GitHub, SAP Cloud Identity Services, and SAP BTP, Cloud Foundry environment fit together.
The 'Hello World Sample' GitHub repository may have the following structure and contain the following files:
<repository-root-directory>/
├── manifest.yml
├── .github/
│ └── workflows/
│ └── deploy.yml
└── resources/
└── hello.jsonThe manifest.yml defines an application manifest for deploying to the Cloud Foundry environment. The manifest given below, will deploy a staticfile_buildbpack serving the hello.json file.
manifest.yml
applications:
- name: github-cf-access
disk_quota: 1G
instances: 1
memory: 256M
random-route: true
path:
./resources
buildpacks:
- staticfile_buildpackThe resources/hello.json file contains some sample content to deploy.
resources/hello.json
{
"hello": "from GitHub Actions"
}
Finally, the deploy.yml contains the definition of the GitHub Actions workflow that pushes the application to the SAP BTP, Cloud Foundry environment.
Notes:
Before running the script below, review it, and adjust the GitHub Actions runner, if needed. Note: There is no need to adjust the inputs, as they actual values can be provided when running the workflow via the UI.
.github/workflows/deploy.yml
name: Deploy
on:
workflow_dispatch:
inputs:
cfApiEndpointUrl:
description: 'Cloud Foundry environment API endpoint'
default: '<e.g., https://api.cf.eu10.hana.ondemand.com>'
required: true
type: string
cfOrg:
description: 'CF org name'
default: '<e.g., myCfOrg>'
required: true
cfSpace:
description: 'CF space name'
default: '<e.g., myCfSpace>'
required: true
userOrigin:
description: 'The "origin-identifier" of your custom platform IdP (see origin of the space user)'
default: '<e.g., myTenant-platform>'
required: true
type: string
tenantIssuerUri:
description: 'Issuer URI of your SAP Cloud Identity Services tenant'
default: '<e.g., https://myTenant.accounts.ondemand.com>'
required: true
jobs:
deploy:
runs-on: [ ubuntu-latest ]
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
steps:
- name: Show provided parameters
run: |
echo "Provided parameters:"
echo '${{ toJson(inputs) }}' | jq -r 'to_entries | .[] | "- \(.key): \(.value)"'
- name: Check out repository code
uses: actions/checkout@v4
- name: Download CF CLI
run: |
cf_version="8.12.0"
mkdir .cfcli
curl -L "https://github.com/cloudfoundry/cli/releases/download/v${cf_version}/cf8-cli_${cf_version}_linux_x86-64.tgz" | tar -zvx -C .cfcli
echo "$(pwd)/.cfcli" >> "$GITHUB_PATH"
- name: Get short-lived GitHub-issued JWT
id: get-github-jwt
run: |
githubJwt=$(curl -s -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" -H "Accept: application/json; api-version=2.0" -H "Content-Type: application/json" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=${{inputs.tenantIssuerUri}}" | jq -r '.value')
echo $githubJwt | jq -R 'split(".") | .[0],.[1] | @base64d | fromjson'
echo "githubJwt=$githubJwt" >> $GITHUB_OUTPUT
- name: Set Cloud Foundry API
run: |
cf api ${{inputs.cfApiEndpointUrl}}
- name: Login to Cloud Foundry environment
run: |
cf auth --assertion ${{steps.get-github-jwt.outputs.githubJwt}} --origin ${{inputs.userOrigin}}
- name: Target Cloud Foundry org and space
run: |
cf target -o '${{inputs.cfOrg}}' -s '${{inputs.cfSpace}}'
- name: Deploy to Cloud Foundry environment
run: |
cf push --strategy rolling
- name: Logout from Cloud Foundry environment
if: always()
run: |
cf logout
In order to run the GitHub Actions workflow go to 'Actions' -> 'Deploy' and click 'Run workflow' and override the provided default values in the 'run workflow UI' with your specific parameters. Finally, click the green 'Run workflow' button.
Once the workflow has been successfully executed:
By using GitHub-issued, short-lived JWTs and integrating GitHub Actions workflows with SAP Cloud Identity Services and the SAP BTP, Cloud Foundry environment, developers can enhance security, simplify automation, and streamline CI/CD workflows. Especially, this approach eliminates the need for managing long-lived credentials and reduces operational overhead.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 36 | |
| 33 | |
| 29 | |
| 27 | |
| 26 | |
| 26 | |
| 25 | |
| 23 | |
| 23 | |
| 23 |