Skip to content

feat(iam): permissions boundaries for the UseCase and Data accounts - #115

Draft
rvanderwerf wants to merge 1 commit into
mainfrom
feat/dda-usecase-data-boundary
Draft

rvanderwerf wants to merge 1 commit into
mainfrom
feat/dda-usecase-data-boundary

Conversation

@rvanderwerf

Copy link
Copy Markdown
Contributor

Extends the permissions boundary of #113 (Portal Account) to the UseCase and Data accounts. Until now a template deployed in those accounts could create a DDA role with any inline policy, for example * on *.

Draft: the Access Analyzer check and a live test are still to do (see below).

Change

  • New iam/usecase-permissions-boundary-policy.json (dda-usecase-permissions-boundary):
    • the services the six UseCase roles use: CloudWatch, ECR, EventBridge, Greengrass, IoT, Logs, S3, SageMaker, Secrets Manager and SQS; Service Quotas, SSM parameter and tag reads;
    • IAM reads; IAM changes only on those six roles, the devices' GreengrassV2TokenExchangeRole and its access policy, and DDAPortalComponentAccessPolicy;
    • iam:PassRole only for the DDA roles, plus roles whose names contain SageMaker, Greengrass or GroundTruth, to SageMaker and Greengrass only. That is what DDAPortalAccessRole passes today;
    • a Deny on iam:CreateRole and iam:PutRolePermissionsBoundary unless the role gets the same boundary. GreengrassV2TokenExchangeRole is the exception, as in the Portal boundary.
  • New iam/data-permissions-boundary-policy.json (dda-data-permissions-boundary): S3, plus Service Quotas, SSM parameter and tag reads; IAM reads; IAM changes only on DDAPortalDataAccessRole and DDASageMakerDataAccessRole; the same Deny, with no exception.
  • iam/setup-account.sh usecase|data creates the account's boundary and bootstraps with --custom-permissions-boundary, as it does for the portal. The boundary keeps its name with --name-suffix: it names itself in its Deny, and there is one per account.
  • usecase-cfn-execution-policy.json and data-cfn-execution-policy.json let the execution role put only that boundary on the stack's roles (iam:PutRolePermissionsBoundary, which an upgrade needs) and read it (iam:GetPolicy). These are the two gaps the Portal live test found (feat(portal): a DDA permissions boundary on the execution role and every portal role #113).
  • usecase-installer-policy.json and data-installer-policy.json may read the CDKToolkit stack. deploy-account-role.sh usecase|data now reads the bootstrap's boundary there (scripts/portal-permissions-boundary.sh) and passes -c ddaPermissionsBoundary=<name> to the app. A lookup that fails stops the deploy.
  • bin/usecase-account-app.ts and bin/data-account-app.ts put the boundary on every role (lib/permissions-boundary.ts). Without the context nothing changes, and the IAM synth gate's UseCase template is unchanged.
  • README: the boundaries of all three accounts, the policy table, and the installer calls of steps 5.1 and 5.2.

Found, not changed: both stacks grant resourcegroupstaggingapi:GetResources (the UseCase stack also GetTagKeys and GetTagValues). That is not an IAM service prefix, so these grant nothing. The tag:* actions next to them are what the Resource Groups Tagging API checks. The boundaries do not list the prefix, and the test skips it.

Upgrading an existing install

In each UseCase and Data account, run this version's iam/setup-account.sh usecase (or data) as an administrator, then deploy-portal.sh usecase (or data). CloudFormation adds the boundary to every role. An account where the setup is not rerun keeps working as before: its bootstrap has no boundary, so the deploy passes none.

