aws-cis-controls-assessment 1.1.1__py3-none-any.whl → 1.1.2__py3-none-any.whl

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.
@@ -6,6 +6,6 @@ CIS Controls Implementation Groups (IG1, IG2, IG3). Implements 163 comprehensive
6
6
  across all implementation groups for complete security compliance assessment.
7
7
  """
8
8
 
9
- __version__ = "1.1.1"
9
+ __version__ = "1.1.2"
10
10
  __author__ = "AWS CIS Assessment Team"
11
11
  __description__ = "Production-ready AWS CIS Controls Compliance Assessment Framework"
@@ -274,6 +274,8 @@ class HTMLReporter(ReportGenerator):
274
274
  def _generate_html_body(self, html_data: Dict[str, Any]) -> str:
275
275
  """Generate HTML body section with content.
276
276
 
277
+ Modified in v1.1.2 to remove Detailed Findings and Remediation sections.
278
+
277
279
  Args:
278
280
  html_data: Enhanced HTML report data
279
281
 
@@ -285,9 +287,7 @@ class HTMLReporter(ReportGenerator):
285
287
  navigation = self._generate_navigation(html_data)
286
288
  executive_dashboard = self._generate_executive_dashboard(html_data)
287
289
  implementation_groups = self._generate_implementation_groups_section(html_data)
288
- detailed_findings = self._generate_detailed_findings_section(html_data)
289
290
  resource_details = self._generate_resource_details_section(html_data)
290
- remediation_section = self._generate_remediation_section(html_data)
291
291
  footer = self._generate_footer(html_data)
292
292
 
