runbooks 0.9.9__py3-none-any.whl → 1.0.1__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.
Files changed (111) hide show
  1. runbooks/__init__.py +1 -1
  2. runbooks/cfat/WEIGHT_CONFIG_README.md +368 -0
  3. runbooks/cfat/app.ts +27 -19
  4. runbooks/cfat/assessment/runner.py +6 -5
  5. runbooks/cfat/cloud_foundations_assessment.py +626 -0
  6. runbooks/cfat/tests/test_weight_configuration.ts +449 -0
  7. runbooks/cfat/weight_config.ts +574 -0
  8. runbooks/cloudops/cost_optimizer.py +95 -33
  9. runbooks/common/__init__.py +26 -9
  10. runbooks/common/aws_pricing.py +1353 -0
  11. runbooks/common/aws_pricing_api.py +205 -0
  12. runbooks/common/aws_utils.py +2 -2
  13. runbooks/common/comprehensive_cost_explorer_integration.py +979 -0
  14. runbooks/common/cross_account_manager.py +606 -0
  15. runbooks/common/date_utils.py +115 -0
  16. runbooks/common/enhanced_exception_handler.py +14 -7
  17. runbooks/common/env_utils.py +96 -0
  18. runbooks/common/mcp_cost_explorer_integration.py +5 -4
  19. runbooks/common/mcp_integration.py +49 -2
  20. runbooks/common/organizations_client.py +579 -0
  21. runbooks/common/profile_utils.py +127 -72
  22. runbooks/common/rich_utils.py +3 -3
  23. runbooks/finops/cost_optimizer.py +2 -1
  24. runbooks/finops/dashboard_runner.py +47 -28
  25. runbooks/finops/ebs_optimizer.py +56 -9
  26. runbooks/finops/elastic_ip_optimizer.py +13 -9
  27. runbooks/finops/embedded_mcp_validator.py +31 -0
  28. runbooks/finops/enhanced_trend_visualization.py +10 -4
  29. runbooks/finops/finops_dashboard.py +6 -5
  30. runbooks/finops/iam_guidance.py +6 -1
  31. runbooks/finops/markdown_exporter.py +217 -2
  32. runbooks/finops/nat_gateway_optimizer.py +76 -20
  33. runbooks/finops/tests/test_integration.py +3 -1
  34. runbooks/finops/vpc_cleanup_exporter.py +28 -26
  35. runbooks/finops/vpc_cleanup_optimizer.py +363 -16
  36. runbooks/inventory/__init__.py +10 -1
  37. runbooks/inventory/cloud_foundations_integration.py +409 -0
  38. runbooks/inventory/core/collector.py +1177 -94
  39. runbooks/inventory/discovery.md +339 -0
  40. runbooks/inventory/drift_detection_cli.py +327 -0
  41. runbooks/inventory/inventory_mcp_cli.py +171 -0
  42. runbooks/inventory/inventory_modules.py +6 -9
  43. runbooks/inventory/list_ec2_instances.py +3 -3
  44. runbooks/inventory/mcp_inventory_validator.py +2149 -0
  45. runbooks/inventory/mcp_vpc_validator.py +23 -6
  46. runbooks/inventory/organizations_discovery.py +104 -9
  47. runbooks/inventory/rich_inventory_display.py +129 -1
  48. runbooks/inventory/unified_validation_engine.py +1279 -0
  49. runbooks/inventory/verify_ec2_security_groups.py +3 -1
  50. runbooks/inventory/vpc_analyzer.py +825 -7
  51. runbooks/inventory/vpc_flow_analyzer.py +36 -42
  52. runbooks/main.py +708 -47
  53. runbooks/monitoring/performance_monitor.py +11 -7
  54. runbooks/operate/base.py +9 -6
  55. runbooks/operate/deployment_framework.py +5 -4
  56. runbooks/operate/deployment_validator.py +6 -5
  57. runbooks/operate/dynamodb_operations.py +6 -5
  58. runbooks/operate/ec2_operations.py +3 -2
  59. runbooks/operate/mcp_integration.py +6 -5
  60. runbooks/operate/networking_cost_heatmap.py +21 -16
  61. runbooks/operate/s3_operations.py +13 -12
  62. runbooks/operate/vpc_operations.py +100 -12
  63. runbooks/remediation/base.py +4 -2
  64. runbooks/remediation/commons.py +5 -5
  65. runbooks/remediation/commvault_ec2_analysis.py +68 -15
  66. runbooks/remediation/config/accounts_example.json +31 -0
  67. runbooks/remediation/ec2_unattached_ebs_volumes.py +6 -3
  68. runbooks/remediation/multi_account.py +120 -7
  69. runbooks/remediation/rds_snapshot_list.py +5 -3
  70. runbooks/remediation/remediation_cli.py +710 -0
  71. runbooks/remediation/universal_account_discovery.py +377 -0
  72. runbooks/security/compliance_automation_engine.py +99 -20
  73. runbooks/security/config/__init__.py +24 -0
  74. runbooks/security/config/compliance_config.py +255 -0
  75. runbooks/security/config/compliance_weights_example.json +22 -0
  76. runbooks/security/config_template_generator.py +500 -0
  77. runbooks/security/security_cli.py +377 -0
  78. runbooks/validation/__init__.py +21 -1
  79. runbooks/validation/cli.py +8 -7
  80. runbooks/validation/comprehensive_2way_validator.py +2007 -0
  81. runbooks/validation/mcp_validator.py +965 -101
  82. runbooks/validation/terraform_citations_validator.py +363 -0
  83. runbooks/validation/terraform_drift_detector.py +1098 -0
  84. runbooks/vpc/cleanup_wrapper.py +231 -10
  85. runbooks/vpc/config.py +346 -73
  86. runbooks/vpc/cross_account_session.py +312 -0
  87. runbooks/vpc/heatmap_engine.py +115 -41
  88. runbooks/vpc/manager_interface.py +9 -9
  89. runbooks/vpc/mcp_no_eni_validator.py +1630 -0
  90. runbooks/vpc/networking_wrapper.py +14 -8
  91. runbooks/vpc/runbooks_adapter.py +33 -12
  92. runbooks/vpc/tests/conftest.py +4 -2
  93. runbooks/vpc/tests/test_cost_engine.py +4 -2
  94. runbooks/vpc/unified_scenarios.py +73 -3
  95. runbooks/vpc/vpc_cleanup_integration.py +512 -78
  96. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/METADATA +94 -52
  97. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/RECORD +101 -81
  98. runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
  99. runbooks/finops/runbooks.security.report_generator.log +0 -0
  100. runbooks/finops/runbooks.security.run_script.log +0 -0
  101. runbooks/finops/runbooks.security.security_export.log +0 -0
  102. runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
  103. runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
  104. runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
  105. runbooks/inventory/runbooks.security.report_generator.log +0 -0
  106. runbooks/inventory/runbooks.security.run_script.log +0 -0
  107. runbooks/inventory/runbooks.security.security_export.log +0 -0
  108. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
  109. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
  110. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
  111. {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Security CLI Commands - Dynamic Configuration Support
4
+
5
+ Enhanced security CLI with enterprise configuration patterns:
6
+ - Dynamic account discovery (environment variables, config files, Organizations API)
7
+ - Dynamic compliance weights and thresholds
8
+ - Profile override support (--profile parameter)
9
+ - Multi-account operations (--all flag)
10
+ - Configuration-driven approach eliminating hardcoded values
11
+
12
+ Author: DevOps Security Engineer (Claude Code Enterprise Team)
13
+ Version: 1.0 - Enterprise Dynamic Configuration Ready
14
+ """
15
+
16
+ import asyncio
17
+ import os
18
+ from pathlib import Path
19
+ from typing import List, Optional
20
+
21
+ import click
22
+ from rich.console import Console
23
+ from rich.panel import Panel
24
+
25
+ from runbooks.common.profile_utils import get_profile_for_operation, validate_profile_access
26
+ from runbooks.common.rich_utils import (
27
+ console,
28
+ create_panel,
29
+ print_error,
30
+ print_info,
31
+ print_success,
32
+ print_warning,
33
+ )
34
+
35
+ from .compliance_automation_engine import ComplianceAutomationEngine, ComplianceFramework
36
+ from .security_baseline_tester import SecurityBaselineTester
37
+ from .config_template_generator import SecurityConfigTemplateGenerator
38
+
39
+
40
+ @click.group()
41
+ @click.option(
42
+ "--profile",
43
+ default=None,
44
+ help="AWS profile to use (overrides environment variables)"
45
+ )
46
+ @click.option(
47
+ "--output-dir",
48
+ default="./artifacts/security",
49
+ help="Output directory for security reports"
50
+ )
51
+ @click.pass_context
52
+ def security(ctx, profile: Optional[str], output_dir: str):
53
+ """
54
+ Enterprise Security Operations with Dynamic Configuration.
55
+
56
+ Supports configuration via:
57
+ - Environment variables
58
+ - Configuration files
59
+ - AWS Organizations API
60
+ - Profile override patterns
61
+ """
62
+ ctx.ensure_object(dict)
63
+ ctx.obj["profile"] = profile
64
+ ctx.obj["output_dir"] = output_dir
65
+
66
+ # Validate profile if specified
67
+ if profile:
68
+ resolved_profile = get_profile_for_operation("management", profile)
69
+ if not validate_profile_access(resolved_profile, "security operations"):
70
+ print_error(f"Profile validation failed: {resolved_profile}")
71
+ raise click.Abort()
72
+
73
+
74
+ @security.command()
75
+ @click.option(
76
+ "--frameworks",
77
+ multiple=True,
78
+ type=click.Choice([
79
+ "aws-well-architected",
80
+ "soc2-type-ii",
81
+ "pci-dss",
82
+ "hipaa",
83
+ "iso27001",
84
+ "nist-cybersecurity",
85
+ "cis-benchmarks"
86
+ ]),
87
+ default=["aws-well-architected"],
88
+ help="Compliance frameworks to assess"
89
+ )
90
+ @click.option(
91
+ "--accounts",
92
+ help="Comma-separated account IDs (overrides discovery)"
93
+ )
94
+ @click.option(
95
+ "--all",
96
+ "all_accounts",
97
+ is_flag=True,
98
+ help="Assess all discovered accounts via Organizations API"
99
+ )
100
+ @click.option(
101
+ "--scope",
102
+ type=click.Choice(["full", "quick", "critical"]),
103
+ default="full",
104
+ help="Assessment scope"
105
+ )
106
+ @click.option(
107
+ "--export-formats",
108
+ multiple=True,
109
+ type=click.Choice(["json", "csv", "html", "pdf"]),
110
+ default=["json", "csv"],
111
+ help="Export formats for compliance reports"
112
+ )
113
+ @click.pass_context
114
+ def assess(ctx, frameworks: List[str], accounts: Optional[str], all_accounts: bool, scope: str, export_formats: List[str]):
115
+ """
116
+ Execute comprehensive compliance assessment with dynamic configuration.
117
+
118
+ Environment Variables Supported:
119
+ - COMPLIANCE_TARGET_ACCOUNTS: Comma-separated account IDs
120
+ - COMPLIANCE_ACCOUNTS_CONFIG: Path to accounts configuration file
121
+ - COMPLIANCE_WEIGHT_<CONTROL_ID>: Dynamic control weights
122
+ - COMPLIANCE_THRESHOLD_<FRAMEWORK>: Dynamic framework thresholds
123
+ """
124
+ profile = ctx.obj["profile"]
125
+ output_dir = ctx.obj["output_dir"]
126
+
127
+ try:
128
+ # Convert framework names to enum values
129
+ framework_mapping = {
130
+ "aws-well-architected": ComplianceFramework.AWS_WELL_ARCHITECTED,
131
+ "soc2-type-ii": ComplianceFramework.SOC2_TYPE_II,
132
+ "pci-dss": ComplianceFramework.PCI_DSS,
133
+ "hipaa": ComplianceFramework.HIPAA,
134
+ "iso27001": ComplianceFramework.ISO27001,
135
+ "nist-cybersecurity": ComplianceFramework.NIST_CYBERSECURITY,
136
+ "cis-benchmarks": ComplianceFramework.CIS_BENCHMARKS,
137
+ }
138
+
139
+ selected_frameworks = [framework_mapping[f] for f in frameworks]
140
+
141
+ # Parse target accounts
142
+ target_accounts = None
143
+ if accounts:
144
+ target_accounts = [acc.strip() for acc in accounts.split(",")]
145
+ print_info(f"Using specified accounts: {len(target_accounts)} accounts")
146
+ elif all_accounts:
147
+ print_info("Using all discovered accounts via Organizations API")
148
+ # target_accounts will be None, triggering discovery
149
+ else:
150
+ print_info("Using default account discovery")
151
+
152
+ # Initialize compliance engine
153
+ console.print(
154
+ create_panel(
155
+ f"[bold cyan]Enterprise Compliance Assessment[/bold cyan]\n\n"
156
+ f"[dim]Frameworks: {', '.join(frameworks)}[/dim]\n"
157
+ f"[dim]Profile: {profile or 'default'}[/dim]\n"
158
+ f"[dim]Scope: {scope}[/dim]\n"
159
+ f"[dim]Export Formats: {', '.join(export_formats)}[/dim]",
160
+ title="🛡️ Starting Assessment",
161
+ border_style="cyan",
162
+ )
163
+ )
164
+
165
+ compliance_engine = ComplianceAutomationEngine(
166
+ profile=profile,
167
+ output_dir=output_dir
168
+ )
169
+
170
+ # Execute assessment
171
+ reports = asyncio.run(compliance_engine.assess_compliance(
172
+ frameworks=selected_frameworks,
173
+ target_accounts=target_accounts,
174
+ scope=scope
175
+ ))
176
+
177
+ # Display summary
178
+ print_success(f"Assessment completed! Generated {len(reports)} compliance reports")
179
+ print_info(f"Reports saved to: {output_dir}")
180
+
181
+ # Display configuration sources used
182
+ _display_configuration_sources()
183
+
184
+ except Exception as e:
185
+ print_error(f"Compliance assessment failed: {str(e)}")
186
+ raise click.Abort()
187
+
188
+
189
+ @security.command()
190
+ @click.option(
191
+ "--language",
192
+ type=click.Choice(["en", "ja", "ko", "vi"]),
193
+ default="en",
194
+ help="Report language"
195
+ )
196
+ @click.option(
197
+ "--export-formats",
198
+ multiple=True,
199
+ type=click.Choice(["json", "csv", "html", "pdf"]),
200
+ default=["json", "csv"],
201
+ help="Export formats for security reports"
202
+ )
203
+ @click.pass_context
204
+ def baseline(ctx, language: str, export_formats: List[str]):
205
+ """
206
+ Execute security baseline assessment with dynamic configuration.
207
+
208
+ Uses enterprise profile management and configuration-driven approach.
209
+ """
210
+ profile = ctx.obj["profile"]
211
+ output_dir = ctx.obj["output_dir"]
212
+
213
+ try:
214
+ console.print(
215
+ create_panel(
216
+ f"[bold cyan]AWS Security Baseline Assessment[/bold cyan]\n\n"
217
+ f"[dim]Profile: {profile or 'default'}[/dim]\n"
218
+ f"[dim]Language: {language}[/dim]\n"
219
+ f"[dim]Export Formats: {', '.join(export_formats)}[/dim]",
220
+ title="🔒 Starting Baseline Assessment",
221
+ border_style="green",
222
+ )
223
+ )
224
+
225
+ # Initialize security baseline tester
226
+ baseline_tester = SecurityBaselineTester(
227
+ profile=profile,
228
+ lang_code=language,
229
+ output_dir=output_dir,
230
+ export_formats=list(export_formats)
231
+ )
232
+
233
+ # Execute baseline assessment
234
+ baseline_tester.run()
235
+
236
+ print_success("Security baseline assessment completed successfully!")
237
+ print_info(f"Results saved to: {output_dir}")
238
+
239
+ except Exception as e:
240
+ print_error(f"Security baseline assessment failed: {str(e)}")
241
+ raise click.Abort()
242
+
243
+
244
+ @security.command()
245
+ @click.pass_context
246
+ def config_info(ctx):
247
+ """
248
+ Display current security configuration and environment setup.
249
+ """
250
+ console.print(
251
+ Panel.fit(
252
+ "[bold cyan]Security Configuration Information[/bold cyan]",
253
+ border_style="cyan"
254
+ )
255
+ )
256
+
257
+ # Display environment variables
258
+ print_info("Environment Configuration:")
259
+
260
+ env_vars = {
261
+ "Profile Configuration": {
262
+ "MANAGEMENT_PROFILE": os.getenv("MANAGEMENT_PROFILE", "Not set"),
263
+ "BILLING_PROFILE": os.getenv("BILLING_PROFILE", "Not set"),
264
+ "CENTRALISED_OPS_PROFILE": os.getenv("CENTRALISED_OPS_PROFILE", "Not set"),
265
+ },
266
+ "Compliance Configuration": {
267
+ "COMPLIANCE_TARGET_ACCOUNTS": os.getenv("COMPLIANCE_TARGET_ACCOUNTS", "Not set"),
268
+ "COMPLIANCE_ACCOUNTS_CONFIG": os.getenv("COMPLIANCE_ACCOUNTS_CONFIG", "Not set"),
269
+ "COMPLIANCE_WEIGHTS_CONFIG": os.getenv("COMPLIANCE_WEIGHTS_CONFIG", "Not set"),
270
+ "COMPLIANCE_THRESHOLDS_CONFIG": os.getenv("COMPLIANCE_THRESHOLDS_CONFIG", "Not set"),
271
+ },
272
+ "Remediation Configuration": {
273
+ "REMEDIATION_TARGET_ACCOUNTS": os.getenv("REMEDIATION_TARGET_ACCOUNTS", "Not set"),
274
+ "REMEDIATION_ACCOUNT_CONFIG": os.getenv("REMEDIATION_ACCOUNT_CONFIG", "Not set"),
275
+ }
276
+ }
277
+
278
+ for category, variables in env_vars.items():
279
+ console.print(f"\n[bold]{category}:[/bold]")
280
+ for var_name, var_value in variables.items():
281
+ status = "✅" if var_value != "Not set" else "❌"
282
+ console.print(f" {status} {var_name}: {var_value}")
283
+
284
+ # Display example configuration files
285
+ console.print("\n[bold]Example Configuration Files:[/bold]")
286
+ config_examples = [
287
+ "src/runbooks/security/config/compliance_weights_example.json",
288
+ "src/runbooks/remediation/config/accounts_example.json"
289
+ ]
290
+
291
+ for config_file in config_examples:
292
+ if os.path.exists(config_file):
293
+ console.print(f" ✅ {config_file}")
294
+ else:
295
+ console.print(f" 📝 {config_file} (example)")
296
+
297
+
298
+ def _display_configuration_sources():
299
+ """Display information about configuration sources used."""
300
+ console.print("\n[bold]Configuration Sources:[/bold]")
301
+
302
+ # Check environment variables
303
+ if os.getenv("COMPLIANCE_TARGET_ACCOUNTS"):
304
+ console.print(" ✅ Using COMPLIANCE_TARGET_ACCOUNTS environment variable")
305
+
306
+ if os.getenv("COMPLIANCE_ACCOUNTS_CONFIG"):
307
+ config_path = os.getenv("COMPLIANCE_ACCOUNTS_CONFIG")
308
+ if os.path.exists(config_path):
309
+ console.print(f" ✅ Using accounts config file: {config_path}")
310
+ else:
311
+ console.print(f" ⚠️ Accounts config file not found: {config_path}")
312
+
313
+ if os.getenv("COMPLIANCE_WEIGHTS_CONFIG"):
314
+ config_path = os.getenv("COMPLIANCE_WEIGHTS_CONFIG")
315
+ if os.path.exists(config_path):
316
+ console.print(f" ✅ Using compliance weights config: {config_path}")
317
+ else:
318
+ console.print(f" ⚠️ Compliance weights config not found: {config_path}")
319
+
320
+ # Check for dynamic control weights
321
+ weight_vars = [var for var in os.environ.keys() if var.startswith("COMPLIANCE_WEIGHT_")]
322
+ if weight_vars:
323
+ console.print(f" ✅ Using {len(weight_vars)} dynamic control weights")
324
+
325
+ # Check for dynamic thresholds
326
+ threshold_vars = [var for var in os.environ.keys() if var.startswith("COMPLIANCE_THRESHOLD_")]
327
+ if threshold_vars:
328
+ console.print(f" ✅ Using {len(threshold_vars)} dynamic framework thresholds")
329
+
330
+ if not any([
331
+ os.getenv("COMPLIANCE_TARGET_ACCOUNTS"),
332
+ os.getenv("COMPLIANCE_ACCOUNTS_CONFIG"),
333
+ weight_vars,
334
+ threshold_vars
335
+ ]):
336
+ console.print(" ℹ️ Using default configuration (Organizations API discovery)")
337
+
338
+
339
+ @security.command("generate-config")
340
+ @click.option(
341
+ "--output-dir",
342
+ default="./artifacts/security/config",
343
+ help="Output directory for configuration templates"
344
+ )
345
+ @click.pass_context
346
+ def generate_config_templates(ctx, output_dir: str):
347
+ """
348
+ Generate universal configuration templates for security operations.
349
+
350
+ Creates templates for:
351
+ - Compliance weights and thresholds
352
+ - Account discovery configuration
353
+ - Environment variable examples
354
+ - Complete setup documentation
355
+
356
+ All templates support universal AWS compatibility with no hardcoded values.
357
+ """
358
+ print_info(f"Generating universal security configuration templates in {output_dir}...")
359
+
360
+ try:
361
+ generator = SecurityConfigTemplateGenerator(output_dir)
362
+ generator.generate_all_templates()
363
+
364
+ print_success("Configuration templates generated successfully!")
365
+ console.print("\n[bold yellow]Next steps:[/bold yellow]")
366
+ console.print("1. Review and customize the generated configuration files")
367
+ console.print("2. Set environment variables or copy configuration files to your preferred location")
368
+ console.print("3. Run: runbooks security assess --help")
369
+ console.print("4. Run: runbooks remediation --help")
370
+
371
+ except Exception as e:
372
+ print_error(f"Failed to generate configuration templates: {e}")
373
+ raise click.Abort()
374
+
375
+
376
+ if __name__ == "__main__":
377
+ security()
@@ -3,8 +3,28 @@ Enterprise MCP Validation Module
3
3
 
4
4
  Provides comprehensive validation between runbooks outputs and MCP server results
5
5
  for enterprise AWS operations with 99.5% accuracy target.
6
+
7
+ ENHANCED CAPABILITIES:
8
+ - Comprehensive 2-Way Validation System (NEW)
9
+ - Enhanced MCP validation from 0.0% → ≥99.5% accuracy
10
+ - Focus on successful modules: inventory, VPC, FinOps
11
+ - Enterprise coordination with qa-testing-specialist agent
12
+ - Evidence-based validation reports with audit trails
6
13
  """
7
14
 
8
15
  from .mcp_validator import MCPValidator, ValidationReport, ValidationResult, ValidationStatus
16
+ from .comprehensive_2way_validator import (
17
+ Comprehensive2WayValidator,
18
+ ValidationDiscrepancy,
19
+ Comprehensive2WayValidationResult
20
+ )
9
21
 
10
- __all__ = ["MCPValidator", "ValidationResult", "ValidationReport", "ValidationStatus"]
22
+ __all__ = [
23
+ "MCPValidator",
24
+ "ValidationResult",
25
+ "ValidationReport",
26
+ "ValidationStatus",
27
+ "Comprehensive2WayValidator",
28
+ "ValidationDiscrepancy",
29
+ "Comprehensive2WayValidationResult"
30
+ ]
@@ -16,6 +16,7 @@ Usage:
16
16
  """
17
17
 
18
18
  import asyncio
19
+ import os
19
20
  import sys
20
21
  from pathlib import Path
21
22
  from typing import List, Optional
@@ -87,7 +88,7 @@ def validate_all(tolerance: float, performance_target: float, save_report: bool,
87
88
 
88
89
 
89
90
  @cli.command()
90
- @click.option("--profile", default="ams-admin-Billing-ReadOnlyAccess-909135376185", help="AWS billing profile")
91
+ @click.option("--profile", default=lambda: os.getenv("BILLING_PROFILE", "default-billing-profile"), help="AWS billing profile")
91
92
  @click.option("--tolerance", default=5.0, help="Cost variance tolerance percentage")
92
93
  def validate_costs(profile: str, tolerance: float):
93
94
  """Validate Cost Explorer data accuracy."""
@@ -139,7 +140,7 @@ def validate_costs(profile: str, tolerance: float):
139
140
 
140
141
 
141
142
  @cli.command()
142
- @click.option("--profile", default="ams-admin-ReadOnlyAccess-909135376185", help="AWS management profile")
143
+ @click.option("--profile", default=lambda: os.getenv("MANAGEMENT_PROFILE", "default-management-profile"), help="AWS management profile")
143
144
  def validate_organizations(profile: str):
144
145
  """Validate Organizations API data accuracy."""
145
146
 
@@ -327,12 +328,12 @@ def status():
327
328
  except ImportError:
328
329
  table.add_row("MCP Integration", "[red]❌ Unavailable[/red]", "Install MCP dependencies")
329
330
 
330
- # Check AWS profiles
331
+ # Check AWS profiles - Universal environment support
331
332
  profiles = [
332
- "ams-admin-Billing-ReadOnlyAccess-909135376185",
333
- "ams-admin-ReadOnlyAccess-909135376185",
334
- "ams-centralised-ops-ReadOnlyAccess-335083429030",
335
- "ams-shared-services-non-prod-ReadOnlyAccess-499201730520",
333
+ os.getenv("BILLING_PROFILE", "default-billing-profile"),
334
+ os.getenv("MANAGEMENT_PROFILE", "default-management-profile"),
335
+ os.getenv("CENTRALISED_OPS_PROFILE", "default-ops-profile"),
336
+ os.getenv("SINGLE_ACCOUNT_PROFILE", "default-single-profile"),
336
337
  ]
337
338
 
338
339
  for profile in profiles: