mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-09-04 06:15:07 +09:00
fix: sanitize AWS session tags (#20)
* Sanitize github actor tag * Add some tests * Sanitize Github actions workflow name * Change sanitization character to an asterisk * Update readme about assuming a role * Tidy up assume role readme entry more * Align sanitize spelling to use -ize * typo: environement -> environment
This commit is contained in:
committed by
GitHub
parent
c69f29a23c
commit
4faf8cd19a
@@ -26,6 +26,39 @@ We recommend following [Amazon IAM best practices](https://docs.aws.amazon.com/I
|
|||||||
* [Rotate the credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials) used in GitHub Actions workflows regularly.
|
* [Rotate the credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials) used in GitHub Actions workflows regularly.
|
||||||
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
|
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
|
||||||
|
|
||||||
|
## Assuming a role
|
||||||
|
If you would like to use the credentials you provide to this action to assume a role, you can do so by specifying the role ARN in `role-to-assume`.
|
||||||
|
The role credentials will then be output instead of the ones you have provided.
|
||||||
|
The default session duration is 6 hours, but if you would like to adjust this you can pass a duration to `role-duration-seconds`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
|
with:
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/role-to-assume
|
||||||
|
role-duration-seconds: 1200
|
||||||
|
```
|
||||||
|
|
||||||
|
### Session tagging
|
||||||
|
The session will have the name "GitHubActions" and be tagged with the following tags:
|
||||||
|
(`GITHUB_` environment variable definitions can be [found here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
|
||||||
|
|
||||||
|
| Key | Value|
|
||||||
|
| --- | --- |
|
||||||
|
| GitHub | "Actions" |
|
||||||
|
| Repository | GITHUB_REPOSITORY |
|
||||||
|
| Workflow | GITHUB_WORKFLOW |
|
||||||
|
| Action | GITHUB_ACTION |
|
||||||
|
| Actor | GITHUB_ACTOR |
|
||||||
|
| Branch | GITHUB_REF |
|
||||||
|
| Commit | GITHUB_SHA |
|
||||||
|
|
||||||
|
_Note: all tag values must conform to [the requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html). Particularly, `GITHUB_WORKFLOW` will be truncated if it's too long. If `GITHUB_ACTOR` or `GITHUB_WORKFLOW` contain invalid charcters, the characters will be replaced with an '*'._
|
||||||
|
|
||||||
## License Summary
|
## License Summary
|
||||||
|
|
||||||
This code is made available under the MIT license.
|
This code is made available under the MIT license.
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const util = require('util');
|
|||||||
// That seems like a reasonable default to use if no role duration is defined.
|
// That seems like a reasonable default to use if no role duration is defined.
|
||||||
const MAX_ACTION_RUNTIME = 6 * 3600;
|
const MAX_ACTION_RUNTIME = 6 * 3600;
|
||||||
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
||||||
|
const MAX_TAG_VALUE_LENGTH = 256;
|
||||||
|
const SANITIZATION_CHARACTER = '*'
|
||||||
|
|
||||||
async function assumeRole(params) {
|
async function assumeRole(params) {
|
||||||
// Assume a role to get short-lived credentials using longer-lived credentials.
|
// Assume a role to get short-lived credentials using longer-lived credentials.
|
||||||
@@ -36,9 +38,9 @@ async function assumeRole(params) {
|
|||||||
Tags: [
|
Tags: [
|
||||||
{Key: 'GitHub', Value: 'Actions'},
|
{Key: 'GitHub', Value: 'Actions'},
|
||||||
{Key: 'Repository', Value: GITHUB_REPOSITORY},
|
{Key: 'Repository', Value: GITHUB_REPOSITORY},
|
||||||
{Key: 'Workflow', Value: GITHUB_WORKFLOW},
|
{Key: 'Workflow', Value: sanitizeGithubWorkflowName(GITHUB_WORKFLOW)},
|
||||||
{Key: 'Action', Value: GITHUB_ACTION},
|
{Key: 'Action', Value: GITHUB_ACTION},
|
||||||
{Key: 'Actor', Value: GITHUB_ACTOR},
|
{Key: 'Actor', Value: sanitizeGithubActor(GITHUB_ACTOR)},
|
||||||
{Key: 'Branch', Value: GITHUB_REF},
|
{Key: 'Branch', Value: GITHUB_REF},
|
||||||
{Key: 'Commit', Value: GITHUB_SHA},
|
{Key: 'Commit', Value: GITHUB_SHA},
|
||||||
]
|
]
|
||||||
@@ -53,6 +55,21 @@ async function assumeRole(params) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanitizeGithubActor(actor) {
|
||||||
|
// In some circumstances the actor may contain square brackets. For example, if they're a bot ('[bot]')
|
||||||
|
// Square brackets are not allowed in AWS session tags
|
||||||
|
return actor.replace(/\[|\]/g, SANITIZATION_CHARACTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeGithubWorkflowName(name) {
|
||||||
|
// Workflow names can be almost any valid UTF-8 string, but tags are more restrictive.
|
||||||
|
// This replaces anything not conforming to the tag restrictions by inverting the regular expression.
|
||||||
|
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
|
||||||
|
const nameWithoutSpecialCharacters = name.replace(/[^\p{L}\p{Z}\p{N}_.:/=+-@]/gu, SANITIZATION_CHARACTER);
|
||||||
|
const nameTruncated = nameWithoutSpecialCharacters.slice(0, MAX_TAG_VALUE_LENGTH)
|
||||||
|
return nameTruncated
|
||||||
|
}
|
||||||
|
|
||||||
function exportCredentials(params){
|
function exportCredentials(params){
|
||||||
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
|
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
|
||||||
// Setting the credentials as secrets masks them in Github Actions logs
|
// Setting the credentials as secrets masks them in Github Actions logs
|
||||||
|
|||||||
+30
-3
@@ -19,10 +19,11 @@ const ENVIRONMENT_VARIABLE_OVERRIDES = {
|
|||||||
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
||||||
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
||||||
GITHUB_ACTION: 'MY-ACTION-NAME',
|
GITHUB_ACTION: 'MY-ACTION-NAME',
|
||||||
GITHUB_ACTOR: 'MY-USERNAME',
|
GITHUB_ACTOR: 'MY-USERNAME[bot]',
|
||||||
GITHUB_REF: 'MY-BRANCH',
|
GITHUB_REF: 'MY-BRANCH',
|
||||||
GITHUB_SHA: 'MY-COMMIT-ID',
|
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||||
};
|
};
|
||||||
|
const GITHUB_ACTOR_SANITIZED = 'MY-USERNAME*bot*'
|
||||||
|
|
||||||
function mockGetInput(requestResponse) {
|
function mockGetInput(requestResponse) {
|
||||||
return function (name, options) { // eslint-disable-line no-unused-vars
|
return function (name, options) { // eslint-disable-line no-unused-vars
|
||||||
@@ -208,7 +209,7 @@ describe('Configure AWS Credentials', () => {
|
|||||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||||
{Key: 'Actor', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTOR},
|
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||||
]
|
]
|
||||||
@@ -230,7 +231,33 @@ describe('Configure AWS Credentials', () => {
|
|||||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||||
{Key: 'Actor', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTOR},
|
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||||
|
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||||
|
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
test('workflow name sanitized in role assumption tags', async () => {
|
||||||
|
core.getInput = jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
process.env = {...process.env, GITHUB_WORKFLOW: 'Workflow!"#$%&\'()*+, -./:;<=>?@[]^_`{|}~🙂💥🍌1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZai9D2AN2RlWCxtMqChNtxuxjqeqhoQZo0oaq39sjcRZgAAAAAAA'};
|
||||||
|
|
||||||
|
const sanitizedWorkflowName = 'Workflow**********+, -./:;<=>?@***_********1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZa'
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||||
|
RoleArn: ROLE_NAME,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 6 * 3600,
|
||||||
|
Tags: [
|
||||||
|
{Key: 'GitHub', Value: 'Actions'},
|
||||||
|
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||||
|
{Key: 'Workflow', Value: sanitizedWorkflowName},
|
||||||
|
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||||
|
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user