293
293
  body_content = f"""<body>
@@ -296,9 +296,7 @@ class HTMLReporter(ReportGenerator):
296
296
  {navigation}
297
297
  {executive_dashboard}
298
298
  {implementation_groups}
299
- {detailed_findings}
300
299
  {resource_details}
301
- {remediation_section}
302
300
  {footer}
303
301
  </div>
304
302
 
@@ -771,9 +769,9 @@ class HTMLReporter(ReportGenerator):
771
769
  background-color: #2c3e50;
772
770
  }
773
771
 
774
- /* Resource ID column width constraint */
772
+ /* Resource ID column width constraint - increased to 220px in v1.1.2 */
775
773
  .resource-table td:first-child {
776
- max-width: 200px;
774
+ max-width: 220px;
777
775
  overflow: hidden;
778
776
  text-overflow: ellipsis;
779
777
  white-space: nowrap;
@@ -785,6 +783,20 @@ class HTMLReporter(ReportGenerator):
785
783
  word-wrap: break-word;
786
784
  }
787
785
 
786
+ /* Resource Type column width constraint - added in v1.1.2 (reduced by 20%) */
787
+ .resource-table td:nth-child(2) {
788
+ max-width: 150px;
789
+ overflow: hidden;
790
+ text-overflow: ellipsis;
791
+ white-space: nowrap;
792
+ }
793
+
794
+ .resource-table td:nth-child(2):hover {
795
+ overflow: visible;
796
+ white-space: normal;
797
+ word-wrap: break-word;
798
+ }
799
+
788
800
  /* Visual frames around each resource row */
789
801
  .resource-row {
790
802
  border: 1px solid #e0e0e0;
@@ -1487,11 +1499,12 @@ class HTMLReporter(ReportGenerator):
1487
1499
  window.URL.revokeObjectURL(url);
1488
1500
  }}
1489
1501
 
1490
- // Resource filtering functionality
1502
+ // Resource filtering functionality (updated in v1.1.2 to support Control filter)
1491
1503
  function filterResources() {{
1492
1504
  const searchTerm = document.getElementById('resourceSearch').value.toLowerCase();
1493
1505
  const statusFilter = document.getElementById('statusFilter').value;
1494
1506
  const typeFilter = document.getElementById('typeFilter').value;
1507
+ const controlFilter = document.getElementById('controlFilter').value;
1495
1508
  const rows = document.querySelectorAll('#resourceTable tbody tr');
1496
1509
 
1497
1510
  rows.forEach(function(row) {{
@@ -1500,6 +1513,7 @@ class HTMLReporter(ReportGenerator):
1500
1513
  const resourceType = cells[1].textContent;
1501
1514
  const status = cells[3].textContent.includes('COMPLIANT') ?
1502
1515
  (cells[3].textContent.includes('NON_COMPLIANT') ? 'NON_COMPLIANT' : 'COMPLIANT') : 'NON_COMPLIANT';
1516
+ const controlId = cells[4].textContent;
1503
1517
  const evaluationReason = cells[6].textContent.toLowerCase();
1504
1518
 
1505
1519
  const matchesSearch = resourceId.includes(searchTerm) ||
@@ -1507,8 +1521,9 @@ class HTMLReporter(ReportGenerator):
1507
1521
  evaluationReason.includes(searchTerm);
1508
1522
  const matchesStatus = !statusFilter || status === statusFilter;
1509
1523
  const matchesType = !typeFilter || resourceType === typeFilter;
1524
+ const matchesControl = !controlFilter || controlId === controlFilter;
1510
1525
 
1511
- row.style.display = (matchesSearch && matchesStatus && matchesType) ? '' : 'none';
1526
+ row.style.display = (matchesSearch && matchesStatus && matchesType && matchesControl) ? '' : 'none';
1512
1527
  }});
1513
1528
  }}
1514
1529
 
@@ -1538,18 +1553,74 @@ class HTMLReporter(ReportGenerator):
1538
1553
  }});
1539
1554
  }}
1540
1555
 
1541
- // Export resources to CSV
1556
+ // Export resources to CSV (updated in v1.1.2 with ARN, aggregate filtering, and port truncation)
1542
1557
  function exportResourcesToCSV() {{
1543
1558
  const table = document.getElementById('resourceTable');
1544
1559
  const rows = table.querySelectorAll('tr');
1545
1560
  let csvContent = '';
1546
1561
 
1547
- rows.forEach(function(row) {{
1562
+ // Excluded aggregate row IDs (v1.1.2)
1563
+ const excludedIds = ['5631', '6460', '629'];
1564
+
1565
+ // Helper function to truncate port lists (v1.1.2)
1566
+ function truncatePortList(text) {{
1567
+ // Match port list patterns like [0, 1, 2, 3, ...]
1568
+ const portListRegex = /\\[(\\d+(?:,\\s*\\d+)*)\\]/g;
1569
+
1570
+ return text.replace(portListRegex, function(match, ports) {{
1571
+ const portArray = ports.split(',').map(p => p.trim());
1572
+ if (portArray.length > 10) {{
1573
+ const truncated = portArray.slice(0, 10).join(', ');
1574
+ return `[${{truncated}}, ...]`;
1575
+ }}
1576
+ return match;
1577
+ }});
1578
+ }}
1579
+
1580
+ rows.forEach(function(row, index) {{
1548
1581
  const cells = row.querySelectorAll('th, td');
1549
- const rowData = Array.from(cells).map(cell =>
1550
- '"' + cell.textContent.replace(/"/g, '""').replace(/\\s+/g, ' ').trim() + '"'
1551
- ).join(',');
1552
- csvContent += rowData + '\\n';
1582
+
1583
+ // Handle header row - change "Resource ID" to "Resource ARN"
1584
+ if (index === 0) {{
1585
+ const headerData = Array.from(cells).map((cell, cellIndex) => {{
1586
+ let headerText = cell.textContent.replace(/\\s+/g, ' ').trim();
1587
+ // Replace "Resource ID" with "Resource ARN" in header
1588
+ if (cellIndex === 0 && headerText.includes('Resource ID')) {{
1589
+ headerText = headerText.replace('Resource ID', 'Resource ARN');
1590
+ }}
1591
+ return '"' + headerText.replace(/"/g, '""') + '"';
1592
+ }}).join(',');
1593
+ csvContent += headerData + '\\n';
1594
+ }} else if (cells.length > 0) {{
1595
+ // Get resource ID to check if it should be excluded
1596
+ const resourceIdCell = cells[0];
1597
+ const resourceId = resourceIdCell.textContent.replace(/\\s+/g, ' ').trim();
1598
+
1599
+ // Skip aggregate rows (v1.1.2)
1600
+ if (excludedIds.includes(resourceId)) {{
1601
+ return;
1602
+ }}
1603
+
1604
+ // Get ARN from data attribute or fall back to resource ID
1605
+ const resourceArn = resourceIdCell.getAttribute('data-arn') || resourceId;
1606
+
1607
+ const rowData = Array.from(cells).map((cell, cellIndex) => {{
1608
+ let cellText = cell.textContent.replace(/\\s+/g, ' ').trim();
1609
+
1610
+ // Use ARN for first column instead of Resource ID (v1.1.2)
1611
+ if (cellIndex === 0) {{
1612
+ cellText = resourceArn;
1613
+ }}
1614
+
1615
+ // Apply port list truncation to evaluation reason column (v1.1.2)
1616
+ if (cellIndex === 6) {{
1617
+ cellText = truncatePortList(cellText);
1618
+ }}
1619
+
1620
+ return '"' + cellText.replace(/"/g, '""') + '"';
1621
+ }}).join(',');
1622
+ csvContent += rowData + '\\n';
1623
+ }}
1553
1624
  }});
1554
1625
 
1555
1626
  const blob = new Blob([csvContent], {{ type: 'text/csv' }});
@@ -1849,161 +1920,7 @@ class HTMLReporter(ReportGenerator):
1849
1920
  </section>
1850
1921
  """