Tests

  • infrastructure/test/usecase-data-permissions-boundary.test.ts (16, eight per account):

    • the boundary on every role with the context, and on none without;
    • every role has a fixed name the boundary lets the execution role create;
    • every action the roles are granted, and every action of the execution policy, is inside the boundary (IAM and STS actions on their resources too);
    • the single Deny;
    • no IAM users, access keys, boundary removal, or changes to the installer, an administrator or a boundary policy;
    • the execution policy's two new statements;
    • the app wiring.

    Mutation check: with sagemaker:* removed from the UseCase boundary, the grants test fails.

  • tests/setup_account.bats: the UseCase and Data boundaries and bootstrap flag; the name with --name-suffix.

  • tests/usecase_data_setup.bats: deploy-account-role.sh passes the bootstrap's boundary for usecase and data (not to the bootstrap), and stops before cdk deploy when the bootstrap cannot be read.

  • Results:

    • infrastructure jest: 543 passed (16 new);
    • edge-cv-portal/tests/*.bats: 235 passed (4 new);
    • IAM CDK synth gate: 40 passed;
    • security preservation: 198 passed, 13 skipped.

Before merging

  • IAM Access Analyzer on the two boundaries and the changed execution and installer policies.
  • Live test. A UseCase account cannot be tested in the single-account test account, because the UseCase stack creates DDASageMakerExecutionRole, which already exists there. The Data stack can run in a second region of that account.

The Portal Account's boundary (#113) now has a counterpart in the other two
account kinds, so a template deployed there can no longer create a DDA role
with "*" on "*".

- New iam/usecase-permissions-boundary-policy.json
  (dda-usecase-permissions-boundary): the services the six UseCase roles use
  (CloudWatch, ECR, EventBridge, Greengrass, IoT, Logs, S3, SageMaker,
  Secrets Manager, SQS; Service Quotas, SSM parameter and tag reads); IAM
  reads; IAM changes only on those six roles, the devices' token exchange
  role and its access policy, and DDAPortalComponentAccessPolicy;
  iam:PassRole only for the DDA roles, plus the *SageMaker*, *Greengrass* and
  *GroundTruth* roles to SageMaker and Greengrass, as DDAPortalAccessRole
  passes them; a Deny on iam:CreateRole and iam:PutRolePermissionsBoundary
  without the same boundary, except GreengrassV2TokenExchangeRole.
- New iam/data-permissions-boundary-policy.json
  (dda-data-permissions-boundary): S3, plus Service Quotas, SSM parameter and
  tag reads; IAM reads; IAM changes only on DDAPortalDataAccessRole and
  DDASageMakerDataAccessRole; the same Deny, with no exception.
- setup-account.sh usecase|data creates the account's boundary and
  bootstraps with --custom-permissions-boundary, as it does for the portal.
- The two execution policies may put only that boundary on their stack's
  roles (iam:PutRolePermissionsBoundary, which an upgrade needs) and read it
  (iam:GetPolicy): the two gaps the Portal live test found.
- The two installer policies may read the CDKToolkit stack:
  deploy-account-role.sh usecase|data now reads the bootstrap's boundary
  there (scripts/portal-permissions-boundary.sh) and passes it to the app
  with -c ddaPermissionsBoundary; a lookup that fails stops the deploy.
  bin/usecase-account-app.ts and bin/data-account-app.ts put it on every
  role. Without the context nothing changes (the IAM synth gate's UseCase
  template is unchanged).
- README: the boundaries of all three accounts.

Tests: usecase-data-permissions-boundary.test.ts (16, eight per account):
the boundary on every role with the context and on none without; every role
has a fixed name the boundary covers; every action the roles are granted,
and every action of the execution policy, is inside the boundary (IAM and
STS actions on their resources too; resourcegroupstaggingapi:*, which the
stacks grant but which is not an IAM service prefix, is skipped); the Deny;
no users, keys, boundary removal or changes to the installer, an
administrator or a boundary policy; the execution policy's two new
statements; the app wiring. setup_account.bats: the UseCase and Data
boundaries and bootstrap flag, and the boundary name with --name-suffix.
usecase_data_setup.bats: deploy-account-role.sh passes the bootstrap's
boundary for usecase and data (not to the bootstrap), and stops when the
bootstrap cannot be read.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant