Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Use ghrawel to deploy an AWS API Gateway RestAPI capable of returning GitHub App installation access tokens and use AWS IAM to control access to this API.
gh
raw
el will aim to provide components that help integrate GitHub and AWS using primarily AWS CDK and minimal application code.
Use this to deploy an AWS API Gateway RestAPI capable of returning GitHub App installation access tokens and use AWS IAM to control access to this API.
The private key belonging to a GitHub App can be used to create installation access tokens that only contains a selection of the permissions that the GitHub App has been granted and also for a limited number of repositories that the GitHub App has been installed in. This installation access token has a maximum lifetime of an hour and can revoke itself.
Use ghrawel to control access to sensitive GitHub API credentials within an AWS and GitHub Actions environments, when such requirements exist.
Creating PATs or GitHub App Private keys is easy and they are simple to use whether stored in AWS or as a GitHub secret. Using this solution introduces new components and complexity that has to be managed and such a thing is not always worth it.
An application or a GitHub Actions workflow with access to AWS IAM Credentials initiates the sequence of events by signing a HTTP request with those credentials.
sequenceDiagram
autonumber
participant HTTP as HTTP Request
participant App as Application/GHA
note over App: Has AWS IAM Credentials
participant API as API Gateway
participant Authorizer as IAM Authorizer
participant Lambda as Lambda
participant GitHub as GitHub API
App->>HTTP: Create and Sign
App->>API: Send Request
API->>Authorizer: Authorization
alt if not authorized
API-->>App: 401
end
API->>Lambda: Forward Authorized Request
Lambda->>Lambda: Additional validation
alt if validation fails
Lambda-->>API: 400 Bad Request
API-->>App: 400 Bad Request
end
Lambda->>GitHub: Request Token
Lambda->>API: Token Response
API->>App: Token Response
App->>GitHub: Uses token
[!NOTE] The machine deploying will require docker as catnekaise/ghrawel-tokenprovider-lambda-go will be built to run in the lambda function. See Dockerfile and application for more.
[!NOTE] This guide assumes some familiarity with AWS CDK.
This test setup can be tested with a GitHub App that only has access to a single test repository in GitHub and this repository (and app) can be on your user instead of in your organization.
Assuming that you make 10 000
requests using this test setup, the cost of lambda and cloudwatch is covered under the free tier. The cost of the API Gateway RestApi will be between free and 0.035$ depending on how old the AWS Account is. Depending on your AWS Environment there could be charges for CloudTrail, Config, other tools and any custom automations that might create additional resources based on the resources deployed. It's best to test this is a sandbox account.
There are no charges related to GitHub.
For our testing purposes we need to create a test repository
and a GitHub App
. The app being created shall be considered a test app and should not be granted unnecessary permissions or installed anywhere but in repositories used for testing this. The link above provides additional information about working with GitHub Apps.
Create a new empty repository in your organization or on your user which can be used for testing.
Create a GitHub App in the same organization or user and grant read & write
on the repository level permissions contents
and issues
.
Identifying and authorizing users
as this app is not for usersHomepage URL
as its a required fieldactive
under webhook as no webhook shall be configured for this use-caseonly on this account
selectedNote down the id
of the GitHub App as it will be used later.
Create a new private key for this GitHub App and keep it around as it will be used later.
Install the GitHub App in the single test repository that was created further above
[!NOTE] CDK for .NET can also be used to test this but examples below has to be translated.
cdk init --language typescript
npm install -s @catnekaise/ghrawel
defaultAppId
in the example below to match your newly created GitHub App.import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import { ManagedGitHubApps, GitHubAppSecretsStorage, TokenProviderApi, PermissionLevel } from '@catnekaise/ghrawel';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'TokenProviderStack');
const apps = new ManagedGitHubApps(stack, 'Apps', {
// Change this value
defaultAppId: 1234,
storage: GitHubAppSecretsStorage.PARAMETER_STORE,
});
const tokenProviderApi = new TokenProviderApi(stack, 'TokenProviderApi', {
apps,
});
const provider = tokenProviderApi.newTokenProvider('example-provider', {
permissions: {
contents: PermissionLevel.READ,
issues: PermissionLevel.WRITE,
},
});
When the stack has completed its deployment a secure string parameter will have been initialized at path /catnekaise/github-apps/default
in Systems Manager Parameter Store
with value placeholder
. Go there and enter the full text value of GitHub App Private Key created earlier inside the value field of this parameter.
The easiest way to see that this is now working and to request an access token is to head over to the API Gateway in the AWS Console. Examples on how to request a token with cURL or GitHub Actions can be seen further down, and more in additional usage docs.
GET
method created and select it.Test
tab.owner
.repo
.In this example cURL is used to create an issue in your test repository. Either use this example or use a tool of your choice with the same input. After Successfully performing this test there should be a new issue in your test repository.
#!/usr/bin/env bash
OWNER="Enter name of organization or user"
REPO="Enter name of repo"
TOKEN="Enter token"
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Token ${TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${OWNER}/${REPO}/issues" \
-d '{"title":"Testing using app installation token","body":"Testing using app installation token"}'
If a GitHub App was created with the example permissions further above and the token provider was configured the with access read
or the permission contents
, then the token shall be able to read contents in the repository but not write content to the repository.
The following cURL command will fetch the contents of README.md
and print out body the full JSON body and decode the value of content
in the body.
#!/usr/bin/env bash
OWNER="Enter name of organization or user"
REPO="Enter name of repo"
MY_TOKEN="Enter token Value"
README_MD=$(curl -s -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Token ${MY_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${OWNER}/${REPO}/contents/README.md")
echo "$README_MD"
echo "$README_MD" | jq -r '.content' | base64 -d
Again, assuming setup have been done as example above, the following cURL command shall fail to create the file TEST.md
in the test repositories default branch.
#!/usr/bin/env bash
OWNER="Enter name of organization or user"
REPO="Enter name of repo"
MTOKEN="Enter token Value"
curl --fail-with-body -L \
-X PUT \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Token ${TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${OWNER}/${REPO}/contents/TEST.md" \
-d '{"message":"my commit message","content":"SGVsbG8gZnJvbSBjYXRuZWthaXNlCg=="}'
Update the stack by creating a second token provider that is granted write
for the contents
permission and re-deploy the stack.
tokenProviderApi.newTokenProvider('example-provider-2', {
permissions: {
contents: PermissionLevel.WRITE,
},
});
After deployment, refresh the page in the web browser where you previously generated a token and find the second GET
method available under the path /x/example-provider-2/{owner}/{repo}
. Use this token provider to generate a new token for the same repository and re-run the example below. After successfully performing this test there should be a file named TEST.md
in the root of your test repository on the default branch.
#!/usr/bin/env bash
OWNER="Enter name of organization or user"
REPO="Enter name of repo"
MY_TOKEN="Enter token Value"
curl --fail-with-body -L \
-X PUT \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Token ${MY_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${OWNER}/${REPO}/contents/TEST.md" \
-d '{"message":"my commit message","content":"SGVsbG8gZnJvbSBjYXRuZWthaXNlCg=="}'
Either clean up now or test this out some more using cURL
or GitHub Actions
before cleaning up. The steps to remove everything that was created.
In GitHub, find the GitHub App and either uninstall, suspend or delete this GitHub App
In AWS Console go to CloudFormation and find the Stack that was created and delete it.
Continue reading here for more detailed examples.
declare const principal: iam.IPrincipal;
const role = new iam.Role(stack, 'Role', {
assumedBy: principal,
});
const provider = tokenProviderApi.newTokenProvider('example-provider', {
permissions: {
contents: PermissionLevel.READ,
issues: PermissionLevel.WRITE,
},
});
provider.grantExecute(role);
This example shows how to use cURL to sign the request with the AWS IAM credentials. The example assumes the existence of AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
and AWS_SESSION_TOKEN
in the environment.
For more usage examples, check out usage docs.
AWS_REGION="eu-west-1"
BASE_URL="https://abcd1234.execute-api.${AWS_REGION}.amazonaws.com/dev"
PROVIDER="example-provider"
RESPONSE=$(curl "${BASE_URL}/x/${PROVIDER}/catnekaise/example-repo" \
--user "${AWS_ACCESS_KEY_ID}":"${AWS_SECRET_ACCESS_KEY}" \
-H "x-amz-security-token: ${AWS_SESSION_TOKEN}" \
--aws-sigv4 "aws:amz:${AWS_REGION}:execute-api")
TOKEN=$(echo "$RESPONSE" | jq -r '.token')
## Use Token...
For more usage examples in GitHub Actions and a re-usable action, check out GitHub Actions usage docs.
on:
workflow_dispatch:
jobs:
job1:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: "Authenticate"
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: "eu-west-1"
role-to-assume: "arn:aws:iam::111111111111:role/role-name"
- name: "Get Token"
uses: catnekaise/ghrawel-token@v1
id: token
with:
base-url: "https://abc123d4.execute-api.eu-west-1.amazonaws.com/dev"
provider-name: "example-provider"
aws-region: "eu-west-1"
- name: "Use Token"
env:
TOKEN: "${{ steps.token.outputs.token }}"
run: |
echo "Utilize the token"
Read more in infrastructure and application.
import { ManagedGitHubApps, TokenProviderApi, TokenProviderLambdaCode, ApplicationArchitecture } from '@catnekaise/ghrawel';
const managedLambda = new lambda.Function(stack, 'Function', {
code: TokenProviderLambdaCode.dotnet({
architecture: ApplicationArchitecture.ARM64,
repository: 'https://github.com/catnekaise/example-fork.git',
checkout: 'main',
}),
handler: 'bootstrap',
runtime: lambda.Runtime.DOTNET_8,
// Add name, vpc, etc
});
const managedApi = new apigateway.RestApi(stack, 'TokenProviderApi', {
// Add domain, vpc, etc
});
const apps = new ManagedGitHubApps(stack, 'Apps', {
defaultAppId: 1234,
storage: GitHubAppSecretsStorage.PARAMETER_STORE,
additionalApps: [
GitHubApp.create('another-app', 1111),
GitHubApp.create('yet-another-app', 2222),
],
});
const tokenProviderApi = new TokenProviderApi(stack, 'TokenProviderApi', {
apps,
lambda: managedLambda,
api: managedApi,
});
tokenProviderApi.newTokenProvider('example-provider', {
permissions: {
contents: PermissionLevel.READ,
},
});
Here're some additional documentation on various topics:
Please open issues if having general feedback or if getting stuck on something that was not covered by any documentation. PR's are welcome for bugfixes. For any feature additions, please open an issue for discussion first.
FAQs
Use ghrawel to deploy an AWS API Gateway RestAPI capable of returning GitHub App installation access tokens and use AWS IAM to control access to this API.
We found that catnekaise.ghrawel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.