1851
1922
 
1852
- def _generate_detailed_findings_section(self, html_data: Dict[str, Any]) -> str:
1853
- """Generate detailed findings section.
1854
-
1855
- This method consolidates findings by control ID only (not by IG) to eliminate
1856
- duplication. Each control appears once with IG membership indicators.
1857
-
1858
- Args:
1859
- html_data: Enhanced HTML report data
1860
-
1861
- Returns:
1862
- Detailed findings HTML as string
1863
- """
1864
- # Consolidate findings by control ID (deduplicated across IGs)
1865
- consolidated_findings = self._consolidate_findings_by_control(
1866
- html_data.get("implementation_groups", {})
1867
- )
1868
-
1869
- findings_content = ""
1870
-
1871
- # Generate findings grouped by control ID only (sorted alphanumerically)
1872
- for control_id, control_data in consolidated_findings.items():
1873
- findings = control_data.get('findings', [])
1874
-
1875
- # Skip if no non-compliant findings
1876
- if not findings:
1877
- continue
1878
-
1879
- # Get control metadata
1880
- config_rule_name = control_data.get('config_rule_name', '')
1881
- title = control_data.get('title', f'CIS Control {control_id}')
1882
- member_igs = control_data.get('member_igs', [])
1883
-
1884
- # Format display name for collapsible header
1885
- display_name = self._format_control_display_name(control_id, config_rule_name, title)
1886
-
1887
- # Generate IG membership badges
1888
- ig_badges_html = ""
1889
- for ig in member_igs:
1890
- badge_class = self._get_ig_badge_class(ig)
1891
- ig_badges_html += f'<span class="ig-membership-badge {badge_class}">{ig}</span>'
1892
-
1893
- # Generate findings table rows
1894
- findings_rows = ""
1895
- for finding in findings:
1896
- if finding.get("compliance_status") == "NON_COMPLIANT":
1897
- findings_rows += f"""
1898
- <tr>
1899
- <td>{finding.get('resource_id', 'N/A')}</td>
1900
- <td>{finding.get('resource_type', 'N/A')}</td>
1901
- <td>{finding.get('region', 'N/A')}</td>
1902
- <td><span class="badge {finding.get('compliance_status', '').lower()}">{finding.get('compliance_status', 'UNKNOWN')}</span></td>
1903
- <td>{finding.get('evaluation_reason', 'N/A')}</td>
1904
- <td>{finding.get('config_rule_name', config_rule_name)}</td>
1905
- </tr>
1906
- """
1907
-
1908
- # Only add control section if there are non-compliant findings
1909
- if findings_rows:
1910
- non_compliant_count = len([f for f in findings if f.get('compliance_status') == 'NON_COMPLIANT'])
1911
-
1912
- findings_content += f"""
1913
- <div class="control-findings-section">
1914
- <button class="collapsible">
1915
- <span class="control-display-name">{display_name}</span>
1916
- <span class="findings-count"> - Non-Compliant Resources ({non_compliant_count} items)</span>
1917
- </button>
1918
- <div class="collapsible-content">
1919
- <div class="ig-membership-badges" style="margin-bottom: 15px;">
1920
- <strong>Implementation Groups:</strong> {ig_badges_html}
1921
- </div>
1922
- <table class="findings-table">
1923
- <thead>
1924
- <tr>
1925
- <th>Resource ID</th>
1926
- <th>Resource Type</th>
1927
- <th>Region</th>
1928
- <th>Compliance Status</th>
1929
- <th>Reason</th>
1930
- <th>Config Rule</th>
1931
- </tr>
1932
- </thead>
1933
- <tbody>
1934
- {findings_rows}
1935
- </tbody>
1936
- </table>
1937
- </div>
1938
- </div>
1939
- """
1940
-
1941
- return f"""
1942
- <section id="detailed-findings" class="detailed-findings">
1943
- <h2>Detailed Findings</h2>
1944
- <p class="section-description">
1945
- Findings are grouped by control ID and deduplicated across Implementation Groups.
1946
- Each control shows which IGs include it.
1947
- </p>
1948
- <div class="search-container">
1949
- <input type="text" placeholder="Search findings..." onkeyup="searchFindings(this.value)" style="width: 100%; padding: 10px; margin-bottom: 20px; border: 1px solid #ddd; border-radius: 5px;">
1950
- </div>
1951
- {findings_content if findings_content else '<p>No non-compliant findings to display.</p>'}
1952
- </section>
1953
- """
1954
1923
 
