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

fix: Make tagging optional #92

Merged
merged 4 commits into from
Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ The session will have the name "GitHubActions" and be tagged with the following

_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 '*'._

The action will use session tagging by default during role assumption. You can skip this session tagging by providing `role-skip-session-tagging` as true in the action's inputs:

```yaml
uses: aws-actions/configure-aws-credentials@v1
with:
role-skip-session-tagging: true
```

## Self-Hosted Runners

If you run your GitHub Actions in a [self-hosted runner](https://help.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) that already has access to AWS credentials, such as an EC2 instance, then you do not need to provide IAM user access key credentials to this action.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ inputs:
role-external-id:
description: 'The external ID of the role to assume'
required: false
role-skip-session-tagging:
description: 'Skip session tagging during role assumption'
required: false
outputs:
aws-account-id:
description: 'The AWS account ID for the provided credentials'
Expand Down
28 changes: 17 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async function assumeRole(params) {
roleDurationSeconds,
roleSessionName,
region,
roleSkipSessionTagging
} = params;
assert(
[sourceAccountId, roleToAssume, roleDurationSeconds, roleSessionName, region].every(isDefined),
Expand All @@ -41,20 +42,23 @@ async function assumeRole(params) {
// Supports only 'aws' partition. Customers in other partitions ('aws-cn') will need to provide full ARN
roleArn = `arn:aws:iam::${sourceAccountId}:role/${roleArn}`;
}
const tagArray = [
{Key: 'GitHub', Value: 'Actions'},
{Key: 'Repository', Value: GITHUB_REPOSITORY},
{Key: 'Workflow', Value: sanitizeGithubWorkflowName(GITHUB_WORKFLOW)},
{Key: 'Action', Value: GITHUB_ACTION},
{Key: 'Actor', Value: sanitizeGithubActor(GITHUB_ACTOR)},
{Key: 'Branch', Value: GITHUB_REF},
{Key: 'Commit', Value: GITHUB_SHA},
];

const roleSessionTags = roleSkipSessionTagging ? undefined : tagArray;

const assumeRoleRequest = {
RoleArn: roleArn,
RoleSessionName: roleSessionName,
DurationSeconds: roleDurationSeconds,
Tags: [
{Key: 'GitHub', Value: 'Actions'},
{Key: 'Repository', Value: GITHUB_REPOSITORY},
{Key: 'Workflow', Value: sanitizeGithubWorkflowName(GITHUB_WORKFLOW)},
{Key: 'Action', Value: GITHUB_ACTION},
{Key: 'Actor', Value: sanitizeGithubActor(GITHUB_ACTOR)},
{Key: 'Branch', Value: GITHUB_REF},
{Key: 'Commit', Value: GITHUB_SHA},
]
Tags: roleSessionTags
};

if (roleExternalId) {
Expand Down Expand Up @@ -196,7 +200,8 @@ async function run() {
const roleExternalId = core.getInput('role-external-id', { required: false });
const roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || MAX_ACTION_RUNTIME;
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;

const roleSkipSessionTagging = core.getInput('role-skip-session-tagging', { required: false });

if (!region.match(REGION_REGEX)) {
throw new Error(`Region is not valid: ${region}`);
}
Expand Down Expand Up @@ -233,7 +238,8 @@ async function run() {
roleToAssume,
roleExternalId,
roleDurationSeconds,
roleSessionName
roleSessionName,
roleSkipSessionTagging
});
exportCredentials(roleCredentials);
await validateCredentials(roleCredentials.accessKeyId);
Expand Down
71 changes: 71 additions & 0 deletions index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,19 @@ describe('Configure AWS Credentials', () => {
expect(core.setFailed).toHaveBeenCalledWith('Region is not valid: $AWS_REGION');
});

test('throws error if access key id exists but missing secret access key', async () => {
process.env.SHOW_STACK_TRACE = 'false';
const inputsWIthoutSecretKey = {...ASSUME_ROLE_INPUTS}
inputsWIthoutSecretKey["aws-secret-access-key"] = undefined
core.getInput = jest
.fn()
.mockImplementation(mockGetInput(inputsWIthoutSecretKey));

await run();
expect(core.setFailed).toHaveBeenCalledWith("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");

});

test('can opt out of masking account ID', async () => {
const mockInputs = {...CREDS_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'false'};
core.getInput = jest
Expand Down Expand Up @@ -523,4 +536,62 @@ describe('Configure AWS Credentials', () => {
})
});

test('skip tagging provided as true', async () => {
core.getInput = jest
.fn()
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': true}));

await run();
expect(mockStsAssumeRole).toHaveBeenCalledWith({
RoleArn: ROLE_ARN,
RoleSessionName: 'GitHubActions',
DurationSeconds: 21600,
Tags: undefined
})
});

test('skip tagging provided as false', async () => {
core.getInput = jest
.fn()
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': false}));

await run();
expect(mockStsAssumeRole).toHaveBeenCalledWith({
RoleArn: ROLE_ARN,
RoleSessionName: 'GitHubActions',
DurationSeconds: 21600,
Tags: [
{Key: 'GitHub', Value: 'Actions'},
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
]
})
});

test('skip tagging not provided', async () => {
core.getInput = jest
.fn()
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS}));

await run();
expect(mockStsAssumeRole).toHaveBeenCalledWith({
RoleArn: ROLE_ARN,
RoleSessionName: 'GitHubActions',
DurationSeconds: 21600,
Tags: [
{Key: 'GitHub', Value: 'Actions'},
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
]
})
});

});