diff --git a/.gitignore b/.gitignore index 0f85f59..41ce270 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,4 @@ temp/ .gcp/firebase-adminsdk-fbsvc-cc86734eaf.json .env.staging .env.development +package-lock.json diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 7bd337c..1ef6dbd 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -432,6 +432,7 @@ export async function GET() { - [ ] All environment variables are set correctly - [ ] JWT secrets are cryptographically secure (32+ characters) +- [ ] No environment variables start with "GITHUB_" (reserved for GitHub Actions) - [ ] Database security rules are configured - [ ] API rate limiting is enabled - [ ] CORS is properly configured diff --git a/lib/config/README.md b/lib/config/README.md index f4d575e..c9debed 100644 --- a/lib/config/README.md +++ b/lib/config/README.md @@ -227,6 +227,7 @@ The configuration system validates: - **Secret strength** meets requirements - **Environment-specific** requirements - **Security best practices** +- **GitHub Actions compatibility** (no GITHUB_ prefixed variables) ### Validation Errors @@ -236,6 +237,7 @@ The system will exit with an error if: - Variables have invalid formats - Security requirements are not met - Environment-specific requirements are not satisfied +- Environment variables start with "GITHUB_" (reserved for GitHub Actions) ### Validation Warnings @@ -254,6 +256,12 @@ The system will warn about: - **ENCRYPTION_KEY**: Must be exactly 32 characters - **WEBHOOK_SECRET**: Must be at least 16 characters +### GitHub Actions Compatibility + +- **No GITHUB_ prefixed variables**: Environment variables starting with "GITHUB_" are reserved for GitHub Actions and will cause validation to fail +- This prevents conflicts with GitHub Actions reserved environment variables +- Use alternative naming conventions (e.g., `GH_CUSTOM_VAR` instead of `GITHUB_CUSTOM_VAR`) + ### Production Security - No debug mode in production diff --git a/lib/config/__tests__/config.test.ts b/lib/config/__tests__/config.test.ts index 537c0a6..66c9330 100644 --- a/lib/config/__tests__/config.test.ts +++ b/lib/config/__tests__/config.test.ts @@ -105,6 +105,43 @@ describe('Configuration System', () => { result.warnings.some(warning => warning.includes('placeholder')) ).toBe(true) }) + + it('should fail validation with GITHUB_ prefixed environment variables', () => { + process.env.GITHUB_SECRET = 'my-secret-value' + process.env.GITHUB_TOKEN = 'my-token-value' + + const result = validateConfiguration() + expect(result.success).toBe(false) + expect( + result.errors.some(error => error.includes('GITHUB_SECRET')) + ).toBe(true) + expect( + result.errors.some(error => error.includes('GITHUB_TOKEN')) + ).toBe(true) + expect( + result.errors.some(error => + error.includes('reserved for GitHub Actions') + ) + ).toBe(true) + + // Clean up + delete process.env.GITHUB_SECRET + delete process.env.GITHUB_TOKEN + }) + + it('should pass validation without GITHUB_ prefixed environment variables', () => { + // Ensure no GITHUB_ variables exist + Object.keys(process.env).forEach(key => { + if (key.startsWith('GITHUB_')) { + delete process.env[key] + } + }) + + const result = validateConfiguration() + expect( + result.errors.some(error => error.includes('GITHUB_')) + ).toBe(false) + }) }) describe('Environment-Specific Configuration', () => { diff --git a/lib/config/validator.ts b/lib/config/validator.ts index 80a34cd..a320488 100644 --- a/lib/config/validator.ts +++ b/lib/config/validator.ts @@ -225,6 +225,20 @@ function validateSecurityConfig( result.errors.push('WEBHOOK_SECRET must be at least 16 characters long') } + // Check for GitHub reserved environment variable names + const githubReservedVars = Object.keys(process.env).filter(key => + key.startsWith('GITHUB_') + ) + + if (githubReservedVars.length > 0) { + githubReservedVars.forEach(varName => { + result.errors.push( + `Environment variable "${varName}" starts with "GITHUB_" which is reserved for GitHub Actions. ` + + 'Please rename this variable to avoid conflicts with GitHub Actions reserved environment variables.' + ) + }) + } + // Check for weak secrets in production if (env === 'production') { const weakPatterns = ['password', '123456', 'secret', 'admin']