1955
- def _generate_remediation_section(self, html_data: Dict[str, Any]) -> str:
1956
- """Generate remediation section.
1957
-
1958
- Args:
1959
- html_data: Enhanced HTML report data
1960
-
1961
- Returns:
1962
- Remediation HTML as string
1963
- """
1964
- remediation_items = ""
1965
-
1966
- for remediation in html_data["remediation_priorities"]:
1967
- steps_html = ""
1968
- for step in remediation["remediation_steps"]:
1969
- steps_html += f"<li>{step}</li>"
1970
-
1971
- # Normalize priority and effort text to proper capitalization
1972
- priority_text = remediation['priority'].capitalize()
1973
- effort_text = remediation['estimated_effort'].capitalize()
1974
-
1975
- remediation_items += f"""
1976
- <div class="remediation-item">
1977
- <div class="remediation-header">
1978
- <div>
1979
- <h4>{remediation['control_id']} - {remediation['config_rule_name']}</h4>
1980
- </div>
1981
- <div class="remediation-badges">
1982
- <span class="badge {remediation['priority_badge']}">{priority_text}</span>
1983
- <span class="badge {remediation['effort_badge']}">{effort_text}</span>
1984
- </div>
1985
- </div>
1986
- <div class="remediation-content">
1987
- <h5>Remediation Steps:</h5>
1988
- <ol>
1989
- {steps_html}
1990
- </ol>
1991
- <p><strong>Documentation:</strong> <a href="{remediation['aws_documentation_link']}" target="_blank">AWS Documentation</a></p>
1992
- </div>
1993
- </div>
1994
- """
1995
-
1996
- return f"""
1997
- <section id="remediation" class="remediation">
1998
- <h2>Remediation Priorities</h2>
1999
- <div class="remediation-list">
2000
- {remediation_items}
2001
- </div>
2002
- <div class="export-actions">
2003
- <button onclick="exportToCSV()" class="export-btn">Export Findings to CSV</button>
2004
- </div>
2005
- </section>
2006
- """
2007
1924
 
2008
1925
  def _generate_footer(self, html_data: Dict[str, Any]) -> str:
