mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
* fix(security): restrict Neptune cookbook SG, add VPC flow logs, harden IaC scan suppressions
Addresses open GHAS code scanning alerts:
- Neptune cookbook stack (neptune-setup.yaml) no longer opens the Bolt/OpenCypher
port to 0.0.0.0/0; a required ClientCidr parameter must be supplied instead.
Updated 21_Amazon_Neptune_Store.ipynb deploy instructions to match.
- Added VPC Flow Logs (CloudWatch Logs + IAM role) to the same stack.
- Documented why an account-wide IAM password policy resource does not belong
in a disposable per-learner CFN stack, with a justified ts:skip.
- Added inline `checkov:skip` / `ts:skip` comments to the knowledge-explorer
Helm templates (deployment/service/configmap) as a second suppression path
for the CKV_K8S_21/AC_K8S_0086/AC_K8S_0080 false positives, since the prior
annotation-only suppression was not being honored by the scanner.
* docs(changelog): document the Neptune and Helm chart security scan fixes
* fix(security): correct flow-log IAM scope and ClientCidr regex from review
- FlowLogRole granted logs:CreateLogStream/PutLogEvents on the bare log
group ARN, but those actions apply to log streams, not the group itself;
scoped them to "${FlowLogGroup.Arn}:log-stream:*" instead and moved the
Describe* actions (which don't support group/stream-level resource
restriction) to Resource: "*", matching AWS's documented flow-log IAM
policy shape. Without this, flow log delivery could silently fail.
- ClientCidr's AllowedPattern only checked digit count (1-3 digits per
octet), so malformed values like 999.999.999.999/32 passed parameter
validation and would only fail later when CloudFormation tried to
create the security group rule. Tightened the regex to enforce valid
IPv4 octet ranges (0-255) and prefix lengths (0-32).
* fix(security): harden IAM policy in neptune-setup and standardize Helm chart scan suppressions
- neptune-setup.yaml: split FlowLogRole policy into account-level statement (CreateLogGroup, DescribeLogGroups, DescribeLogStreams with Resource: '*') and log-group-scoped statement (CreateLogStream, PutLogEvents with !GetAtt FlowLogGroup.Arn) per AWS VPC Flow Logs least-privilege documentation.
- deployment.yaml: remove unreliable file-header skip comments (# checkov:skip / # ts:skip) and replace with resource-level metadata.annotations (checkov.io/skip and runterrascan.io/skip). Update seccomp rule ID from CKV_K8S_28 to checkov's actual seccomp rule CKV_K8S_31 on both Deployment and pod-template metadata.
- configmap.yaml / service.yaml: remove stale # ts:skip=AC_K8S_0086 file-header comments and add runterrascan.io/skip resource-level metadata annotations for consistency across all chart templates.
- .checkov.yaml: update documentation to explain resource-level metadata.annotations and reference CKV_K8S_31.
---------
Co-authored-by: Sameer6305 <sskadam6305@gmail.com>
299 lines
9.6 KiB
YAML
299 lines
9.6 KiB
YAML
# ts:skip=AC_AWS_0148 IAM password policy is an AWS-account-wide singleton, not a
|
|
# per-stack resource. Managing it here would mean every learner who deploys or
|
|
# deletes this cookbook stack also mutates (or removes) their account's password
|
|
# policy as a side effect. Account password policy should be set once, out of
|
|
# band, by the account owner - not by a disposable tutorial stack.
|
|
AWSTemplateFormatVersion: '2010-09-09'
|
|
Description: >
|
|
Amazon Neptune cluster with public endpoint, IAM authentication, and least-privilege
|
|
IAM user for Semantica cookbook. Uses db.t3.medium (most cost-effective Neptune instance type).
|
|
Network access to the Bolt/OpenCypher port is restricted to an operator-supplied CIDR
|
|
(see ClientCidr) - do not widen this to 0.0.0.0/0 outside of a short-lived local experiment.
|
|
|
|
Parameters:
|
|
EnvironmentName:
|
|
Type: String
|
|
Default: semantica-neptune
|
|
Description: Environment name prefix for resource naming
|
|
|
|
ClientCidr:
|
|
Type: String
|
|
Description: >-
|
|
CIDR block allowed to reach the Neptune Bolt/OpenCypher endpoint (port 8182) - e.g. your
|
|
workstation's public IP as "x.x.x.x/32", or your office/VPN CIDR. Required: there is no
|
|
default, so you must explicitly choose a range. Passing 0.0.0.0/0 is possible but exposes
|
|
the database to the entire internet and is strongly discouraged beyond a brief local test.
|
|
AllowedPattern: '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[12]?[0-9])$'
|
|
ConstraintDescription: Must be a valid IPv4 CIDR block with octets 0-255 and prefix 0-32, e.g. 203.0.113.25/32
|
|
|
|
Resources:
|
|
# =============================================================================
|
|
# VPC & NETWORKING
|
|
# =============================================================================
|
|
|
|
VPC:
|
|
Type: AWS::EC2::VPC
|
|
Properties:
|
|
CidrBlock: 10.0.0.0/16
|
|
EnableDnsHostnames: true
|
|
EnableDnsSupport: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-vpc
|
|
|
|
InternetGateway:
|
|
Type: AWS::EC2::InternetGateway
|
|
Properties:
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-igw
|
|
|
|
InternetGatewayAttachment:
|
|
Type: AWS::EC2::VPCGatewayAttachment
|
|
Properties:
|
|
InternetGatewayId: !Ref InternetGateway
|
|
VpcId: !Ref VPC
|
|
|
|
PublicSubnet1:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId: !Ref VPC
|
|
AvailabilityZone: !Select [0, !GetAZs '']
|
|
CidrBlock: 10.0.1.0/24
|
|
MapPublicIpOnLaunch: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-public-subnet-1
|
|
|
|
PublicSubnet2:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId: !Ref VPC
|
|
AvailabilityZone: !Select [1, !GetAZs '']
|
|
CidrBlock: 10.0.2.0/24
|
|
MapPublicIpOnLaunch: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-public-subnet-2
|
|
|
|
PublicRouteTable:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId: !Ref VPC
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-public-rt
|
|
|
|
DefaultPublicRoute:
|
|
Type: AWS::EC2::Route
|
|
DependsOn: InternetGatewayAttachment
|
|
Properties:
|
|
RouteTableId: !Ref PublicRouteTable
|
|
DestinationCidrBlock: 0.0.0.0/0
|
|
GatewayId: !Ref InternetGateway
|
|
|
|
PublicSubnet1RouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
RouteTableId: !Ref PublicRouteTable
|
|
SubnetId: !Ref PublicSubnet1
|
|
|
|
PublicSubnet2RouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
RouteTableId: !Ref PublicRouteTable
|
|
SubnetId: !Ref PublicSubnet2
|
|
|
|
# =============================================================================
|
|
# VPC FLOW LOGS
|
|
# =============================================================================
|
|
|
|
FlowLogGroup:
|
|
Type: AWS::Logs::LogGroup
|
|
Properties:
|
|
LogGroupName: !Sub /aws/vpc/${EnvironmentName}-flow-logs
|
|
RetentionInDays: 30
|
|
|
|
FlowLogRole:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
RoleName: !Sub ${EnvironmentName}-flow-log-role
|
|
AssumeRolePolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service: vpc-flow-logs.amazonaws.com
|
|
Action: sts:AssumeRole
|
|
Policies:
|
|
- PolicyName: flow-log-publish
|
|
PolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- logs:CreateLogGroup
|
|
- logs:DescribeLogGroups
|
|
- logs:DescribeLogStreams
|
|
Resource: "*"
|
|
- Effect: Allow
|
|
Action:
|
|
- logs:CreateLogStream
|
|
- logs:PutLogEvents
|
|
Resource: !GetAtt FlowLogGroup.Arn
|
|
|
|
VPCFlowLog:
|
|
Type: AWS::EC2::FlowLog
|
|
Properties:
|
|
ResourceType: VPC
|
|
ResourceId: !Ref VPC
|
|
TrafficType: ALL
|
|
LogDestinationType: cloud-watch-logs
|
|
LogGroupName: !Ref FlowLogGroup
|
|
DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-vpc-flow-log
|
|
|
|
# =============================================================================
|
|
# SECURITY GROUP
|
|
# =============================================================================
|
|
|
|
NeptuneSecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupName: !Sub ${EnvironmentName}-neptune-sg
|
|
GroupDescription: Security group for Neptune cluster - allows Bolt protocol access from ClientCidr only
|
|
VpcId: !Ref VPC
|
|
SecurityGroupIngress:
|
|
- IpProtocol: tcp
|
|
FromPort: 8182
|
|
ToPort: 8182
|
|
CidrIp: !Ref ClientCidr
|
|
Description: Allow Bolt/OpenCypher protocol access from the operator-specified CIDR
|
|
SecurityGroupEgress:
|
|
- IpProtocol: -1
|
|
CidrIp: 0.0.0.0/0
|
|
Description: Allow all outbound traffic
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-neptune-sg
|
|
|
|
# =============================================================================
|
|
# NEPTUNE CLUSTER
|
|
# =============================================================================
|
|
|
|
NeptuneSubnetGroup:
|
|
Type: AWS::Neptune::DBSubnetGroup
|
|
Properties:
|
|
DBSubnetGroupDescription: Subnet group for Neptune cluster
|
|
DBSubnetGroupName: !Sub ${EnvironmentName}-subnet-group
|
|
SubnetIds:
|
|
- !Ref PublicSubnet1
|
|
- !Ref PublicSubnet2
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-subnet-group
|
|
|
|
NeptuneCluster:
|
|
Type: AWS::Neptune::DBCluster
|
|
Properties:
|
|
DBClusterIdentifier: !Sub ${EnvironmentName}-cluster
|
|
DBSubnetGroupName: !Ref NeptuneSubnetGroup
|
|
VpcSecurityGroupIds:
|
|
- !Ref NeptuneSecurityGroup
|
|
EngineVersion: '1.4.6.3'
|
|
IamAuthEnabled: true
|
|
StorageEncrypted: true
|
|
DeletionProtection: false
|
|
EnableCloudwatchLogsExports:
|
|
- audit
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-cluster
|
|
|
|
NeptuneInstance:
|
|
Type: AWS::Neptune::DBInstance
|
|
Properties:
|
|
DBInstanceIdentifier: !Sub ${EnvironmentName}-instance
|
|
DBInstanceClass: db.t3.medium
|
|
DBClusterIdentifier: !Ref NeptuneCluster
|
|
PubliclyAccessible: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-instance
|
|
|
|
# =============================================================================
|
|
# IAM USER WITH LEAST PRIVILEGES
|
|
# =============================================================================
|
|
|
|
NeptuneUser:
|
|
Type: AWS::IAM::User
|
|
Properties:
|
|
UserName: !Sub ${EnvironmentName}-user
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Sub ${EnvironmentName}-user
|
|
|
|
NeptuneUserPolicy:
|
|
Type: AWS::IAM::Policy
|
|
Properties:
|
|
PolicyName: !Sub ${EnvironmentName}-neptune-access
|
|
Users:
|
|
- !Ref NeptuneUser
|
|
PolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Sid: NeptuneDataAccess
|
|
Effect: Allow
|
|
Action:
|
|
- neptune-db:connect
|
|
- neptune-db:ReadDataViaQuery
|
|
- neptune-db:WriteDataViaQuery
|
|
- neptune-db:DeleteDataViaQuery
|
|
Resource: !Sub
|
|
- arn:aws:neptune-db:${AWS::Region}:${AWS::AccountId}:${ClusterResourceId}/*
|
|
- ClusterResourceId: !GetAtt NeptuneCluster.ClusterResourceId
|
|
|
|
NeptuneUserAccessKey:
|
|
Type: AWS::IAM::AccessKey
|
|
Properties:
|
|
UserName: !Ref NeptuneUser
|
|
|
|
# =============================================================================
|
|
# OUTPUTS
|
|
# =============================================================================
|
|
|
|
Outputs:
|
|
NeptuneEndpoint:
|
|
Description: Neptune cluster endpoint (hostname only) - use as NEPTUNE_ENDPOINT
|
|
Value: !GetAtt NeptuneCluster.Endpoint
|
|
|
|
NeptunePort:
|
|
Description: Neptune cluster port - use as NEPTUNE_PORT
|
|
Value: !GetAtt NeptuneCluster.Port
|
|
|
|
AwsAccessKeyId:
|
|
Description: Access key ID for the Neptune IAM user - use as AWS_ACCESS_KEY_ID
|
|
Value: !Ref NeptuneUserAccessKey
|
|
|
|
AwsSecretAccessKey:
|
|
Description: Secret access key for the Neptune IAM user - use as AWS_SECRET_ACCESS_KEY
|
|
Value: !GetAtt NeptuneUserAccessKey.SecretAccessKey
|
|
|
|
AwsRegion:
|
|
Description: AWS region where Neptune is deployed - use as AWS_REGION
|
|
Value: !Ref AWS::Region
|
|
|
|
NeptuneClusterResourceId:
|
|
Description: Neptune cluster resource ID (for IAM policy reference)
|
|
Value: !GetAtt NeptuneCluster.ClusterResourceId
|
|
|
|
VpcId:
|
|
Description: VPC ID
|
|
Value: !Ref VPC
|
|
|
|
SecurityGroupId:
|
|
Description: Neptune security group ID
|
|
Value: !Ref NeptuneSecurityGroup
|