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

Define IAM Permissions Boundary for Project #7144

Merged
merged 41 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6f0c6c7
fix(amplify-provider-awscloudformation): fix tests failing due to sys…
rajrajhans Apr 10, 2021
7228ddb
feat: s3 sse by default
edwardfoyle Apr 7, 2021
707a370
chore: fix init push issue
edwardfoyle Apr 8, 2021
d960307
chore: cleanup
edwardfoyle Apr 8, 2021
aab7976
test: whole lotta tests
edwardfoyle Apr 9, 2021
61659bc
test: update nondeterministic test
edwardfoyle Apr 12, 2021
733301d
fix: serialize modifiers and improve test error handling
edwardfoyle Apr 13, 2021
921038e
fix: add parameterization to ResourceModifier
edwardfoyle Apr 14, 2021
a71caab
fix: add type to sig
edwardfoyle Apr 14, 2021
2a59d5a
test: update test with new modifier structure
edwardfoyle Apr 14, 2021
7561636
test: fix test
edwardfoyle Apr 14, 2021
2fe4187
feat: add permission boundary to IAM roles
edwardfoyle Apr 13, 2021
abba2a2
fix: update iam role modifier
edwardfoyle Apr 14, 2021
dd28cf3
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle Apr 20, 2021
838f7dc
test: add e2e test for perm bound
edwardfoyle Apr 20, 2021
08d81a5
test: add unit tests for perm bound modifier
edwardfoyle Apr 20, 2021
da7a4e7
fix: fix regex
edwardfoyle Apr 21, 2021
f51ebdd
feat: switch to env-specific config
edwardfoyle Apr 29, 2021
afbc857
chore: dumping env perm bound changes
edwardfoyle Apr 30, 2021
70f85c4
feat: fixup env-specific config and add headless support
edwardfoyle May 5, 2021
f5fa7e2
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle May 5, 2021
0e09990
chore: cleaning up things
edwardfoyle May 5, 2021
68228f3
test: more unit tests and e2e test
edwardfoyle May 5, 2021
91ef0c4
test: small test tweaks
edwardfoyle May 5, 2021
1eea72e
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle May 5, 2021
4099db4
chore: reverting some unintentional linting changes
edwardfoyle May 5, 2021
56e10c8
fix: add update to env help text
edwardfoyle May 5, 2021
cbe9a0f
test: add mock
edwardfoyle May 6, 2021
9ff685b
chore: address PR comments
edwardfoyle May 7, 2021
ccfd139
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle May 10, 2021
95ec526
chore: use module var instead of global var
edwardfoyle May 20, 2021
d0ad684
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle May 20, 2021
6aad5f1
chore: rename permission boundary -> permissions boundary
edwardfoyle May 20, 2021
68adc9d
fix: merge tpi instead of overwrite
edwardfoyle May 21, 2021
27b318e
chore: remove newline
edwardfoyle May 21, 2021
6baa2a8
fix: load creds for new env when checking policy
edwardfoyle May 22, 2021
490ed8c
fix: test fixes
edwardfoyle May 22, 2021
3e34fcd
test: fix unit tests
edwardfoyle May 22, 2021
251b058
Merge remote-tracking branch 'upstream/master' into param-bound
edwardfoyle May 22, 2021
fd65741
test: fix profile selection
edwardfoyle May 24, 2021
6fbff2b
fix: change permissions boundary success text
edwardfoyle May 24, 2021
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
70 changes: 50 additions & 20 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1119,30 +1119,38 @@ jobs:
environment:
TEST_SUITE: src/__tests__/migration/node.function.test.ts
CLI_REGION: eu-west-2
iam-permission-boundary-amplify_e2e_tests:
working_directory: ~/repo
docker: *ref_1
resource_class: large
steps: *ref_4
environment:
TEST_SUITE: src/__tests__/iam-permission-boundary.test.ts
CLI_REGION: eu-central-1
function_5-amplify_e2e_tests:
working_directory: ~/repo
docker: *ref_1
resource_class: large
steps: *ref_4
environment:
TEST_SUITE: src/__tests__/function_5.test.ts
CLI_REGION: eu-central-1
CLI_REGION: ap-northeast-1
configure-project-amplify_e2e_tests:
working_directory: ~/repo
docker: *ref_1
resource_class: large
steps: *ref_4
environment:
TEST_SUITE: src/__tests__/configure-project.test.ts
CLI_REGION: ap-northeast-1
CLI_REGION: ap-southeast-1
api_4-amplify_e2e_tests:
working_directory: ~/repo
docker: *ref_1
resource_class: large
steps: *ref_4
environment:
TEST_SUITE: src/__tests__/api_4.test.ts
CLI_REGION: ap-southeast-1
CLI_REGION: ap-southeast-2
schema-iterative-update-4-amplify_e2e_tests_pkg_linux:
working_directory: ~/repo
docker: *ref_1
Expand Down Expand Up @@ -1803,6 +1811,16 @@ jobs:
TEST_SUITE: src/__tests__/migration/node.function.test.ts
CLI_REGION: eu-west-2
steps: *ref_5
iam-permission-boundary-amplify_e2e_tests_pkg_linux:
working_directory: ~/repo
docker: *ref_1
resource_class: large
environment:
AMPLIFY_DIR: /home/circleci/repo/out
AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux
TEST_SUITE: src/__tests__/iam-permission-boundary.test.ts
CLI_REGION: eu-central-1
steps: *ref_5
function_5-amplify_e2e_tests_pkg_linux:
working_directory: ~/repo
docker: *ref_1
Expand All @@ -1811,7 +1829,7 @@ jobs:
AMPLIFY_DIR: /home/circleci/repo/out
AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux
TEST_SUITE: src/__tests__/function_5.test.ts
CLI_REGION: eu-central-1
CLI_REGION: ap-northeast-1
steps: *ref_5
configure-project-amplify_e2e_tests_pkg_linux:
working_directory: ~/repo
Expand All @@ -1821,7 +1839,7 @@ jobs:
AMPLIFY_DIR: /home/circleci/repo/out
AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux
TEST_SUITE: src/__tests__/configure-project.test.ts
CLI_REGION: ap-northeast-1
CLI_REGION: ap-southeast-1
steps: *ref_5
api_4-amplify_e2e_tests_pkg_linux:
working_directory: ~/repo
Expand All @@ -1831,7 +1849,7 @@ jobs:
AMPLIFY_DIR: /home/circleci/repo/out
AMPLIFY_PATH: /home/circleci/repo/out/amplify-pkg-linux
TEST_SUITE: src/__tests__/api_4.test.ts
CLI_REGION: ap-southeast-1
CLI_REGION: ap-southeast-2
steps: *ref_5
workflows:
version: 2
Expand Down Expand Up @@ -1944,19 +1962,19 @@ workflows:
- predictions-amplify_e2e_tests
- schema-predictions-amplify_e2e_tests
- amplify-configure-amplify_e2e_tests
- function_5-amplify_e2e_tests
- iam-permission-boundary-amplify_e2e_tests
- containers-api-amplify_e2e_tests
- interactions-amplify_e2e_tests
- datastore-modelgen-amplify_e2e_tests
- configure-project-amplify_e2e_tests
- function_5-amplify_e2e_tests
- schema-iterative-update-2-amplify_e2e_tests
- schema-data-access-patterns-amplify_e2e_tests
- init-special-case-amplify_e2e_tests
- api_4-amplify_e2e_tests
- auth_1-amplify_e2e_tests
- configure-project-amplify_e2e_tests
- feature-flags-amplify_e2e_tests
- schema-versioned-amplify_e2e_tests
- plugin-amplify_e2e_tests
- api_4-amplify_e2e_tests
- done_with_pkg_linux_e2e_tests:
requires:
- schema-key-amplify_e2e_tests_pkg_linux
Expand All @@ -1974,19 +1992,19 @@ workflows:
- predictions-amplify_e2e_tests_pkg_linux
- schema-predictions-amplify_e2e_tests_pkg_linux
- amplify-configure-amplify_e2e_tests_pkg_linux
- function_5-amplify_e2e_tests_pkg_linux
- iam-permission-boundary-amplify_e2e_tests_pkg_linux
- containers-api-amplify_e2e_tests_pkg_linux
- interactions-amplify_e2e_tests_pkg_linux
- datastore-modelgen-amplify_e2e_tests_pkg_linux
- configure-project-amplify_e2e_tests_pkg_linux
- function_5-amplify_e2e_tests_pkg_linux
- schema-iterative-update-2-amplify_e2e_tests_pkg_linux
- schema-data-access-patterns-amplify_e2e_tests_pkg_linux
- init-special-case-amplify_e2e_tests_pkg_linux
- api_4-amplify_e2e_tests_pkg_linux
- auth_1-amplify_e2e_tests_pkg_linux
- configure-project-amplify_e2e_tests_pkg_linux
- feature-flags-amplify_e2e_tests_pkg_linux
- schema-versioned-amplify_e2e_tests_pkg_linux
- plugin-amplify_e2e_tests_pkg_linux
- api_4-amplify_e2e_tests_pkg_linux
- amplify_migration_tests_latest:
context:
- amplify-ecr-image-pull
Expand Down Expand Up @@ -2339,7 +2357,7 @@ workflows:
filters: *ref_9
requires:
- auth_4-amplify_e2e_tests
- function_5-amplify_e2e_tests:
- iam-permission-boundary-amplify_e2e_tests:
context: *ref_7
post-steps: *ref_8
filters: *ref_9
Expand Down Expand Up @@ -2399,7 +2417,7 @@ workflows:
filters: *ref_9
requires:
- migration-api-key-migration1-amplify_e2e_tests
- configure-project-amplify_e2e_tests:
- function_5-amplify_e2e_tests:
context: *ref_7
post-steps: *ref_8
filters: *ref_9
Expand Down Expand Up @@ -2459,7 +2477,7 @@ workflows:
filters: *ref_9
requires:
- layer-amplify_e2e_tests
- api_4-amplify_e2e_tests:
- configure-project-amplify_e2e_tests:
context: *ref_7
post-steps: *ref_8
filters: *ref_9
Expand Down Expand Up @@ -2519,6 +2537,12 @@ workflows:
filters: *ref_9
requires:
- auth_3-amplify_e2e_tests
- api_4-amplify_e2e_tests:
context: *ref_7
post-steps: *ref_8
filters: *ref_9
requires:
- auth_1-amplify_e2e_tests
- schema-iterative-update-4-amplify_e2e_tests_pkg_linux:
context: &ref_10
- amplify-ecr-image-pull
Expand Down Expand Up @@ -2777,7 +2801,7 @@ workflows:
filters: *ref_12
requires:
- auth_4-amplify_e2e_tests_pkg_linux
- function_5-amplify_e2e_tests_pkg_linux:
- iam-permission-boundary-amplify_e2e_tests_pkg_linux:
context: *ref_10
post-steps: *ref_11
filters: *ref_12
Expand Down Expand Up @@ -2841,7 +2865,7 @@ workflows:
filters: *ref_12
requires:
- migration-api-key-migration1-amplify_e2e_tests_pkg_linux
- configure-project-amplify_e2e_tests_pkg_linux:
- function_5-amplify_e2e_tests_pkg_linux:
context: *ref_10
post-steps: *ref_11
filters: *ref_12
Expand Down Expand Up @@ -2905,7 +2929,7 @@ workflows:
filters: *ref_12
requires:
- layer-amplify_e2e_tests_pkg_linux
- api_4-amplify_e2e_tests_pkg_linux:
- configure-project-amplify_e2e_tests_pkg_linux:
context: *ref_10
post-steps: *ref_11
filters: *ref_12
Expand Down Expand Up @@ -2969,3 +2993,9 @@ workflows:
filters: *ref_12
requires:
- auth_3-amplify_e2e_tests_pkg_linux
- api_4-amplify_e2e_tests_pkg_linux:
context: *ref_10
post-steps: *ref_11
filters: *ref_12
requires:
- auth_1-amplify_e2e_tests_pkg_linux
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { getPermissionBoundaryArn, setPermissionBoundaryArn } from '..';
import { stateManager } from '../state-manager';