2009
1926
  """Generate footer section.
@@ -2109,6 +2026,8 @@ class HTMLReporter(ReportGenerator):
2109
2026
  def _build_navigation_structure(self, html_data: Dict[str, Any]) -> Dict[str, Any]:
2110
2027
  """Build navigation structure for the report.
2111
2028
 
2029
+ Modified in v1.1.2 to remove Detailed Findings and Remediation sections.
2030
+
2112
2031
  Args:
2113
2032
  html_data: Enhanced HTML report data
2114
2033
 
@@ -2119,9 +2038,7 @@ class HTMLReporter(ReportGenerator):
2119
2038
  "sections": [
2120
2039
  {"id": "dashboard", "title": "Dashboard"},
2121
2040
  {"id": "implementation-groups", "title": "Implementation Groups"},
2122
- {"id": "detailed-findings", "title": "Detailed Findings"},
2123
- {"id": "resource-details", "title": "Resource Details"},
2124
- {"id": "remediation", "title": "Remediation"}
2041
+ {"id": "resource-details", "title": "Resource Details"}
2125
2042
  ]
2126
2043
  }
2127
2044
 
@@ -2594,9 +2511,14 @@ class HTMLReporter(ReportGenerator):
2594
2511
  status_class = "compliant" if resource["compliance_status"] == "COMPLIANT" else "non_compliant"
2595
2512
  status_icon = "✓" if resource["compliance_status"] == "COMPLIANT" else "✗"
2596
2513
 
2514
+ # Construct pseudo-ARN for CSV export (v1.1.2)
2515
+ # Format: arn:aws:service:region:account:resource-type/resource-id
2516
+ # Since we don't have account ID in resource data, we'll use a placeholder
2517
+ resource_arn = f"arn:aws:{resource['resource_type'].split('::')[1].lower() if '::' in resource['resource_type'] else 'unknown'}:{resource['region']}:*:{resource['resource_id']}"
2518
+
2597
2519
  resource_rows += f"""
2598
2520
  <tr class="resource-row {status_class}">
2599
- <td><code>{resource['resource_id']}</code></td>
2521
+ <td data-arn="{resource_arn}"><code>{resource['resource_id']}</code></td>
2600
2522
  <td>{resource['resource_type']}</td>
2601
2523
  <td>{resource['region']}</td>
2602
2524
  <td>
@@ -2616,6 +2538,12 @@ class HTMLReporter(ReportGenerator):
2616
2538
  non_compliant_resources = total_resources - compliant_resources
2617
2539
  compliance_percentage = (compliant_resources / total_resources * 100) if total_resources > 0 else 0
2618
2540
 
2541
+ # Extract unique Control IDs for filter dropdown (v1.1.2)
2542
+ unique_control_ids = sorted(set(r["control_id"] for r in all_resources), key=self._sort_control_id)
2543
+ control_filter_options = ""
2544
+ for control_id in unique_control_ids:
2545
+ control_filter_options += f'<option value="{control_id}">{control_id}</option>'
2546
+
2619
2547
  # Generate resource type breakdown
2620
2548
  resource_type_stats = {}
2621
2549
  for resource in all_resources:
@@ -2689,6 +2617,10 @@ class HTMLReporter(ReportGenerator):
2689
2617
  <option value="">All Types</option>
2690
2618
  {self._generate_resource_type_options(resource_type_stats)}
2691
2619
  </select>
2620
+ <select id="controlFilter" onchange="filterResources()" class="filter-select">
2621
+ <option value="">All Controls</option>
2622
+ {control_filter_options}
2623
+ </select>
2692
2624
  </div>
2693
2625
 
2694
2626
  <table class="findings-table resource-table" id="resourceTable">
@@ -2859,6 +2791,8 @@ class HTMLReporter(ReportGenerator):
2859
2791
  Enriches control data with additional fields needed for improved display,
2860
2792
  including formatted names, IG membership badges, and truncation indicators.
2861
2793
 
2794
+ Modified in v1.1.2 to remove duplicate Control ID prefix from display names.
2795
+
2862
2796
  Args:
2863
2797
  control_data: Existing control data dictionary
2864
2798
  control_id: Control identifier (e.g., "1.5")
@@ -2867,7 +2801,7 @@ class HTMLReporter(ReportGenerator):
2867
2801
 
2868
2802
  Returns:
2869
2803
  Enhanced control data with additional fields:
2870
- - display_name: Formatted name combining control ID and rule name
2804
+ - display_name: Formatted name without duplicate Control ID prefix
2871
2805
  - originating_ig: Which IG introduced this control (IG1, IG2, or IG3)
2872
2806
  - ig_badge_class: CSS class for IG badge styling
2873
2807
  - needs_truncation: Boolean indicating if display name exceeds 50 characters
@@ -2884,7 +2818,7 @@ class HTMLReporter(ReportGenerator):
2884
2818
  Output enriched data (includes all input fields plus):
2885
2819
  {
2886
2820
  ...original fields...,
2887
- 'display_name': '1.5: root-account-hardware-mfa-enabled',
2821
+ 'display_name': 'root-account-hardware-mfa-enabled', # No "1.5:" prefix
2888
2822
  'originating_ig': 'IG1',
2889
2823
  'ig_badge_class': 'ig-badge-1',
2890
2824
  'needs_truncation': False
@@ -2895,16 +2829,25 @@ class HTMLReporter(ReportGenerator):
2895
2829
  - Truncation threshold is 50 characters
2896
2830
  - Gracefully handles missing config_rule_name
2897
2831
  - Originating IG is determined by checking IG1, IG2, IG3 in order
2832
+ - v1.1.2: Removes duplicate Control ID prefix from display names
2898
2833
  """
