Thank you for your interest in contributing! This project demonstrates secure AWS remote account access patterns and welcomes contributions that improve security, usability, and documentation.
- Code of Conduct
- Getting Started
- How to Contribute
- Development Setup
- Pull Request Process
- Coding Standards
- Security Considerations
This project follows the Contributor Covenant code of conduct. By participating, you are expected to uphold this code.
- Security improvements: Better authentication flows, permission models, or vulnerability fixes
- User experience enhancements: Simpler setup processes, better error messages, clearer documentation
- New examples: Additional use cases, integration patterns, or deployment scenarios
- Documentation: Tutorials, security guides, troubleshooting help, or API documentation
- Bug fixes: Issues with existing functionality
- Testing: Improved test coverage, integration tests, or security validation
- Contributions that make AWS integration simpler for end users
- Security-first approaches that follow AWS best practices
- Clear, well-documented code with examples
- Comprehensive testing of new functionality
- Go 1.21 or later
- AWS CLI v2 configured with appropriate permissions
- Docker (for running examples locally)
- Git
-
Fork and clone the repository
git clone https://github.com/yourusername/aws-remote-access-patterns.git cd aws-remote-access-patterns -
Install dependencies
go mod download go mod tidy
-
Set up AWS credentials for testing
# For cross-account testing, you'll need: export AWS_ACCOUNT_ID="your-aws-account-id" export TEMPLATE_S3_BUCKET="your-test-bucket" # For external tool testing: aws configure # or use AWS SSO
-
Run tests
go test ./... -
Try the examples
# Test the CLI tool cd examples/simple-cli go run main.go --compare # Test the SaaS service cd examples/simple-saas go run main.go
Before creating an issue, please:
- Check existing issues to avoid duplicates
- Use the issue templates when available
- Provide detailed information:
- Go version and operating system
- AWS SDK versions
- Steps to reproduce the issue
- Expected vs actual behavior
- Error messages or logs
Enhancement suggestions should include:
- Clear description of the proposed feature
- Use case - why would this be useful?
- User experience impact - how does this improve simplicity?
- Security considerations - any security implications?
- Implementation ideas (optional)
- Create an issue describing what you plan to work on
- Wait for feedback from maintainers before investing significant time
- Fork the repository and create a feature branch
-
Create a feature branch
git checkout -b feature/amazing-new-feature
-
Make your changes
- Follow the coding standards
- Add tests for new functionality
- Update documentation as needed
-
Test thoroughly
# Run all tests go test ./... # Test examples cd examples/simple-cli && go run main.go --setup cd examples/simple-saas && go run main.go # Run security checks go vet ./...
-
Update documentation
- Update relevant README sections
- Add/update code comments
- Update CHANGELOG.md following Keep a Changelog
-
Commit your changes
git add . git commit -m "feat: add amazing new feature - Implements X to improve Y - Adds tests for Z scenario - Updates documentation Closes #123"
-
Push and create PR
git push origin feature/amazing-new-feature
Your PR must:
- ✅ Pass all tests (
go test ./...) - ✅ Follow coding standards (see below)
- ✅ Include tests for new functionality
- ✅ Update documentation as needed
- ✅ Have a clear description of changes
- ✅ Reference related issues with "Closes #123"
- ✅ Follow security best practices
- Automated checks run (tests, linting, security scans)
- Maintainer review focuses on:
- Code quality and security
- User experience impact
- Documentation completeness
- Test coverage
- Feedback incorporation and iteration
- Final approval and merge
- Use
gofmtandgoimportsfor formatting - Follow standard Go conventions from Effective Go
- Use meaningful variable names - clarity over brevity
- Add package and function comments for public APIs
// Good: Clear package documentation
// Package crossaccount provides secure cross-account AWS integration
// for SaaS services that need access to customer AWS accounts.
package crossaccount
// Good: Clear function documentation with examples
// GenerateSetupLink creates a one-click setup link for customer AWS integration.
//
// Example:
// setupResp, err := client.GenerateSetupLink("acme-corp", "Acme Corporation")
// if err != nil {
// return err
// }
// // Send setupResp.LaunchURL to customer
func (c *Client) GenerateSetupLink(customerID, customerName string) (*SetupResponse, error) {
// Validate inputs early
if customerID == "" {
return nil, fmt.Errorf("customer ID is required")
}
// Use clear, descriptive variable names
externalID := c.generateSecureExternalID(customerID)
// Return structured response with helpful information
return &SetupResponse{
LaunchURL: launchURL,
ExternalID: externalID,
// ... other fields
}, nil
}// Good: Descriptive error messages that help users
if err := client.CompleteSetup(ctx, req); err != nil {
return fmt.Errorf("failed to complete AWS setup for customer %s: %w", customerID, err)
}
// Good: User-friendly error responses
c.JSON(400, gin.H{
"error": "Setup verification failed",
"details": err.Error(),
"common_solutions": []string{
"Verify the Role ARN was copied correctly from CloudFormation outputs",
"Ensure the CloudFormation stack creation completed successfully",
"Check that the External ID matches the one provided during setup",
},
})// Good: Provide sensible defaults to minimize configuration
func New(cfg *Config) (*Client, error) {
// Set helpful defaults
if cfg.SessionDuration == 0 {
cfg.SessionDuration = time.Hour // 1 hour is reasonable
}
if cfg.DefaultRegion == "" {
cfg.DefaultRegion = "us-east-1" // Most common region
}
return &Client{config: cfg}, nil
}// Good: Test both happy path and error conditions
func TestGenerateSetupLink(t *testing.T) {
tests := []struct {
name string
customerID string
customerName string
wantErr bool
}{
{
name: "valid input",
customerID: "acme-corp",
customerName: "Acme Corporation",
wantErr: false,
},
{
name: "empty customer ID",
customerID: "",
customerName: "Acme Corporation",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &Client{config: testConfig()}
resp, err := client.GenerateSetupLink(tt.customerID, tt.customerName)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, resp)
} else {
assert.NoError(t, err)
assert.NotNil(t, resp)
assert.NotEmpty(t, resp.LaunchURL)
assert.NotEmpty(t, resp.ExternalID)
}
})
}
}All contributions are reviewed for security implications:
- Credential handling: No long-lived secrets, proper credential lifecycle
- Permission scope: Least privilege principles, clear permission boundaries
- Input validation: Proper validation and sanitization of user inputs
- Error information: Avoid leaking sensitive data in error messages
- Audit trails: Ensure actions are properly logged for security monitoring
// Good: Validate inputs early and clearly
func (c *Client) AssumeRole(ctx context.Context, customerID string) (aws.Config, error) {
if customerID == "" {
return aws.Config{}, fmt.Errorf("customer ID is required")
}
// Good: Use cryptographically secure random generation
randomBytes := make([]byte, 16)
if _, err := rand.Read(randomBytes); err != nil {
return aws.Config{}, fmt.Errorf("failed to generate secure external ID: %w", err)
}
// Good: Don't log sensitive information
log.Info("assuming role for customer", "customer_id", customerID)
// Never log: external_id, role_arn, or temporary credentials
}// ❌ DON'T: Store long-lived credentials
type BadCredentials struct {
AccessKey string // Long-lived, insecure
SecretKey string // Permanent secret
}
// ❌ DON'T: Use predictable external IDs
func badExternalID(customerID string) string {
return fmt.Sprintf("external-%s", customerID) // Predictable!
}
// ❌ DON'T: Over-privilege by default
var badPermissions = Permission{
Effect: "Allow",
Actions: []string{"*"}, // Too broad!
Resources: []string{"*"}, // Everything!
}
// ❌ DON'T: Log sensitive information
log.Info("role assumed", "external_id", externalID) // Sensitive!This project follows Semantic Versioning:
- MAJOR: Incompatible API changes
- MINOR: Backward-compatible functionality additions
- PATCH: Backward-compatible bug fixes
Update CHANGELOG.md with your changes:
## [Unreleased]
### Added
- New QuickConfig helper for common service types
- Additional permission templates for monitoring platforms
### Changed
- Improved error messages in setup validation
### Fixed
- Fixed race condition in credential caching
### Security
- Enhanced external ID generation for better entropy- Open an issue for questions about the codebase
- Check existing documentation in the
docs/directory - Review examples in the
examples/directory - Read the security guide in
SECURITY.md
Contributors will be recognized in:
CONTRIBUTORS.mdfile- Release notes for significant contributions
- GitHub contributor graphs
Thank you for helping make AWS integration more secure and user-friendly! 🚀