jest.mock('../state-manager');

const testEnv = 'testEnv';

const objKey = 'PermissionBoundaryPolicyArn';

const stateManager_mock = stateManager as jest.Mocked<typeof stateManager>;
stateManager_mock.getLocalEnvInfo.mockReturnValue({
envName: testEnv,
});

const testArn = 'testArn';

const tpi_stub = {
[testEnv]: {
awscloudformation: {
[objKey]: testArn,
},
},
};

describe('get permission boundary arn', () => {
beforeEach(jest.clearAllMocks);
it('gets arn from team provider info file', () => {
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce(tpi_stub);
expect(getPermissionBoundaryArn()).toEqual(testArn);
});

it('gets arn from preInitTeamProviderInfo', () => {
(global as any).preInitTeamProviderInfo = tpi_stub;
expect(getPermissionBoundaryArn()).toEqual(testArn);
delete (global as any).preInitTeamProviderInfo;
});

it('returns undefined if no value found', () => {
expect(getPermissionBoundaryArn()).toBeUndefined();
});
});

describe('set permission boundary arn', () => {
beforeEach(jest.clearAllMocks);
it('sets the ARN value in tpi file if specified', () => {
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce({});
setPermissionBoundaryArn(testArn);
expect(stateManager_mock.setTeamProviderInfo.mock.calls[0][1][testEnv].awscloudformation[objKey]).toEqual(testArn);
});

it('sets the ARN for the specified env', () => {
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce({});
setPermissionBoundaryArn(testArn, 'otherenv');
expect(stateManager_mock.setTeamProviderInfo.mock.calls[0][1].otherenv.awscloudformation[objKey]).toEqual(testArn);
});

it('removes the ARN value if not specified', () => {
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce(tpi_stub);
setPermissionBoundaryArn();
expect(stateManager_mock.setTeamProviderInfo.mock.calls[0][1][testEnv].awscloudformation).toBeDefined();
expect(stateManager_mock.setTeamProviderInfo.mock.calls[0][1][testEnv].awscloudformation[objKey]).toBeUndefined();
});

it('if tpi object specified, sets arn in object and sets global preInitTeamProviderInfo', () => {
const tpi: Record<string, any> = {};
setPermissionBoundaryArn(testArn, undefined, tpi);
expect(tpi[testEnv].awscloudformation[objKey]).toEqual(testArn);
expect((global as any).preInitTeamProviderInfo).toEqual(tpi);
delete (global as any).preInitTeamProviderInfo;
});
});
3 changes: 2 additions & 1 deletion packages/amplify-cli-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './cliContext';
export * from './cliContextEnvironmentProvider';
export * from './cliEnvironmentProvider';
export * from './feature-flags';
export * from './permissionBoundaryState';
export * from './jsonUtilities';
export * from './jsonValidationError';
export * from './serviceSelection';
Expand Down Expand Up @@ -181,7 +182,7 @@ interface AmplifyToolkit {
getResourceStatus: (category?: $TSAny, resourceName?: $TSAny, providerName?: $TSAny, filteredResources?: $TSAny) => $TSAny;
getResourceOutputs: () => $TSAny;
getWhen: () => $TSAny;
inputValidation: (input: $TSAny) => $TSAny;
inputValidation: (input: $TSAny) => (value: $TSAny) => boolean | string;
listCategories: () => $TSAny;
makeId: (n?: number) => string;
openEditor: () => $TSAny;
Expand Down
55 changes: 55 additions & 0 deletions packages/amplify-cli-core/src/permissionBoundaryState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { stateManager } from './state-manager';
import _ from 'lodash';
import { $TSObject } from '.';

export const getPermissionBoundaryArn = (env?: string): string | undefined => {
try {
const preInitTpi = (global as any).preInitTeamProviderInfo;
const teamProviderInfo = preInitTpi ?? stateManager.getTeamProviderInfo();
// if the pre init team-provider-info only has one env (which should always be the case), default to that one
if (preInitTpi && Object.keys(preInitTpi).length === 1 && !env) {
env = Object.keys(preInitTpi)[0];
}
return _.get(teamProviderInfo, teamProviderInfoObjectPath(env)) as string | undefined;
} catch (err) {
// uninitialized project
return undefined;
}
};

/**
* Stores the permission boundary ARN in team-provider-info
* If teamProviderInfo is not specified, the file is read, updated and written back to disk
* If teamProviderInfo is specified, then this function assumes that the env is not initialized
* In this case, the teamProviderInfo object is updated but not written to disk. Instead "preInitTeamProviderInfo" is set
* so that subsequent calls to getPermissionBoundaryArn will return the permission boundary arn of the pre-initialized env
* @param arn The permission boundary arn. If undefined or empty, the permission boundary is removed
* @param env The Amplify env to update. If not specified, defaults to the current checked out environment
* @param teamProviderInfo The team-provider-info object to update
*/
export const setPermissionBoundaryArn = (arn?: string, env?: string, teamProviderInfo?: $TSObject): void => {
let tpiGetter = () => stateManager.getTeamProviderInfo();
let tpiSetter = (tpi: $TSObject) => {
stateManager.setTeamProviderInfo(undefined, tpi);
delete (global as any).preInitTeamProviderInfo; // avoids a potential edge case where set permissions is called again w/o tpi
edwardfoyle marked this conversation as resolved.
Show resolved Hide resolved
};
if (teamProviderInfo) {
tpiGetter = () => teamProviderInfo;
tpiSetter = (tpi: $TSObject) => {
(global as any).preInitTeamProviderInfo = tpi;
};
}
const tpi = tpiGetter();
if (!arn) {
_.unset(tpi, teamProviderInfoObjectPath(env));
} else {
_.set(tpi, teamProviderInfoObjectPath(env), arn);
}
tpiSetter(tpi);
};

const teamProviderInfoObjectPath = (env?: string) => [
env || (stateManager.getLocalEnvInfo().envName as string),
'awscloudformation',
'PermissionBoundaryPolicyArn',
];
4 changes: 4 additions & 0 deletions packages/amplify-cli/src/commands/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ function displayHelp(context) {
name: 'import --name <env-name> --config <provider-configs> [--awsInfo <aws-configs>]',
description: 'Imports an already existing Amplify project environment stack to your local backend',
},
{
name: 'update [--permission-boundary <IAM Policy ARN>]',
description: 'Update the environment configuration',
},
{
name: 'remove <env-name>',
description: 'Removes an environment from the Amplify project',
Expand Down
6 changes: 6 additions & 0 deletions packages/amplify-cli/src/commands/env/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { $TSContext } from 'amplify-cli-core';
import { executeProviderCommand } from '../../extensions/amplify-helpers/get-provider-plugins';

export const run = async (context: $TSContext) => {
await executeProviderCommand(context, 'updateEnv');
};
Loading