2899
2834
  enriched = control_data.copy()
2900
2835
 
2901
2836
  # Format display name
2902
- enriched['display_name'] = self._format_control_display_name(
2837
+ display_name = self._format_control_display_name(
2903
2838
  control_id,
2904
2839
  control_data.get('config_rule_name', ''),
2905
2840
  control_data.get('title')
2906
2841
  )
2907
2842
 
2843
+ # Remove duplicate Control ID prefix if present (v1.1.2 improvement)
2844
+ # Check if display_name starts with "control_id: "
2845
+ prefix = f"{control_id}: "
2846
+ if display_name.startswith(prefix):
2847
+ display_name = display_name[len(prefix):]
2848
+
2849
+ enriched['display_name'] = display_name
2850
+
2908
2851
  # Determine originating IG (which IG introduced this control)
2909
2852
  originating_ig = self._determine_originating_ig(control_id, all_igs)
2910
2853
  enriched['originating_ig'] = originating_ig
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws-cis-controls-assessment
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: Production-ready AWS CIS Controls compliance assessment framework with 145 comprehensive rules
5
5
  Author-email: AWS CIS Assessment Team <security@example.com>
6
6
  Maintainer-email: AWS CIS Assessment Team <security@example.com>
@@ -1,4 +1,4 @@
1
- aws_cis_assessment/__init__.py,sha256=ICafcznKTUU2j4VAbZ6-yjWXSQZGQRYzpzY7NIZ_23U,480
1
+ aws_cis_assessment/__init__.py,sha256=LHhkIKN6ePtfS9xu2BnrEUW9cMfzW53q0CDz-d0syiY,480
2
2
  aws_cis_assessment/cli/__init__.py,sha256=DYaGVAIoy5ucs9ubKQxX6Z3ZD46AGz9AaIaDQXzrzeY,100
3
3
  aws_cis_assessment/cli/examples.py,sha256=F9K2Fe297kUfwoq6Ine9Aj_IXNU-KwO9hd7SAPWeZHI,12884
4
4
  aws_cis_assessment/cli/main.py,sha256=i5QoqHXsPG_Kw0W7jM3Zj2YaAaCJnxxnfz82QBBHq-U,49441
@@ -63,9 +63,9 @@ aws_cis_assessment/core/scoring_engine.py,sha256=ylx2urk_DxGzU_LZB0ip-qtUzOh4yu0
63
63
  aws_cis_assessment/reporters/__init__.py,sha256=GXdlY08kKy1Y3mMBv8Y0JuUB69u--e5DIu2jNJpc6QI,357
64
64
  aws_cis_assessment/reporters/base_reporter.py,sha256=joy_O4IL4Hs_qwAuPtl81GIPxLAbUAMFKiF8r5si2aw,18082
65
65
  aws_cis_assessment/reporters/csv_reporter.py,sha256=r83xzfP1t5AO9MfKawgN4eTeOU6eGZwJQgvNDLEd7NI,31419
66
- aws_cis_assessment/reporters/html_reporter.py,sha256=H5LkcaXbzArNNO-CLJT5oXMSNccxU58L-ba_Q769Yhs,118310
66
+ aws_cis_assessment/reporters/html_reporter.py,sha256=etqaoDa82yuaT3c1b_d3kSNN_jeOshR2lxf-TlCTYD8,116314
67
67
  aws_cis_assessment/reporters/json_reporter.py,sha256=MObCzTc9nlGTEXeWc7P8tTMeKCpEaJNfcSYc79cHXhc,22250
68
- aws_cis_controls_assessment-1.1.1.dist-info/licenses/LICENSE,sha256=T_p0qKH4RoI3ejr3tktf3rx2Zart_9KeUmJd5iiqXW8,1079
68
+ aws_cis_controls_assessment-1.1.2.dist-info/licenses/LICENSE,sha256=T_p0qKH4RoI3ejr3tktf3rx2Zart_9KeUmJd5iiqXW8,1079
69
69
  deprecation-package/aws_cis_assessment_deprecated/__init__.py,sha256=WOaufqanKNhvWQ3frj8e627tS_kZnyk2R2hwqPFqydw,1892
70
70
  docs/README.md,sha256=MXnfbPRmxir-7ihG2lNmLI9TJG0Pp0QWqoDZtXiH_Mk,4912
71
71
  docs/adding-aws-backup-controls.md,sha256=l_H0H8W71n-6NbeplNujC_li2NiaQcYPr0hQMhEPbrc,21081
@@ -80,8 +80,8 @@ docs/scoring-comparison-aws-config.md,sha256=8BBe1tQsaAT0BAE3OdGIRFjuT1VJcOlM1qB
80
80
  docs/scoring-methodology.md,sha256=C86FisBxKt6pyr-Kp6rAVPz45yPZpgsGibjgq8obIsg,9404
81
81
  docs/troubleshooting.md,sha256=mGmWgrc3A1dn-Uk_XxWFh04OQxjmqkeax8vQX7takg0,18220
82
82
  docs/user-guide.md,sha256=lBDgU40tIPstOdNx4YqVkPTIDntn4o2y2tr2CPQt7b8,11942
83
- aws_cis_controls_assessment-1.1.1.dist-info/METADATA,sha256=gXpUI7yboznt4qn6KmVKtKSZVVO9In29KhHqrokOqZo,21383
84
- aws_cis_controls_assessment-1.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
85
- aws_cis_controls_assessment-1.1.1.dist-info/entry_points.txt,sha256=-AxPn5Y7yau0pQh33F5_uyWfvcnm2Kg1_nMQuLrZ7SY,68
86
- aws_cis_controls_assessment-1.1.1.dist-info/top_level.txt,sha256=4OHmV6RAEWkz-Se50kfmuGCd-mUSotDZz3iLGF9CmkI,44
87
- aws_cis_controls_assessment-1.1.1.dist-info/RECORD,,
83
+ aws_cis_controls_assessment-1.1.2.dist-info/METADATA,sha256=vkzPrC5mz6oh7gfD9UOOnPuKeMtnXjLTtEpCdf_ZAJc,21383
84
+ aws_cis_controls_assessment-1.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
85
+ aws_cis_controls_assessment-1.1.2.dist-info/entry_points.txt,sha256=-AxPn5Y7yau0pQh33F5_uyWfvcnm2Kg1_nMQuLrZ7SY,68
86
+ aws_cis_controls_assessment-1.1.2.dist-info/top_level.txt,sha256=4OHmV6RAEWkz-Se50kfmuGCd-mUSotDZz3iLGF9CmkI,44
87
+ aws_cis_controls_assessment-1.1.2.dist-info/RECORD,,