Skip to content

Commit

Permalink
Release v1.6.9 into Main
Browse files Browse the repository at this point in the history
  • Loading branch information
estohlmann authored Feb 26, 2025
2 parents 80c9050 + e7d052f commit 7e15e8b
Show file tree
Hide file tree
Showing 16 changed files with 712 additions and 144 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ MLSpace provides users access to selected resources within the Amazon SageMaker
- *Optional*: Have your VPC information available, if you are using an existing one for your deployment
- *Optional*: Have your Proxy information available if required
- *Note*: CDK briefly leverages SSM. Confirm it is approved for use by your organization before beginning
- *Note*: The MLSpace deployment is optimized for Linux-based environments. If your local environment does not meet this requirement, we recommend provisioning an Amazon EC2 instance running Linux to serve as your deployment platform.

### Software

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from ml_space_lambda.data_access_objects.app_configuration import AppConfigurationModel
from ml_space_lambda.enums import EnvVariable, IAMEffect, IAMStatementProperty, ResourceType, ServiceType
from ml_space_lambda.utils.account_utils import account_arn_from_context
from ml_space_lambda.utils.iam_manager import IAM_RESOURCE_PREFIX, IAMManager
from ml_space_lambda.utils.iam_manager import IAMManager
from ml_space_lambda.utils.mlspace_config import get_environment_variables

env_variables = get_environment_variables()
Expand All @@ -44,7 +44,7 @@ def __init__(self, context):
IAMStatementProperty.EFFECT: IAMEffect.DENY,
IAMStatementProperty.ACTION: "iam:PassRole",
IAMStatementProperty.RESOURCE: account_arn_from_context(
context, "iam", f"role/{IAM_RESOURCE_PREFIX}*", omit_region=True
context, "iam", f"role/{env_variables[EnvVariable.IAM_RESOURCE_PREFIX]}*", omit_region=True
),
IAMStatementProperty.CONDITION: {"StringEquals": {"iam:PassedToReception": "translate.amazonaws.com"}},
},
Expand Down
1 change: 1 addition & 0 deletions backend/src/ml_space_lambda/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def __str__(self):
PERMISSIONS_BOUNDARY_ARN = "PERMISSIONS_BOUNDARY_ARN"
JOB_INSTANCE_CONSTRAINT_POLICY_ARN = "JOB_INSTANCE_CONSTRAINT_POLICY_ARN"
KMS_INSTANCE_CONDITIONS_POLICY_ARN = "KMS_INSTANCE_CONDITIONS_POLICY_ARN"
IAM_RESOURCE_PREFIX = "IAM_RESOURCE_PREFIX"


class Permission(str, Enum):
Expand Down
14 changes: 7 additions & 7 deletions backend/src/ml_space_lambda/utils/iam_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

logger = logging.getLogger(__name__)

IAM_RESOURCE_PREFIX = "MLSpace"
IAM_ROLE_NAME_MAX_LENGTH = 64
IAM_POLICY_NAME_MAX_LENGTH = 128
USER_POLICY_VERSION = 1
Expand Down Expand Up @@ -154,6 +153,7 @@ def __init__(self, iam_client=None, sts_client=None):
self.notebook_role_name = env_variables[EnvVariable.NOTEBOOK_ROLE_NAME]
self.default_notebook_role_policy_arns = []
self.permissions_boundary_arn = env_variables[EnvVariable.PERMISSIONS_BOUNDARY_ARN]
self.iam_resource_prefix = env_variables[EnvVariable.IAM_RESOURCE_PREFIX]

