import * as cdk from "aws-cdk-lib"; import * as identitystore from "aws-cdk-lib/aws-identitystore"; import * as sso from "aws-cdk-lib/aws-sso"; import { Construct } from "constructs"; const IDENTITY_CENTER_INSTANCE_ARN = "arn:aws:sso:::instance/ssoins-722321f42ca610e4"; const IDENTITY_STORE_ID = "d-9067ec8e26"; const VIEW_ONLY_POLICY = "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"; export interface ViewAccessStackProps extends cdk.StackProps { managementAccountId: string; securityAccountId: string; externalDevAccountId: string; devAccountId: string; prodAccountId: string; } /** * Identity Center group and permission set for view-only access across * every organization account. * * ViewOnlyAccess lists and describes resources. It does not read S3 * objects, secret values, DynamoDB items, or log contents. There is no * inline policy and no sts:AssumeRole on OrganizationAccountAccessRole. * * Group membership is outside this stack. */ export class ViewAccessStack extends cdk.Stack { constructor(scope: Construct, id: string, props: ViewAccessStackProps) { super(scope, id, props); const group = new identitystore.CfnGroup(this, "ViewGroup", { identityStoreId: IDENTITY_STORE_ID, displayName: "view", description: "View-only across all organization accounts. No data-plane reads.", }); const permissionSet = new sso.CfnPermissionSet(this, "ViewPermissionSet", { instanceArn: IDENTITY_CENTER_INSTANCE_ARN, name: "View", description: "ViewOnlyAccess in every organization account. No assume-role.", sessionDuration: "PT8H", managedPolicies: [VIEW_ONLY_POLICY], }); this.assignment( "ViewManagementAssignment", permissionSet, group, props.managementAccountId, ); this.assignment( "ViewSecurityAssignment", permissionSet, group, props.securityAccountId, ); this.assignment( "ViewExternalDevAssignment", permissionSet, group, props.externalDevAccountId, ); this.assignment( "ViewDevAssignment", permissionSet, group, props.devAccountId, ); this.assignment( "ViewProdAssignment", permissionSet, group, props.prodAccountId, ); } private assignment( id: string, permissionSet: sso.CfnPermissionSet, group: identitystore.CfnGroup, targetId: string, ): void { new sso.CfnAssignment(this, id, { instanceArn: IDENTITY_CENTER_INSTANCE_ARN, permissionSetArn: permissionSet.attrPermissionSetArn, principalId: group.attrGroupId, principalType: "GROUP", targetId, targetType: "AWS_ACCOUNT", }); } }