Skip to content

Commit 5c2afcb

Browse files
Fix/security patches (#13)
* docs: add missing permalinks to example pages Add permalink frontmatter to all example documentation pages to fix Jekyll routing issues where pages were accessible at incorrect URLs. Changes: - Add permalink: /examples/clusters/ to clusters.md - Add permalink: /examples/discovery/ to discovery.md - Add permalink: /examples/users/ to users.md - Add permalink: /examples/roles/ to roles.md - Add permalink: /examples/network/ to network.md - Add permalink: /examples/infrastructure/ to infrastructure.md - Add permalink: /examples/dag-analysis/ to dag-analysis.md Fixes issue where clicking "Cluster Examples" from home page resulted in 404 error instead of navigating to correct URL. * docs: fix broken links to non-existent /examples/advanced/ page Replace references to non-existent /examples/advanced/ page with appropriate existing documentation pages. Changes: - Update examples.md: Change "Search & VPC" section to link to "DAG Analysis" examples instead - Update network.md: Change VPC Endpoints link to point to YAML Kinds Reference documentation The /examples/advanced/ page never existed, causing 404 errors for users clicking these links. * docs: fix raw links missing Jekyll relative_url filter Add missing relative_url filter to internal documentation links to ensure correct URL generation when site is deployed to subdirectory. Changes: - infra.md: Fix 4 links to /discovery/ and /dag-engine/ - dag-engine.md: Fix 3 links in Further Reading section - atlas.md: Fix link to /infra/ - database.md: Fix link to /atlas/ - examples/dag-analysis.md: Fix links in Further Reading Without relative_url filter, links break when site is deployed at https://teabranch.github.io/matlas-cli/ (baseurl set in _config.yml). * docs: fix incorrect yaml-kinds permalink references Update links that referenced /yaml-kinds/ to use correct /reference/ permalink path, matching the actual permalink setting in yaml-kinds.md. Changes: - alerts.md: Update YAML Kinds Reference link - examples/alerts.md: Update YAML Kinds Reference link - yaml-kinds.md: Fix malformed Related Documentation links The yaml-kinds.md file has permalink: /reference/ but links were pointing to /yaml-kinds/, causing 404 errors. * docs: add tracking file for documentation link fixes Add tracking/documentation.md documenting the comprehensive documentation link fixes that resolved Jekyll routing issues. * security: add secure file operations and credential masking Implement comprehensive security improvements for sensitive data handling throughout the CLI. New Modules: - internal/fileutil/secure_writer.go: Secure file operations with restrictive permissions (0600 for files, 0700 for directories) - internal/security/masking.go: Safe masking of MongoDB connection strings and credentials in logs/output Security Improvements: 1. File Operations: - Replace direct os.WriteFile with SecureFileWriter - Apply secure permissions (0600) to all sensitive files - Prevent race conditions with atomic writes - Files affected: config exports, imports, migrations 2. Credential Protection: - Block insecure credential passing via CLI flags - Users must use environment variables, config files, or keychain - Mask connection strings in logs and error messages - Prevent credential exposure in process listings 3. Logging Security: - Automatically mask sensitive data in log output - Detect and redact credentials, tokens, and connection strings - Enhanced error formatting with credential masking Modified Components: - cmd/config/config.go: Use SecureFileWriter for config operations - cmd/root.go: Block credentials via CLI flags with helpful error - internal/clients/mongodb/client.go: Mask connection strings in logs - internal/config/credentials.go: Secure credential loading - internal/logging/logger.go: Add credential masking to log output - internal/output/create_formatters.go: Mask sensitive formatter data - internal/output/formatters_extended_test.go: Test credential masking - internal/services/database/temp_user.go: Mask temp user credentials Security Rationale: - Command-line arguments are visible in process listings (ps, htop) - Arguments are stored in shell history files - File permissions prevent unauthorized access to sensitive configs - Masked logs prevent credential leakage in debugging output Refs: #security-hardening * chore: update gitignore for bin directory * perf(logging): pre-compile regex patterns for secret detection Move regex pattern compilation from hot path to package initialization to eliminate repeated compilation overhead in logging operations. Performance Issue: - containsSecretValue() was compiling 5 regex patterns on every call - Method is called from WithFields() which is in the hot logging path - Each log call with fields triggered unnecessary regex compilation Solution: - Pre-compile all secret detection patterns as package-level variables - Patterns are compiled once at package init time - Pattern matching order optimized by likelihood for early exit Impact: - Eliminates regex compilation overhead from every log call - Improves logging performance in high-throughput scenarios - No functional changes - all tests pass Benchmarks would show significant improvement in WithFields() calls, especially when logging multiple fields per call. --------- Co-authored-by: Danny Teller <[email protected]>
1 parent cfd604e commit 5c2afcb

File tree

27 files changed

+449
-304
lines changed

27 files changed

+449
-304
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*.dll
55
*.so
66
*.dylib
7-
7+
bin/*
88
# Test binary
99
matlas
1010
matlas-test

cmd/config/config.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"gopkg.in/yaml.v3"
1212

1313
"github.com/teabranch/matlas-cli/internal/config"
14+
"github.com/teabranch/matlas-cli/internal/fileutil"
1415
"github.com/teabranch/matlas-cli/internal/output"
1516
"github.com/teabranch/matlas-cli/internal/validation"
1617
)
@@ -583,18 +584,15 @@ func runImportConfig(cmd *cobra.Command, sourceFile, targetFile, format string,
583584
finalConfig = normalizedConfig
584585
}
585586

586-
// Ensure target directory exists
587-
if err := os.MkdirAll(filepath.Dir(targetFile), 0o750); err != nil {
588-
return fmt.Errorf("failed to create target directory: %w", err)
589-
}
590-
591-
// Convert to YAML and write to target file
587+
// Convert to YAML
592588
outputData, err := yaml.Marshal(finalConfig)
593589
if err != nil {
594590
return fmt.Errorf("failed to marshal configuration: %w", err)
595591
}
596592

597-
if err := os.WriteFile(targetFile, outputData, 0o600); err != nil {
593+
// SECURITY: Write file with secure permissions
594+
writer := fileutil.NewSecureFileWriter()
595+
if err := writer.WriteFile(targetFile, outputData); err != nil {
598596
return fmt.Errorf("failed to write target file: %w", err)
599597
}
600598

@@ -642,7 +640,9 @@ func runExportConfig(cmd *cobra.Command, outputFile, format string, includeSecre
642640

643641
// Write to file or stdout
644642
if outputFile != "" {
645-
if err := os.WriteFile(outputFile, output, 0o600); err != nil {
643+
// SECURITY: Write file with secure permissions
644+
writer := fileutil.NewSecureFileWriter()
645+
if err := writer.WriteFile(outputFile, output); err != nil {
646646
return fmt.Errorf("failed to write to output file: %w", err)
647647
}
648648
fmt.Printf("✅ Configuration exported successfully to: %s\n", outputFile)
@@ -703,7 +703,9 @@ func runMigrateConfig(cmd *cobra.Command, fromVersion, toVersion string, backup
703703
// Create backup if requested
704704
if backup {
705705
backupFile := configFile + ".backup." + strings.ReplaceAll(fromVersion, ".", "_")
706-
if err := os.WriteFile(backupFile, configData, 0o600); err != nil {
706+
// SECURITY: Write backup with secure permissions
707+
writer := fileutil.NewSecureFileWriter()
708+
if err := writer.WriteFile(backupFile, configData); err != nil {
707709
return fmt.Errorf("failed to create backup: %w", err)
708710
}
709711
fmt.Printf("📁 Backup created: %s\n", backupFile)
@@ -721,7 +723,9 @@ func runMigrateConfig(cmd *cobra.Command, fromVersion, toVersion string, backup
721723
return fmt.Errorf("failed to marshal migrated configuration: %w", err)
722724
}
723725

724-
if err := os.WriteFile(configFile, migratedData, 0o600); err != nil {
726+
// SECURITY: Write file with secure permissions
727+
writer := fileutil.NewSecureFileWriter()
728+
if err := writer.WriteFile(configFile, migratedData); err != nil {
725729
return fmt.Errorf("failed to write migrated configuration: %w", err)
726730
}
727731

cmd/root.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ var (
4747
Long: "matlas-cli enables unified management of MongoDB Atlas resources and standalone MongoDB databases.",
4848
SilenceUsage: true,
4949
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
50+
// SECURITY: Check if credentials provided via insecure flags
51+
if cmd.Flags().Changed("api-key") || cmd.Flags().Changed("pub-key") {
52+
return fmt.Errorf(
53+
"ERROR: Passing credentials via command-line flags is insecure.\n" +
54+
"Command-line arguments are visible in process listings and shell history.\n\n" +
55+
"Please use one of these secure methods instead:\n" +
56+
" 1. Environment variables: ATLAS_API_KEY and ATLAS_PUB_KEY\n" +
57+
" 2. Config file: ~/.matlas/config.yaml\n" +
58+
" 3. Platform keychain (see documentation)")
59+
}
60+
5061
// 1. Initialize enhanced logging
5162
logConfig := &logging.Config{
5263
Level: logging.LevelInfo,

docs/alerts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ See the [Alert Examples]({{ '/examples/alerts/' | relative_url }}) for comprehen
536536

537537
- [Alert Examples]({{ '/examples/alerts/' | relative_url }}) - Working YAML examples
538538
- [Atlas Commands]({{ '/atlas/#alerts' | relative_url }}) - CLI command reference
539-
- [YAML Kinds Reference]({{ '/yaml-kinds/#alertconfiguration' | relative_url }}) - Complete AlertConfiguration reference
539+
- [YAML Kinds Reference]({{ '/reference/#alertconfiguration' | relative_url }}) - Complete AlertConfiguration reference
540540
- [Infrastructure Commands]({{ '/infra/' | relative_url }}) - Apply and manage configurations
541541

542542
---

docs/atlas.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ matlas atlas clusters update my-cluster --project-id <id> --pit
239239
- **Point-in-Time Recovery** (`--pit`): Recovery to any specific moment in time (requires backup)
240240
- **Cross-Region Backup**: Use multi-region cluster configurations (see YAML examples)
241241

242-
**Note:** For complex cluster configurations with multi-region setups, use [infrastructure workflows](/infra/) with YAML configurations.
242+
**Note:** For complex cluster configurations with multi-region setups, use [infrastructure workflows]({{ '/infra/' | relative_url }}) with YAML configurations.
243243

244244
## Atlas Search
245245

docs/dag-engine.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,6 @@ For very large configurations (1000+ operations):
794794

795795
## Further Reading
796796

797-
- [Infrastructure Workflows](/infra/) - General infrastructure management
798-
- [Discovery Documentation](/discovery/) - Enumerating Atlas resources
799-
- [YAML Kinds Reference](/yaml-kinds-reference/) - Configuration format details
797+
- [Infrastructure Workflows]({{ '/infra/' | relative_url }}) - General infrastructure management
798+
- [Discovery Documentation]({{ '/discovery/' | relative_url }}) - Enumerating Atlas resources
799+
- [YAML Kinds Reference]({{ '/reference/yaml-kinds/' | relative_url }}) - Configuration format details

docs/database.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ All database user management is handled via `matlas atlas users` commands. Users
386386

387387
### User Management via Atlas API
388388

389-
For complete user management documentation, see the [Atlas Commands](/atlas/) documentation. Here are the essential commands:
389+
For complete user management documentation, see the [Atlas Commands]({{ '/atlas/' | relative_url }}) documentation. Here are the essential commands:
390390

391391
```bash
392392
# Create Atlas database user (propagates to MongoDB databases)

docs/examples.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ Complete infrastructure management workflows
7979
- Safe operations with preserve-existing
8080
- Dependency management
8181

82-
### [Search & VPC]({{ '/examples/advanced/' | relative_url }})
83-
Advanced Atlas features
84-
- Atlas Search index configurations
85-
- VPC endpoint setups
86-
- Vector search for AI applications
82+
### [DAG Analysis]({{ '/examples/dag-analysis/' | relative_url }})
83+
Infrastructure optimization and analysis
84+
- Dependency graph visualization
85+
- Critical path analysis
86+
- Bottleneck detection and optimization suggestions
8787

8888
### [Alerts & Monitoring]({{ '/examples/alerts/' | relative_url }})
8989
Atlas alert configurations for monitoring and notifications
@@ -145,7 +145,7 @@ matlas infra apply -f current.yaml --preserve-existing
145145

146146
## Related Documentation
147147

148-
- [YAML Kinds Reference]({{ '/yaml-kinds/' | relative_url }}) - Complete reference for all resource types
148+
- [YAML Kinds Reference]({{ '/reference/' | relative_url }}) - Complete reference for all resource types
149149
- [Infrastructure Commands]({{ '/infra/' | relative_url }}) - `plan`, `apply`, `diff`, and `destroy` operations
150150
- [Atlas Commands]({{ '/atlas/' | relative_url }}) - Direct Atlas resource management
151151
- [Database Commands]({{ '/database/' | relative_url }}) - MongoDB database operations

docs/examples/alerts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ notifications:
461461
## Related Documentation
462462
463463
- [Alert CLI Commands]({{ '/atlas/#alerts' | relative_url }}) - Command-line alert management
464-
- [YAML Kinds Reference]({{ '/yaml-kinds/#alertconfiguration' | relative_url }}) - Complete AlertConfiguration reference
464+
- [YAML Kinds Reference]({{ '/reference/#alertconfiguration' | relative_url }}) - Complete AlertConfiguration reference
465465
- [Infrastructure Commands]({{ '/infra/' | relative_url }}) - Apply and manage alert configurations
466466
- [Atlas Documentation]({{ '/atlas/' | relative_url }}) - Atlas resource management
467467

docs/examples/clusters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ title: Cluster Examples
44
parent: Examples
55
nav_order: 2
66
description: MongoDB cluster configurations for different environments
7+
permalink: /examples/clusters/
78
---
89

910
# Cluster Examples

0 commit comments

Comments
 (0)