def get_iam_role_arn(self, project_name: str, username: str) -> Optional[str]:
"""
Expand Down Expand Up @@ -181,7 +181,7 @@ def add_iam_role(self, project_name: str, username: str) -> str:
iam_role_arn = self._create_iam_role(iam_role_name, project_name, username)

# Build additional resource name variables
project_policy_name = f"{IAM_RESOURCE_PREFIX}-project-{project_name}"
project_policy_name = f"{self.iam_resource_prefix}-project-{project_name}"

aws_account = self.sts_client.get_caller_identity()["Account"]
project_policy_arn = f"arn:{self.aws_partition}:iam::{aws_account}:policy/{project_policy_name}"
Expand Down Expand Up @@ -282,7 +282,7 @@ def update_user_policy(
self,
username: str,
) -> str:
user_policy_name = f"{IAM_RESOURCE_PREFIX}-user-{username}"
user_policy_name = f"{self.iam_resource_prefix}-user-{username}"
aws_account = self.sts_client.get_caller_identity()["Account"]
user_policy_arn = f"arn:{self.aws_partition}:iam::{aws_account}:policy/{user_policy_name}"
self._check_name_length(IAMResourceType.POLICY, user_policy_name)
Expand Down Expand Up @@ -336,7 +336,7 @@ def remove_project_user_roles(self, role_identifiers: List[str], project: str =
self.iam_client.delete_role(RoleName=iam_role)

if project:
project_policy_name = f"{IAM_RESOURCE_PREFIX}-project-{project}"
project_policy_name = f"{self.iam_resource_prefix}-project-{project}"
self.iam_client.delete_policy(
PolicyArn=f"arn:{self.aws_partition}:iam::{aws_account}:policy/{project_policy_name}"
)
Expand All @@ -351,7 +351,7 @@ def remove_all_user_roles(self, username: str, projects: List[str]) -> None:
self.remove_project_user_roles(roles_to_delete)
# Delete user policy
aws_account = self.sts_client.get_caller_identity()["Account"]
user_policy_name = f"{IAM_RESOURCE_PREFIX}-user-{username}"
user_policy_name = f"{self.iam_resource_prefix}-user-{username}"
user_policy_arn = f"arn:{self.aws_partition}:iam::{aws_account}:policy/{user_policy_name}"
self.iam_client.delete_policy(PolicyArn=user_policy_arn)

Expand Down Expand Up @@ -579,7 +579,7 @@ def update_dynamic_policy(
expected_policy_version: int = None,
):
aws_account = self.sts_client.get_caller_identity()["Account"]
prefixed_policy_name = f"{IAM_RESOURCE_PREFIX}-{policy_name}"
prefixed_policy_name = f"{self.iam_resource_prefix}-{policy_name}"
self._check_name_length(IAMResourceType.POLICY, prefixed_policy_name)
policy_arn = f"arn:{self.aws_partition}:iam::{aws_account}:policy/{prefixed_policy_name}"
logger.info(f"Attempting to update {policy_name} with the provided policy {policy}")
Expand Down Expand Up @@ -686,7 +686,7 @@ def _generate_user_hash(self, username: str) -> str:
def _generate_iam_role_name(self, username: str, project_name: str) -> str:
user_hash = self._generate_user_hash(username)

iam_role_name_prefix = f"{IAM_RESOURCE_PREFIX}-{project_name}-"
iam_role_name_prefix = f"{self.iam_resource_prefix}-{project_name}-"
hash_split = IAM_ROLE_NAME_MAX_LENGTH - len(iam_role_name_prefix)
iam_role_name = f"{iam_role_name_prefix}{user_hash[: hash_split - 1]}"

Expand Down
1 change: 1 addition & 0 deletions backend/src/ml_space_lambda/utils/mlspace_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
EnvVariable.GROUP_USERS_TABLE: "mlspace-group-users",
EnvVariable.GROUP_DATASETS_TABLE: "mlspace-group-datasets",
EnvVariable.GROUPS_MEMBERSHIP_HISTORY_TABLE: "mlspace-group-membership-history",
EnvVariable.IAM_RESOURCE_PREFIX: "MLSpace",
}


Expand Down
1 change: 1 addition & 0 deletions backend/test/config/test_describe_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def test_describe_config_success(mock_sagemaker, mock_pull_config, mock_s3_param
EnvVariable.JOB_INSTANCE_CONSTRAINT_POLICY_ARN: "",
EnvVariable.NOTEBOOK_ROLE_NAME: "",
EnvVariable.PERMISSIONS_BOUNDARY_ARN: "",
EnvVariable.IAM_RESOURCE_PREFIX: "MLSpace",
},
"s3ParamFile": {
"pSMSKMSKeyId": "example_key_id",
Expand Down
1 change: 1 addition & 0 deletions backend/test/utils/test_mlspace_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,5 @@ def test_environment_variables():
EnvVariable.SYSTEM_TAG: "MLSpace",
EnvVariable.TRANSLATE_DATE_ROLE_ARN: "",
EnvVariable.USERS_TABLE: "mlspace-users",
EnvVariable.IAM_RESOURCE_PREFIX: "MLSpace",
}
10 changes: 10 additions & 0 deletions bin/mlspace-cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { MLSpaceConfig, generateConfig } from '../lib/utils/configTypes';
import { AppConfigurationApiStack } from '../lib/stacks/api/appConfiguration';
import { GroupsApiStack } from '../lib/stacks/api/groups';
import { GroupMembershipHistoryApiStack } from '../lib/stacks/api/groupMembershipHistory';
import { AddPermissionBoundary } from '@cdklabs/cdk-enterprise-iac';


const config: MLSpaceConfig = generateConfig();
Expand Down Expand Up @@ -222,6 +223,15 @@ stacks.push(...apiStacks);

// Apply infrastructure tags to all stack resources for cost reporting
stacks.forEach((resource) => {
// Apply permissions boundary aspect to all stacks if the boundary is defined
if (config.PERMISSIONS_BOUNDARY_POLICY_NAME !== '' && config.IAM_RESOURCE_PREFIX !== '') {
Aspects.of(resource).add(new AddPermissionBoundary({
permissionsBoundaryPolicyName: config.PERMISSIONS_BOUNDARY_POLICY_NAME,
rolePrefix: config.IAM_RESOURCE_PREFIX,
policyPrefix: config.IAM_RESOURCE_PREFIX,
instanceProfilePrefix: config.IAM_RESOURCE_PREFIX,
}));
}
// Tags are not supported on log groups in ADC regions
if (!isIso || resource instanceof LogGroup) {
Tags.of(resource).add('system', config.SYSTEM_TAG);
Expand Down
1 change: 1 addition & 0 deletions frontend/docs/admin-guide/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ In order to build and deploy {{ $params.APPLICATION_NAME }} to your AWS account,
- [awscli](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- [nodejs](https://nodejs.org/en/download/)
- cdk (`npm install -g cdk`)
- Linux based deployment platform - *If your local environment does not meet this requirement, we recommend provisioning an Amazon EC2 instance running Linux to serve as your deployment platform.*


### Information
Expand Down
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@amzn/mlspace",
"homepage": "/Prod",
"version": "1.6.8",
"version": "1.6.9",
"main": "dist/lib/index.js",
"types": "dist/types/index.d.ts",
"private": true,
Expand Down
14 changes: 6 additions & 8 deletions frontend/src/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# Release v1.6.8
# v1.6.9

## Enhancements
- Updated third-party dependencies.
- Enabled configurable display of migration options.
- Updated documentation for deployment to an existing VPC.
- Enhanced enforcement of proper resource tagging.
- Added support for custom permission boundary to all stacks, this includes ensuring IAM prefixes are applied to all application created roles. This allows customers to provide a more constrained permission boundary for the application.
- Updated documentation to make it more clear about deployment platform expectations

## Bugs
- Corrected a typo in IAM policies.
## Security
- Upgraded esbuild dependency to resolve potential CORS settings issue

## Acknowledgements
* @bedanley
* @dustins
* @estohlmann

**Full Changelog**: https://github.com/awslabs/mlspace/compare/v1.6.7...v1.6.8
**Full Changelog**: https://github.com/awslabs/mlspace/compare/v1.6.8...v1.6.9
4 changes: 1 addition & 3 deletions lib/stacks/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,11 @@ export class IAMStack extends Stack {
effect: Effect.ALLOW,
actions: [
'translate:StopTextTranslationJob',
'translate:ListTextTranslationJobs',
'translate:List*',
'translate:StartTextTranslationJob',
'translate:DescribeTextTranslationJob',
'translate:TranslateDocument',
'translate:TranslateText',
'translate:ListTerminologies',
'translate:ListLanguages',
],
resources: ['*'],
}));
Expand Down
1 change: 1 addition & 0 deletions lib/utils/apiFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export function registerAPIEndpoint (
NOTEBOOK_ROLE_NAME: notebookRoleName,
APP_ROLE_NAME: appRoleName,
PERMISSIONS_BOUNDARY_ARN: permissionsBoundaryArn || '',
IAM_RESOURCE_PREFIX: mlspaceConfig.IAM_RESOURCE_PREFIX,
...funcDef.environment,
...mlspaceConfig.ADDITIONAL_LAMBDA_ENVIRONMENT_VARS,
},
Expand Down
Loading

0 comments on commit 7e15e8b

Please sign in to comment.