@meyicloud/meyi-insight-server 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/tenant.controller.js +1 -1
- package/dist/controllers/tenant.controller.js.map +1 -1
- package/dist/features/ai-usage/ai-usage.controller.d.ts +7 -0
- package/dist/features/ai-usage/ai-usage.controller.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.controller.js +32 -0
- package/dist/features/ai-usage/ai-usage.controller.js.map +1 -0
- package/dist/features/ai-usage/ai-usage.model.d.ts +24 -0
- package/dist/features/ai-usage/ai-usage.model.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.model.js +105 -0
- package/dist/features/ai-usage/ai-usage.model.js.map +1 -0
- package/dist/features/ai-usage/ai-usage.query.d.ts +13 -0
- package/dist/features/ai-usage/ai-usage.query.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.query.js +119 -0
- package/dist/features/ai-usage/ai-usage.query.js.map +1 -0
- package/dist/features/ai-usage/ai-usage.routes.d.ts +8 -0
- package/dist/features/ai-usage/ai-usage.routes.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.routes.js +14 -0
- package/dist/features/ai-usage/ai-usage.routes.js.map +1 -0
- package/dist/features/ai-usage/ai-usage.service.d.ts +9 -0
- package/dist/features/ai-usage/ai-usage.service.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.service.js +52 -0
- package/dist/features/ai-usage/ai-usage.service.js.map +1 -0
- package/dist/features/ai-usage/ai-usage.types.d.ts +107 -0
- package/dist/features/ai-usage/ai-usage.types.d.ts.map +1 -0
- package/dist/features/ai-usage/ai-usage.types.js +14 -0
- package/dist/features/ai-usage/ai-usage.types.js.map +1 -0
- package/dist/features/ai-usage/index.d.ts +5 -0
- package/dist/features/ai-usage/index.d.ts.map +1 -0
- package/dist/features/ai-usage/index.js +5 -0
- package/dist/features/ai-usage/index.js.map +1 -0
- package/dist/features/sources/cloudtrail/stackTemplates.d.ts +1 -1
- package/dist/features/sources/cloudtrail/stackTemplates.d.ts.map +1 -1
- package/dist/features/sources/cloudtrail/stackTemplates.js +17 -18
- package/dist/features/sources/cloudtrail/stackTemplates.js.map +1 -1
- package/dist/features/sources/cloudtrail/template.d.ts.map +1 -1
- package/dist/features/sources/cloudtrail/template.js +146 -21
- package/dist/features/sources/cloudtrail/template.js.map +1 -1
- package/dist/migrations/run.d.ts.map +1 -1
- package/dist/migrations/run.js +30 -15
- package/dist/migrations/run.js.map +1 -1
- package/dist/pipeline/defaults/pipelineDefaults.js +1 -1
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +6 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/dist/service.d.ts +2 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +4 -0
- package/dist/service.js.map +1 -1
- package/dist/services/tenant.service.js +2 -2
- package/dist/services/tenant.service.js.map +1 -1
- package/dist/tenancy.d.ts +1 -0
- package/dist/tenancy.d.ts.map +1 -1
- package/dist/tenancy.js +9 -3
- package/dist/tenancy.js.map +1 -1
- package/package.json +75 -75
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const STACK_YAML = "AWSTemplateFormatVersion: '2010-09-09'\nDescription: |\n Meyi Connect Security Monitoring - Regional Events Stack.\n Deploys regional security alerting rules and SNS webhook delivery.\n\nParameters:\n Environment:\n Type: String\n Default: \"MeyiConnect\"\n Description: Environment name (used as a prefix for resource names)\n\n WebhookUrl:\n Type: String\n Description: MeyiConnect webhook URL for security alerts.\n\n CreateCloudTrail:\n Type: String\n Default: 'false'\n Description: Kept for backwards compatibility.\n\n PrimaryRegion:\n Type: String\n Default: 'us-east-1'\n Description: Kept for backwards compatibility.\n\n DeploymentMode:\n Type: String\n Default: 'Organizations'\n Description: Kept for backwards compatibility.\n\nResources:\n\n # ============================================================\n # SNS TOPIC & SUBSCRIPTION FOR ALERTS\n # ============================================================\n\n SecurityAlertsTopic:\n Type: AWS::SNS::Topic\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n\n SecurityAlertsTopicPolicy:\n Type: AWS::SNS::TopicPolicy\n Properties:\n Topics:\n - !Ref SecurityAlertsTopic\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Principal:\n Service: events.amazonaws.com\n Action: sns:Publish\n Resource: !Ref SecurityAlertsTopic\n\n WebhookSubscription:\n Type: AWS::SNS::Subscription\n Properties:\n TopicArn: !Ref SecurityAlertsTopic\n Endpoint: !Ref WebhookUrl\n Protocol: https\n\n # ============================================================\n # EVENTBRIDGE RULES ON DEFAULT BUS\n # Regional events fire directly in this region - no forwarding needed\n # ============================================================\n\n DataAndInfrastructureSecurityRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: EC2, VPC, network, S3, and RDS configuration changes in the deployment region\n EventPattern:\n source:\n - aws.ec2\n - aws.s3\n - aws.rds\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventSource:\n - ec2.amazonaws.com\n - s3.amazonaws.com\n - rds.amazonaws.com\n eventName:\n # EC2 & Network Events\n - StopInstances\n - RunInstances\n - RebootInstances\n - StartInstances\n - TerminateInstances\n - CreateCustomerGateway\n - DeleteCustomerGateway\n - AttachInternetGateway\n - CreateInternetGateway\n - DeleteInternetGateway\n - DetachInternetGateway\n - CreateNetworkAcl\n - DeleteNetworkAcl\n - CreateNetworkAclEntry\n - DeleteNetworkAclEntry\n - ReplaceNetworkAclEntry\n - ReplaceNetworkAclAssociation\n - AuthorizeSecurityGroupIngress\n - AuthorizeSecurityGroupEgress\n - RevokeSecurityGroupIngress\n - RevokeSecurityGroupEgress\n - ModifySecurityGroupRules\n - UpdateSecurityGroupRuleDescriptionsIngress\n - UpdateSecurityGroupRuleDescriptionsEgress\n - CreateSecurityGroup\n - DeleteSecurityGroup\n - CreateVpc\n - DeleteVpc\n - ModifyVpcAttribute\n - AcceptVpcPeeringConnection\n - CreateVpcPeeringConnection\n - DeleteVpcPeeringConnection\n - RejectVpcPeeringConnection\n - AttachClassicLinkVpc\n - DetachClassicLinkVpc\n - DisableVpcClassicLink\n - EnableVpcClassicLink\n - ModifyImageAttribute\n - ModifySnapshotAttribute\n - ModifyInstanceAttribute\n - ImportKeyPair\n - CreateKeyPair\n - DisableEbsEncryptionByDefault\n - DeleteFlowLogs\n # S3 Events\n - PutBucketPublicAccessBlock\n - DeletePublicAccessBlock\n - PutBucketPolicy\n - DeleteBucketPolicy\n - PutBucketAcl\n - PutBucketEncryption\n - DeleteBucketEncryption\n - DeleteBucket\n # RDS Events\n - ModifyDBInstance\n - ModifyDBSnapshotAttribute\n - DeleteDBInstance\n - DeleteDBClusterSnapshot\n - RestoreDBInstanceFromDBSnapshot\n State: ENABLED\n Targets:\n - Arn: !Ref SecurityAlertsTopic\n Id: SNSTarget\n\n OperationsAndSecretsSecurityRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: Lambda, SSM, Secrets Manager, and KMS configuration/management events\n EventPattern:\n source:\n - aws.lambda\n - aws.ssm\n - aws.secretsmanager\n - aws.kms\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventSource:\n - lambda.amazonaws.com\n - ssm.amazonaws.com\n - secretsmanager.amazonaws.com\n - kms.amazonaws.com\n eventName:\n
|
|
1
|
+
export declare const STACK_YAML = "AWSTemplateFormatVersion: '2010-09-09'\nDescription: |\n Meyi Connect Security Monitoring - Regional Events Stack.\n Deploys regional security alerting rules and SNS webhook delivery.\n\nParameters:\n Environment:\n Type: String\n Default: \"MeyiConnect\"\n Description: Environment name (used as a prefix for resource names)\n\n WebhookUrl:\n Type: String\n Description: MeyiConnect webhook URL for security alerts.\n\n CreateCloudTrail:\n Type: String\n Default: 'false'\n Description: Kept for backwards compatibility.\n\n PrimaryRegion:\n Type: String\n Default: 'us-east-1'\n Description: Kept for backwards compatibility.\n\n DeploymentMode:\n Type: String\n Default: 'Organizations'\n Description: Kept for backwards compatibility.\n\nResources:\n\n # ============================================================\n # SNS TOPIC & SUBSCRIPTION FOR ALERTS\n # ============================================================\n\n SecurityAlertsTopic:\n Type: AWS::SNS::Topic\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n\n SecurityAlertsTopicPolicy:\n Type: AWS::SNS::TopicPolicy\n Properties:\n Topics:\n - !Ref SecurityAlertsTopic\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Principal:\n Service: events.amazonaws.com\n Action: sns:Publish\n Resource: !Ref SecurityAlertsTopic\n\n WebhookSubscription:\n Type: AWS::SNS::Subscription\n Properties:\n TopicArn: !Ref SecurityAlertsTopic\n Endpoint: !Ref WebhookUrl\n Protocol: https\n\n # ============================================================\n # EVENTBRIDGE RULES ON DEFAULT BUS\n # Regional events fire directly in this region - no forwarding needed\n # ============================================================\n\n DataAndInfrastructureSecurityRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: EC2, VPC, network, S3, and RDS configuration changes in the deployment region\n EventPattern:\n source:\n - aws.ec2\n - aws.s3\n - aws.rds\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventSource:\n - ec2.amazonaws.com\n - s3.amazonaws.com\n - rds.amazonaws.com\n eventName:\n # EC2 & Network Events\n - StopInstances\n - RunInstances\n - RebootInstances\n - StartInstances\n - TerminateInstances\n - CreateCustomerGateway\n - DeleteCustomerGateway\n - AttachInternetGateway\n - CreateInternetGateway\n - DeleteInternetGateway\n - DetachInternetGateway\n - CreateNetworkAcl\n - DeleteNetworkAcl\n - CreateNetworkAclEntry\n - DeleteNetworkAclEntry\n - ReplaceNetworkAclEntry\n - ReplaceNetworkAclAssociation\n - AuthorizeSecurityGroupIngress\n - AuthorizeSecurityGroupEgress\n - RevokeSecurityGroupIngress\n - RevokeSecurityGroupEgress\n - ModifySecurityGroupRules\n - UpdateSecurityGroupRuleDescriptionsIngress\n - UpdateSecurityGroupRuleDescriptionsEgress\n - CreateSecurityGroup\n - DeleteSecurityGroup\n - CreateVpc\n - DeleteVpc\n - ModifyVpcAttribute\n - AcceptVpcPeeringConnection\n - CreateVpcPeeringConnection\n - DeleteVpcPeeringConnection\n - RejectVpcPeeringConnection\n - AttachClassicLinkVpc\n - DetachClassicLinkVpc\n - DisableVpcClassicLink\n - EnableVpcClassicLink\n - ModifyImageAttribute\n - ModifySnapshotAttribute\n - ModifyInstanceAttribute\n - ImportKeyPair\n - CreateKeyPair\n - DisableEbsEncryptionByDefault\n - DeleteFlowLogs\n # S3 Events\n - PutBucketPublicAccessBlock\n - DeletePublicAccessBlock\n - PutBucketPolicy\n - DeleteBucketPolicy\n - PutBucketAcl\n - PutBucketEncryption\n - DeleteBucketEncryption\n - DeleteBucket\n # RDS Events\n - ModifyDBInstance\n - ModifyDBSnapshotAttribute\n - DeleteDBInstance\n - DeleteDBClusterSnapshot\n - RestoreDBInstanceFromDBSnapshot\n State: ENABLED\n Targets:\n - Arn: !Ref SecurityAlertsTopic\n Id: SNSTarget\n\n OperationsAndSecretsSecurityRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: Lambda, SSM, Secrets Manager, and KMS configuration/management events\n EventPattern:\n source:\n - aws.lambda\n - aws.ssm\n - aws.secretsmanager\n - aws.kms\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventSource:\n - lambda.amazonaws.com\n - ssm.amazonaws.com\n - secretsmanager.amazonaws.com\n - kms.amazonaws.com\n eventName:\n # Lambda, SSM, Secrets Manager\n - AddPermission\n - CreateFunction\n - UpdateFunctionCode\n - CreateEventSourceMapping\n - StartSession\n - PutParameter\n - DeleteParameter\n - DeleteSecret\n - PutResourcePolicy\n # KMS\n - ScheduleKeyDeletion\n - DisableKey\n - DisableKeyRotation\n - PutKeyPolicy\n - DeleteAlias\n - CancelKeyDeletion\n State: ENABLED\n Targets:\n - Arn: !Ref SecurityAlertsTopic\n Id: SNSTarget\n\n AuditAndTamperingSecurityRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: CloudTrail, GuardDuty, Security Hub, and Config auditing or tampering events\n EventPattern:\n source:\n - aws.cloudtrail\n - aws.securityhub\n - aws.guardduty\n - aws.config\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventSource:\n - cloudtrail.amazonaws.com\n - securityhub.amazonaws.com\n - guardduty.amazonaws.com\n - config.amazonaws.com\n eventName:\n # CloudTrail\n - CreateTrail\n - UpdateTrail\n - DeleteTrail\n - StartLogging\n - StopLogging\n - PutEventSelectors\n - DeleteEventDataStore\n # Security Services Tampering\n - BatchDisableStandards\n - DeleteMembers\n - DisassociateMembers\n - DeleteDetector\n - UpdateDetector\n - CreateFilter\n - StopMonitoringMembers\n - DisableSecurityHub\n - StopConfigurationRecorder\n - DeleteConfigurationRecorder\n - DeleteDeliveryChannel\n State: ENABLED\n Targets:\n - Arn: !Ref SecurityAlertsTopic\n Id: SNSTarget\n\n ControlTowerManagedRule:\n Type: AWS::Events::Rule\n DependsOn: SecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: Security Hub findings imported by AWS Control Tower\n EventPattern:\n source:\n - aws.securityhub\n detail-type:\n - Security Hub Findings - Imported\n detail:\n findings:\n Compliance:\n AssociatedStandards:\n StandardsId:\n - prefix: standards/service-managed-aws-control-tower\n State: ENABLED\n Targets:\n - Arn: !Ref SecurityAlertsTopic\n Id: SNSTarget\n\n# ============================================================\n# OUTPUTS\n# ============================================================\n\nOutputs:\n SecurityAlertsTopicArn:\n Description: ARN of the regional security alerts SNS topic\n Value: !Ref SecurityAlertsTopic";
|
|
2
2
|
export declare const GLOBAL_STACK_YAML = "AWSTemplateFormatVersion: '2010-09-09'\nDescription: |\n Meyi Connect Security Monitoring - Global Events Stack (us-east-1). Fully independent of\n the regional Central Stack. Captures IAM, Root Login, Console Login Failure, and AWS Health\n events (all global services that only fire in us-east-1) and delivers them directly to the\n Meyi Connect webhook via Amazon SNS. No cross-region forwarding,\n no shared resources with any other stack.\n\nParameters:\n Environment:\n Type: String\n Default: \"MeyiConnect\"\n Description: Environment name (used as a prefix for resource names)\n\n WebhookUrl:\n Type: String\n Description: MeyiConnect webhook URL for global security alerts.\n\n CreateCloudTrail:\n Type: String\n Default: 'false'\n Description: Dummy parameter for compatibility with meyi-security-monitoring.yaml.\n\n PrimaryRegion:\n Type: String\n Default: 'us-east-1'\n Description: Dummy parameter for compatibility with meyi-security-monitoring.yaml.\n\n DeploymentMode:\n Type: String\n Default: 'Organizations'\n AllowedValues:\n - 'Organizations'\n - 'Standalone'\n Description: Whether this is deployed via AWS Organizations or as a standalone account.\n\nResources:\n\n # ============================================================\n # SNS TOPIC & SUBSCRIPTION FOR GLOBAL ALERTS\n # ============================================================\n\n GlobalSecurityAlertsTopic:\n Type: AWS::SNS::Topic\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n\n GlobalSecurityAlertsTopicPolicy:\n Type: AWS::SNS::TopicPolicy\n Properties:\n Topics:\n - !Ref GlobalSecurityAlertsTopic\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Principal:\n Service: events.amazonaws.com\n Action: sns:Publish\n Resource: !Ref GlobalSecurityAlertsTopic\n\n WebhookSubscription:\n Type: AWS::SNS::Subscription\n Properties:\n TopicArn: !Ref GlobalSecurityAlertsTopic\n Endpoint: !Ref WebhookUrl\n Protocol: https\n\n # ============================================================\n # EVENTBRIDGE RULES - GLOBAL EVENTS\n # IAM, Root Login, Console Login, Health, and Organizations all fire only in us-east-1\n # ============================================================\n\n IAMAndOrganizationsSecurityEventsRule:\n Type: AWS::Events::Rule\n DependsOn: GlobalSecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: IAM and Organizations security configuration changes\n EventPattern:\n source:\n - aws.iam\n - aws.organizations\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n eventName:\n # IAM events\n - CreateUser\n - DeleteUser\n - CreateAccessKey\n - UpdateAccessKey\n - DeleteAccessKey\n - AttachRolePolicy\n - DetachRolePolicy\n - PutUserPolicy\n - PutRolePolicy\n - UpdateAssumeRolePolicy\n - DeactivateMFADevice\n - CreateLoginProfile\n - UpdateLoginProfile\n - DeleteLoginProfile\n - CreateAccountAlias\n - DeleteAccountAlias\n - UpdateAccountPasswordPolicy\n - DeleteAccountPasswordPolicy\n - DeleteGroupPolicy\n - PutGroupPolicy\n - CreatePolicy\n - DeletePolicy\n - CreatePolicyVersion\n - DeletePolicyVersion\n - AttachUserPolicy\n - DetachUserPolicy\n - AttachGroupPolicy\n - DetachGroupPolicy\n - CreateRole\n - DeleteRole\n - CreateSAMLProvider\n - UpdateSAMLProvider\n - CreateOpenIDConnectProvider\n - UpdateOpenIDConnectProvider\n - CreateServiceSpecificCredential\n # Organizations events\n - LeaveOrganization\n - RemoveAccountFromOrganization\n - DeletePolicy\n - DetachPolicy\n - DisablePolicyType\n - UpdatePolicy\n - CreateAccount\n - InviteAccountToOrganization\n State: ENABLED\n Targets:\n - Arn: !Ref GlobalSecurityAlertsTopic\n Id: SNSTarget\n\n ConsoleLoginRule:\n Type: AWS::Events::Rule\n DependsOn: GlobalSecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: Root login, failed console logins, and MFA-not-used console login attempts\n EventPattern:\n detail-type:\n - AWS Console Sign In via CloudTrail\n detail:\n eventName:\n - ConsoleLogin\n $or:\n - userIdentity:\n type:\n - Root\n responseElements:\n ConsoleLogin:\n - Success\n - responseElements:\n ConsoleLogin:\n - Failure\n - responseElements:\n ConsoleLogin:\n - Success\n additionalEventData:\n MFAUsed:\n - \"No\"\n State: ENABLED\n Targets:\n - Arn: !Ref GlobalSecurityAlertsTopic\n Id: SNSTarget\n\n HealthEventsRule:\n Type: AWS::Events::Rule\n DependsOn: GlobalSecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: AWS Health notifications\n EventPattern:\n source:\n - aws.health\n detail-type:\n - AWS Health Event\n State: ENABLED\n Targets:\n - Arn: !Ref GlobalSecurityAlertsTopic\n Id: SNSTarget\n\n RootAPICallsRule:\n Type: AWS::Events::Rule\n DependsOn: GlobalSecurityAlertsTopicPolicy\n Properties:\n Tags:\n - Key: Project\n Value: MeyiConnect\n - Key: Created_for\n Value: L1 Security\n - Key: aws-apn-id\n Value: pc:eyl8vo7kcwv8k9qctzbathhiq\n Description: Capture any API call made by the Root user account in us-east-1\n EventPattern:\n detail-type:\n - AWS API Call via CloudTrail\n detail:\n userIdentity:\n type:\n - Root\n State: ENABLED\n Targets:\n - Arn: !Ref GlobalSecurityAlertsTopic\n Id: SNSTarget\n\n# ============================================================\n# OUTPUTS\n# ============================================================\n\nOutputs:\n TopicArn:\n Description: Global security alerts SNS Topic ARN\n Value: !Ref GlobalSecurityAlertsTopic\n\n RulesDeployed:\n Description: Rules deployed in this stack\n Value: IAMAndOrganizationsSecurityEvents, ConsoleLogin, HealthEvents, RootAPICalls";
|
|
3
3
|
//# sourceMappingURL=stackTemplates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stackTemplates.d.ts","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/stackTemplates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"stackTemplates.d.ts","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/stackTemplates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,wnSA2Sa,CAAC;AAErC,eAAO,MAAM,iBAAiB,u6OAqPyD,CAAC"}
|
|
@@ -188,24 +188,23 @@ Resources:
|
|
|
188
188
|
- secretsmanager.amazonaws.com
|
|
189
189
|
- kms.amazonaws.com
|
|
190
190
|
eventName:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- CancelKeyDeletion
|
|
191
|
+
# Lambda, SSM, Secrets Manager
|
|
192
|
+
- AddPermission
|
|
193
|
+
- CreateFunction
|
|
194
|
+
- UpdateFunctionCode
|
|
195
|
+
- CreateEventSourceMapping
|
|
196
|
+
- StartSession
|
|
197
|
+
- PutParameter
|
|
198
|
+
- DeleteParameter
|
|
199
|
+
- DeleteSecret
|
|
200
|
+
- PutResourcePolicy
|
|
201
|
+
# KMS
|
|
202
|
+
- ScheduleKeyDeletion
|
|
203
|
+
- DisableKey
|
|
204
|
+
- DisableKeyRotation
|
|
205
|
+
- PutKeyPolicy
|
|
206
|
+
- DeleteAlias
|
|
207
|
+
- CancelKeyDeletion
|
|
209
208
|
State: ENABLED
|
|
210
209
|
Targets:
|
|
211
210
|
- Arn: !Ref SecurityAlertsTopic
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stackTemplates.js","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/stackTemplates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"stackTemplates.js","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/stackTemplates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCA2SU,CAAC;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uFAqPsD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,sBAAsB,QAUxB,CAAC;
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,sBAAsB,QAUxB,CAAC;AA4zCZ,wBAAgB,mCAAmC,CAAC,KAAK,EAAE;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,eAAe,GAAG,YAAY,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAqBT"}
|
|
@@ -34,6 +34,7 @@ Metadata:
|
|
|
34
34
|
Parameters:
|
|
35
35
|
- DeploymentMode
|
|
36
36
|
- CreateIAMRoles
|
|
37
|
+
- DeployToManagementAccount
|
|
37
38
|
- TargetOUs
|
|
38
39
|
- TargetAccounts
|
|
39
40
|
- TargetRegions
|
|
@@ -59,6 +60,8 @@ Metadata:
|
|
|
59
60
|
default: "Deployment Mode"
|
|
60
61
|
CreateIAMRoles:
|
|
61
62
|
default: "Create StackSet IAM Roles?"
|
|
63
|
+
DeployToManagementAccount:
|
|
64
|
+
default: "Also deploy to this (management) account?"
|
|
62
65
|
TargetOUs:
|
|
63
66
|
default: "Target Organizational Unit IDs (comma separated)"
|
|
64
67
|
TargetAccounts:
|
|
@@ -95,7 +98,15 @@ Parameters:
|
|
|
95
98
|
AllowedValues:
|
|
96
99
|
- 'true'
|
|
97
100
|
- 'false'
|
|
98
|
-
Description: "Create standard AWSCloudFormationStackSetAdministrationRole and AWSCloudFormationStackSetExecutionRole?
|
|
101
|
+
Description: "Create standard AWSCloudFormationStackSetAdministrationRole and AWSCloudFormationStackSetExecutionRole? Used in Standalone mode, and in Organizations mode when DeployToManagementAccount is true. Set to false if these roles already exist in this account."
|
|
102
|
+
|
|
103
|
+
DeployToManagementAccount:
|
|
104
|
+
Type: String
|
|
105
|
+
Default: 'true'
|
|
106
|
+
AllowedValues:
|
|
107
|
+
- 'true'
|
|
108
|
+
- 'false'
|
|
109
|
+
Description: "Organizations mode only. Service-managed StackSets never deploy to the management account, so when true this stack also deploys the same monitoring to THIS account through two additional self-managed StackSets."
|
|
99
110
|
|
|
100
111
|
TargetOUs:
|
|
101
112
|
Type: CommaDelimitedList
|
|
@@ -141,7 +152,8 @@ Conditions:
|
|
|
141
152
|
HasTargetAccounts: !Not [ !Equals [ !Join [ "", !Ref TargetAccounts ], "" ] ]
|
|
142
153
|
IsServiceManaged: !Equals [ !Ref DeploymentMode, 'Organizations' ]
|
|
143
154
|
IsSelfManaged: !Equals [ !Ref DeploymentMode, 'Standalone' ]
|
|
144
|
-
|
|
155
|
+
DeployManagement: !And [ !Condition IsServiceManaged, !Equals [ !Ref DeployToManagementAccount, 'true' ] ]
|
|
156
|
+
ShouldCreateRoles: !And [ !Or [ !Condition IsSelfManaged, !Condition DeployManagement ], !Equals [ !Ref CreateIAMRoles, 'true' ] ]
|
|
145
157
|
ShouldCreateStackInstances: !Or [ !Condition IsSelfManaged, !Condition HasTargetOUs ]
|
|
146
158
|
|
|
147
159
|
Resources:
|
|
@@ -229,6 +241,8 @@ Resources:
|
|
|
229
241
|
- cloudtrail:GetTrailStatus
|
|
230
242
|
- cloudtrail:StartLogging
|
|
231
243
|
- cloudtrail:StopLogging
|
|
244
|
+
- cloudtrail:PutEventSelectors
|
|
245
|
+
- cloudtrail:GetEventSelectors
|
|
232
246
|
- cloudtrail:ListTags
|
|
233
247
|
- cloudtrail:AddTags
|
|
234
248
|
- cloudtrail:RemoveTags
|
|
@@ -260,6 +274,45 @@ Resources:
|
|
|
260
274
|
- events:UntagResource
|
|
261
275
|
- events:ListTagsForResource
|
|
262
276
|
Resource: !Sub "arn:aws:events:*:\${AWS::AccountId}:rule/\${AWS::StackName}-*"
|
|
277
|
+
- Sid: EventBridgeApiDestinationOperations
|
|
278
|
+
Effect: Allow
|
|
279
|
+
Action:
|
|
280
|
+
- events:CreateConnection
|
|
281
|
+
- events:UpdateConnection
|
|
282
|
+
- events:DeleteConnection
|
|
283
|
+
- events:DescribeConnection
|
|
284
|
+
- events:CreateApiDestination
|
|
285
|
+
- events:UpdateApiDestination
|
|
286
|
+
- events:DeleteApiDestination
|
|
287
|
+
- events:DescribeApiDestination
|
|
288
|
+
Resource:
|
|
289
|
+
- !Sub "arn:aws:events:*:\${AWS::AccountId}:connection/\${AWS::StackName}-*"
|
|
290
|
+
- !Sub "arn:aws:events:*:\${AWS::AccountId}:api-destination/\${AWS::StackName}-*"
|
|
291
|
+
- Sid: EventBridgeConnectionSecret
|
|
292
|
+
Effect: Allow
|
|
293
|
+
Action:
|
|
294
|
+
- secretsmanager:CreateSecret
|
|
295
|
+
- secretsmanager:UpdateSecret
|
|
296
|
+
- secretsmanager:DeleteSecret
|
|
297
|
+
- secretsmanager:DescribeSecret
|
|
298
|
+
- secretsmanager:GetSecretValue
|
|
299
|
+
- secretsmanager:PutSecretValue
|
|
300
|
+
Resource: !Sub "arn:aws:secretsmanager:*:\${AWS::AccountId}:secret:events!connection/*"
|
|
301
|
+
- Sid: ApiDestinationInvokeRole
|
|
302
|
+
Effect: Allow
|
|
303
|
+
Action:
|
|
304
|
+
- iam:CreateRole
|
|
305
|
+
- iam:DeleteRole
|
|
306
|
+
- iam:GetRole
|
|
307
|
+
- iam:PutRolePolicy
|
|
308
|
+
- iam:DeleteRolePolicy
|
|
309
|
+
- iam:GetRolePolicy
|
|
310
|
+
- iam:TagRole
|
|
311
|
+
- iam:UntagRole
|
|
312
|
+
- iam:PassRole
|
|
313
|
+
Resource:
|
|
314
|
+
- !Sub "arn:aws:iam::\${AWS::AccountId}:role/\${AWS::StackName}-EbRole-*"
|
|
315
|
+
- !Sub "arn:aws:iam::\${AWS::AccountId}:role/\${AWS::StackName}-GlEbRole-*"
|
|
263
316
|
|
|
264
317
|
# ============================================================
|
|
265
318
|
# STACKSET
|
|
@@ -599,24 +652,23 @@ Resources:
|
|
|
599
652
|
- secretsmanager.amazonaws.com
|
|
600
653
|
- kms.amazonaws.com
|
|
601
654
|
eventName:
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
- CancelKeyDeletion
|
|
655
|
+
# Lambda, SSM, Secrets Manager
|
|
656
|
+
- AddPermission
|
|
657
|
+
- CreateFunction
|
|
658
|
+
- UpdateFunctionCode
|
|
659
|
+
- CreateEventSourceMapping
|
|
660
|
+
- StartSession
|
|
661
|
+
- PutParameter
|
|
662
|
+
- DeleteParameter
|
|
663
|
+
- DeleteSecret
|
|
664
|
+
- PutResourcePolicy
|
|
665
|
+
# KMS
|
|
666
|
+
- ScheduleKeyDeletion
|
|
667
|
+
- DisableKey
|
|
668
|
+
- DisableKeyRotation
|
|
669
|
+
- PutKeyPolicy
|
|
670
|
+
- DeleteAlias
|
|
671
|
+
- CancelKeyDeletion
|
|
620
672
|
State: ENABLED
|
|
621
673
|
Targets:
|
|
622
674
|
- Id: ApiDestinationTarget
|
|
@@ -1089,6 +1141,7 @@ Resources:
|
|
|
1089
1141
|
- Key: aws-apn-id
|
|
1090
1142
|
Value: pc:eyl8vo7kcwv8k9qctzbathhiq
|
|
1091
1143
|
|
|
1144
|
+
__MEYI_MANAGEMENT_STACKSETS__
|
|
1092
1145
|
# ============================================================
|
|
1093
1146
|
# EVENTBRIDGE API DESTINATION & CONNECTION (PARENT STACKSET STATUS)
|
|
1094
1147
|
# ============================================================
|
|
@@ -1230,15 +1283,87 @@ Outputs:
|
|
|
1230
1283
|
Backend: \${BackendUrl}
|
|
1231
1284
|
|
|
1232
1285
|
`;
|
|
1286
|
+
/**
|
|
1287
|
+
* Service-managed StackSets never deploy to the Organizations management account.
|
|
1288
|
+
* To cover it from the same stack, clone the two StackSets above as self-managed
|
|
1289
|
+
* StackSets that target only this account, reusing their inline TemplateBody.
|
|
1290
|
+
*/
|
|
1291
|
+
function buildManagementStackSets(yaml) {
|
|
1292
|
+
const bodyOf = (resource) => {
|
|
1293
|
+
const start = yaml.indexOf(` ${resource}:\n`);
|
|
1294
|
+
if (start < 0)
|
|
1295
|
+
throw new Error(`Template resource not found: ${resource}`);
|
|
1296
|
+
const from = yaml.indexOf(' TemplateBody: |\n', start);
|
|
1297
|
+
const to = yaml.indexOf(' PermissionModel:', from);
|
|
1298
|
+
if (from < 0 || to < 0)
|
|
1299
|
+
throw new Error(`TemplateBody not found: ${resource}`);
|
|
1300
|
+
return yaml.slice(from, to);
|
|
1301
|
+
};
|
|
1302
|
+
const build = (id, suffix, description, body, regions) => ` ${id}:
|
|
1303
|
+
Type: AWS::CloudFormation::StackSet
|
|
1304
|
+
Condition: DeployManagement
|
|
1305
|
+
DependsOn:
|
|
1306
|
+
- StackSetApiDestination
|
|
1307
|
+
- StackSetOperationRule
|
|
1308
|
+
Properties:
|
|
1309
|
+
StackSetName: !Sub "\${AWS::StackName}-SecurityMonitoring${suffix}-Mgmt"
|
|
1310
|
+
Description: !Sub "\${AWS::StackName} ${description} (management account)"
|
|
1311
|
+
${body} PermissionModel: SELF_MANAGED
|
|
1312
|
+
AdministrationRoleARN: !If
|
|
1313
|
+
- ShouldCreateRoles
|
|
1314
|
+
- !GetAtt StackSetAdministrationRole.Arn
|
|
1315
|
+
- !Sub "arn:aws:iam::\${AWS::AccountId}:role/AWSCloudFormationStackSetAdministrationRole"
|
|
1316
|
+
ExecutionRoleName: AWSCloudFormationStackSetExecutionRole
|
|
1317
|
+
Parameters:
|
|
1318
|
+
- ParameterKey: ParentStackName
|
|
1319
|
+
ParameterValue: !Ref "AWS::StackName"
|
|
1320
|
+
- ParameterKey: WebhookUrl
|
|
1321
|
+
ParameterValue: !Ref WebhookUrl
|
|
1322
|
+
- ParameterKey: WebhookAuthToken
|
|
1323
|
+
ParameterValue: !Ref WebhookAuthToken
|
|
1324
|
+
- ParameterKey: CreateCloudTrail
|
|
1325
|
+
ParameterValue: !Ref CreateCloudTrail
|
|
1326
|
+
- ParameterKey: PrimaryRegion
|
|
1327
|
+
ParameterValue: !Ref PrimaryRegion
|
|
1328
|
+
StackInstancesGroup:
|
|
1329
|
+
- DeploymentTargets:
|
|
1330
|
+
Accounts:
|
|
1331
|
+
- !Ref AWS::AccountId
|
|
1332
|
+
Regions: ${regions}
|
|
1333
|
+
OperationPreferences:
|
|
1334
|
+
MaxConcurrentPercentage: 50
|
|
1335
|
+
FailureToleranceCount: 1
|
|
1336
|
+
RegionConcurrencyType: PARALLEL
|
|
1337
|
+
Capabilities:
|
|
1338
|
+
- CAPABILITY_NAMED_IAM
|
|
1339
|
+
Tags:
|
|
1340
|
+
- Key: Project
|
|
1341
|
+
Value: MeyiConnectSecurityMonitoring
|
|
1342
|
+
- Key: Created_for
|
|
1343
|
+
Value: L1 Security
|
|
1344
|
+
- Key: aws-apn-id
|
|
1345
|
+
Value: pc:eyl8vo7kcwv8k9qctzbathhiq
|
|
1346
|
+
|
|
1347
|
+
`;
|
|
1348
|
+
return [
|
|
1349
|
+
' # ============================================================',
|
|
1350
|
+
' # MANAGEMENT ACCOUNT STACKSETS (self-managed, Organizations mode only)',
|
|
1351
|
+
' # ============================================================',
|
|
1352
|
+
'',
|
|
1353
|
+
build('ManagementSecurityMonitoringStackSet', '', 'Security Monitoring (regional logs)', bodyOf('SecurityMonitoringStackSet'), '!Ref TargetRegions'),
|
|
1354
|
+
build('ManagementGlobalSecurityMonitoringStackSet', '-Global', 'Global Security Monitoring (us-east-1 only)', bodyOf('GlobalSecurityMonitoringStackSet'), '[ us-east-1 ]'),
|
|
1355
|
+
].join('\n');
|
|
1356
|
+
}
|
|
1233
1357
|
export function buildCloudTrailCentralStackTemplate(input) {
|
|
1234
1358
|
const mode = input.deploymentMode ?? 'Standalone';
|
|
1235
|
-
const createIAMRoles =
|
|
1359
|
+
const createIAMRoles = 'true';
|
|
1236
1360
|
const targetOUs = input.targetOUs ?? '';
|
|
1237
1361
|
const targetAccounts = input.targetAccounts ?? '';
|
|
1238
1362
|
const resolvedRegions = (input.targetRegions ?? '').trim() || ALL_AWS_ACTIVE_REGIONS;
|
|
1239
1363
|
const primaryRegion = resolvedRegions.split(',')[0].trim() || 'us-east-1';
|
|
1240
1364
|
const createCloudTrailDefault = input.createCloudTrail ? "true" : "false";
|
|
1241
1365
|
return CENTRAL_STACK_YAML
|
|
1366
|
+
.replace(/__MEYI_MANAGEMENT_STACKSETS__/g, buildManagementStackSets(CENTRAL_STACK_YAML))
|
|
1242
1367
|
.replace(/__MEYI_WEBHOOK_URL__/g, input.webhookUrl)
|
|
1243
1368
|
.replace(/__MEYI_WEBHOOK_AUTH_TOKEN__/g, input.webhookAuthToken || '')
|
|
1244
1369
|
.replace(/__MEYI_DEPLOYMENT_STATUS_URL__/g, input.deploymentStatusUrl)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW;IAClD,cAAc;IACd,WAAW,EAAE,WAAW,EAAE,WAAW;IACrC,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,gBAAgB,EAAE,gBAAgB;IAClC,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB;IACpD,WAAW;CACZ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,kBAAkB,GAAG
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/features/sources/cloudtrail/template.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/migrations/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/migrations/run.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAiiD1D"}
|
package/dist/migrations/run.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { sql } from "drizzle-orm";
|
|
2
2
|
import yaml from "js-yaml";
|
|
3
|
+
import { isMultiTenantEnabled } from "../tenancy.js";
|
|
3
4
|
/**
|
|
4
5
|
* Run all DDL migrations for the Insight plugin.
|
|
5
6
|
* Safe to run on every start - all statements use IF NOT EXISTS / IF EXISTS guards.
|
|
6
7
|
*/
|
|
7
8
|
export async function runMigrations(db) {
|
|
8
|
-
|
|
9
|
+
// Standalone single-tenant mode keeps one tenant that owns everything. A
|
|
10
|
+
// multi-tenant host (Meyi Connect) has no default tenant: nothing is created
|
|
11
|
+
// for one and no row is assigned to one.
|
|
12
|
+
const defaultTenantId = isMultiTenantEnabled()
|
|
13
|
+
? ""
|
|
14
|
+
: (process.env.INSIGHT_DEFAULT_TENANT_ID || "default").trim() || "default";
|
|
9
15
|
const defaultTenantSql = defaultTenantId.replace(/'/g, "''");
|
|
16
|
+
const backfill = async (statement) => {
|
|
17
|
+
if (defaultTenantId)
|
|
18
|
+
await db.execute(sql.raw(statement));
|
|
19
|
+
};
|
|
10
20
|
const defaultTokenTtlDaysRaw = Number.parseInt(process.env.INSIGHT_WEBHOOK_TOKEN_DEFAULT_DAYS || "30", 10);
|
|
11
21
|
const defaultTokenTtlDays = Number.isFinite(defaultTokenTtlDaysRaw) && defaultTokenTtlDaysRaw > 0
|
|
12
22
|
? defaultTokenTtlDaysRaw
|
|
@@ -111,13 +121,13 @@ export async function runMigrations(db) {
|
|
|
111
121
|
"created_at" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
112
122
|
"updated_at" TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
113
123
|
);
|
|
114
|
-
INSERT INTO "meyiconnect"."insight_tenants" ("id", "name", "is_default")
|
|
124
|
+
${defaultTenantId ? `INSERT INTO "meyiconnect"."insight_tenants" ("id", "name", "is_default")
|
|
115
125
|
VALUES ('${defaultTenantSql}', 'Default tenant', true)
|
|
116
|
-
ON CONFLICT ("id") DO UPDATE SET "is_default" = true, "updated_at" = NOW();
|
|
126
|
+
ON CONFLICT ("id") DO UPDATE SET "is_default" = true, "updated_at" = NOW();` : "NULL;"}
|
|
117
127
|
ELSIF v_relkind = 'r' THEN
|
|
118
|
-
INSERT INTO "meyiconnect"."insight_tenants" ("id", "name", "is_default")
|
|
128
|
+
${defaultTenantId ? `INSERT INTO "meyiconnect"."insight_tenants" ("id", "name", "is_default")
|
|
119
129
|
VALUES ('${defaultTenantSql}', 'Default tenant', true)
|
|
120
|
-
ON CONFLICT ("id") DO UPDATE SET "is_default" = true, "updated_at" = NOW();
|
|
130
|
+
ON CONFLICT ("id") DO UPDATE SET "is_default" = true, "updated_at" = NOW();` : "NULL;"}
|
|
121
131
|
END IF;
|
|
122
132
|
END $$;
|
|
123
133
|
`));
|
|
@@ -153,7 +163,7 @@ export async function runMigrations(db) {
|
|
|
153
163
|
END IF;
|
|
154
164
|
END $$;
|
|
155
165
|
`));
|
|
156
|
-
await
|
|
166
|
+
await backfill(`UPDATE "meyiconnect"."insight_sources" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id"::text = ''`);
|
|
157
167
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_sources_tenant_id_idx ON "meyiconnect"."insight_sources" ("tenant_id")`));
|
|
158
168
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_sources" ADD COLUMN IF NOT EXISTS "webhook_token_never_expires" BOOLEAN NOT NULL DEFAULT false`));
|
|
159
169
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_sources" ADD COLUMN IF NOT EXISTS "webhook_token_expires_at" TIMESTAMPTZ`));
|
|
@@ -430,7 +440,7 @@ export async function runMigrations(db) {
|
|
|
430
440
|
ADD COLUMN IF NOT EXISTS "aws_secret_access_key" TEXT,
|
|
431
441
|
ADD COLUMN IF NOT EXISTS "aws_region" TEXT
|
|
432
442
|
`));
|
|
433
|
-
await
|
|
443
|
+
await backfill(`UPDATE "meyiconnect"."insight_projects" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id"::text = ''`);
|
|
434
444
|
await db.execute(sql.raw(`DROP INDEX IF EXISTS "meyiconnect"."insight_projects_tag_unique"`)).catch(() => { });
|
|
435
445
|
await db.execute(sql.raw(`DROP INDEX IF EXISTS insight_projects_tag_unique`)).catch(() => { });
|
|
436
446
|
await db.execute(sql.raw(`CREATE UNIQUE INDEX IF NOT EXISTS insight_projects_tenant_tag_unique ON "meyiconnect"."insight_projects" ("tenant_id", "tag")`));
|
|
@@ -486,7 +496,7 @@ export async function runMigrations(db) {
|
|
|
486
496
|
END IF;
|
|
487
497
|
END $$;
|
|
488
498
|
`));
|
|
489
|
-
await
|
|
499
|
+
await backfill(`UPDATE "meyiconnect"."insight_incidents" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id"::text = ''`);
|
|
490
500
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_incidents_tenant_id_idx ON "meyiconnect"."insight_incidents" ("tenant_id")`));
|
|
491
501
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_incidents" ADD COLUMN IF NOT EXISTS "incident_down_time" TEXT NOT NULL DEFAULT ''`));
|
|
492
502
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_incidents" ADD COLUMN IF NOT EXISTS "name" TEXT`));
|
|
@@ -628,7 +638,7 @@ export async function runMigrations(db) {
|
|
|
628
638
|
END IF;
|
|
629
639
|
END $$;
|
|
630
640
|
`));
|
|
631
|
-
await
|
|
641
|
+
await backfill(`UPDATE "meyiconnect"."insight_alerts" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id"::text = ''`);
|
|
632
642
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_alerts_tenant_id_idx ON "meyiconnect"."insight_alerts" ("tenant_id")`));
|
|
633
643
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_alerts" ADD COLUMN IF NOT EXISTS "alias_id" TEXT`));
|
|
634
644
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_alerts" ADD COLUMN IF NOT EXISTS "additional_configuration" JSONB`));
|
|
@@ -744,7 +754,7 @@ export async function runMigrations(db) {
|
|
|
744
754
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_settings" ADD COLUMN IF NOT EXISTS "aws_bedrock_secret_access_key" TEXT`));
|
|
745
755
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_settings" ADD COLUMN IF NOT EXISTS "aws_bedrock_region" TEXT`));
|
|
746
756
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_settings" ADD COLUMN IF NOT EXISTS "tenant_id" TEXT`));
|
|
747
|
-
await
|
|
757
|
+
await backfill(`UPDATE "meyiconnect"."insight_settings" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id" = ''`);
|
|
748
758
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_settings_tenant_id_idx ON "meyiconnect"."insight_settings" ("tenant_id")`));
|
|
749
759
|
// notification_providers
|
|
750
760
|
await db.execute(sql.raw(`
|
|
@@ -762,7 +772,7 @@ export async function runMigrations(db) {
|
|
|
762
772
|
)
|
|
763
773
|
`));
|
|
764
774
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."notification_providers" ADD COLUMN IF NOT EXISTS "tenant_id" TEXT`)).catch(() => { });
|
|
765
|
-
await
|
|
775
|
+
await backfill(`UPDATE "meyiconnect"."notification_providers" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id"::text = ''`).catch(() => { });
|
|
766
776
|
await db.execute(sql.raw(`DROP INDEX IF EXISTS "meyiconnect"."notification_providers_provider_name_unique"`)).catch(() => { });
|
|
767
777
|
await db.execute(sql.raw(`DROP INDEX IF EXISTS notification_providers_provider_name_unique`)).catch(() => { });
|
|
768
778
|
await db.execute(sql.raw(`CREATE UNIQUE INDEX IF NOT EXISTS notification_providers_tenant_name_unique ON "meyiconnect"."notification_providers" ("tenant_id", "provider_name")`)).catch(() => { });
|
|
@@ -869,7 +879,7 @@ export async function runMigrations(db) {
|
|
|
869
879
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_sops" ADD COLUMN IF NOT EXISTS "project" TEXT`));
|
|
870
880
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_sops" ADD COLUMN IF NOT EXISTS "ai_model_used" TEXT`));
|
|
871
881
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_sops" ADD COLUMN IF NOT EXISTS "tenant_id" TEXT`));
|
|
872
|
-
await
|
|
882
|
+
await backfill(`UPDATE "meyiconnect"."insight_sops" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id" = ''`);
|
|
873
883
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_sops_tenant_id_idx ON "meyiconnect"."insight_sops" ("tenant_id")`));
|
|
874
884
|
await db.execute(sql.raw(`CREATE UNIQUE INDEX IF NOT EXISTS insight_sops_tenant_sop_id_unique ON "meyiconnect"."insight_sops" ("tenant_id", "sop_id")`));
|
|
875
885
|
// incident_evidence
|
|
@@ -904,7 +914,7 @@ export async function runMigrations(db) {
|
|
|
904
914
|
`));
|
|
905
915
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_workflows" ADD COLUMN IF NOT EXISTS "tenant_id" TEXT`));
|
|
906
916
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_workflows" ADD COLUMN IF NOT EXISTS "source_id" UUID REFERENCES "meyiconnect"."insight_sources"("id") ON DELETE CASCADE`));
|
|
907
|
-
await
|
|
917
|
+
await backfill(`UPDATE "meyiconnect"."insight_workflows" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id" = ''`);
|
|
908
918
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_workflows_tenant_id_idx ON "meyiconnect"."insight_workflows" ("tenant_id")`));
|
|
909
919
|
await db.execute(sql.raw(`
|
|
910
920
|
ALTER TABLE "meyiconnect"."insight_workflows"
|
|
@@ -937,12 +947,12 @@ export async function runMigrations(db) {
|
|
|
937
947
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_workflow_executions" ADD COLUMN IF NOT EXISTS "tenant_id" TEXT`));
|
|
938
948
|
await db.execute(sql.raw(`
|
|
939
949
|
UPDATE "meyiconnect"."insight_workflow_executions" e
|
|
940
|
-
SET "tenant_id" = COALESCE(w."tenant_id", '${defaultTenantSql}')
|
|
950
|
+
SET "tenant_id" = ${defaultTenantId ? `COALESCE(w."tenant_id", '${defaultTenantSql}')` : `w."tenant_id"`}
|
|
941
951
|
FROM "meyiconnect"."insight_workflows" w
|
|
942
952
|
WHERE e."workflow_id" = w."id"
|
|
943
953
|
AND (e."tenant_id" IS NULL OR e."tenant_id" = '')
|
|
944
954
|
`));
|
|
945
|
-
await
|
|
955
|
+
await backfill(`UPDATE "meyiconnect"."insight_workflow_executions" SET "tenant_id" = '${defaultTenantSql}' WHERE "tenant_id" IS NULL OR "tenant_id" = ''`);
|
|
946
956
|
await db.execute(sql.raw(`CREATE INDEX IF NOT EXISTS insight_workflow_executions_tenant_id_idx ON "meyiconnect"."insight_workflow_executions" ("tenant_id")`));
|
|
947
957
|
// ─── insight_alerts pipeline columns (Phase 1) ───────────────────────────────
|
|
948
958
|
await db.execute(sql.raw(`ALTER TABLE "meyiconnect"."insight_alerts" ADD COLUMN IF NOT EXISTS "fingerprint" TEXT`));
|
|
@@ -1439,6 +1449,11 @@ export async function runMigrations(db) {
|
|
|
1439
1449
|
// the same column, so either host can migrate first.
|
|
1440
1450
|
await db.execute(sql.raw(`
|
|
1441
1451
|
ALTER TABLE "meyiconnect"."ai_usage_log" ADD COLUMN IF NOT EXISTS "report_id" TEXT;
|
|
1452
|
+
`));
|
|
1453
|
+
// The AI usage API (src/features/ai-usage) reads a tenant's rows by time window.
|
|
1454
|
+
await db.execute(sql.raw(`
|
|
1455
|
+
CREATE INDEX IF NOT EXISTS ai_usage_log_tenant_created_idx
|
|
1456
|
+
ON "meyiconnect"."ai_usage_log" ("tenant_id", "created_at" DESC);
|
|
1442
1457
|
`));
|
|
1443
1458
|
// ─── insight_incidents.priority ───────────────────────────────────────────
|
|
1444
1459
|
// P1..P4. The default is set before the backfill so rows inserted meanwhile (e.g. by a server that
|