Skip to main content

secrets-management

Never commit secrets, manage credentials securely using environment variables, vaults, and Hack23 ISMS key management policy

Datos de origen

Repositorio
Hack23/cia
Última actividad en el origen
10 de febrero de 2026 a las 22:35
Idioma detectado de SKILL.md
inglés
Estrellas
241
Forks
56

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
secrets-management
description
Never commit secrets, manage credentials securely using environment variables, vaults, and Hack23 ISMS key management policy
license
Apache-2.0
# Secrets Management Skill ## Purpose This skill ensures secure handling of sensitive credentials, API keys, database passwords, and cryptographic keys throughout the CIA platform's development and deployment lifecycle. It enforces zero-tolerance for hardcoded secrets and mandates proper secrets management practices. ## When to Use This Skill Apply this skill when: - ✅ Adding new external API integrations (Riksdagen, World Bank) - ✅ Configuring database connections - ✅ Implementing authentication mechanisms - ✅ Setting up CI/CD pipelines - ✅ Deploying to new environments - ✅ Rotating credentials after security incidents - ✅ Reviewing code that handles configuration Do NOT skip for: - ❌ Development/testing credentials (still use proper secrets management) - ❌ "Temporary" hardcoded values (they become permanent) - ❌ Internal-only APIs (still require proper secrets management) ## Golden Rules of Secrets Management ### Rule #1: Never Commit Secrets to Git **ABSOLUTELY FORBIDDEN:** ```java // ❌ NEVER DO THIS - Hardcoded credentials public class DatabaseConfig { private static final String DB_URL = "jdbc:postgresql://prod-db.example.com:5432/cia"; private static final String DB_USERNAME = "admin"; private static final String DB_PASSWORD = "SuperSecret123!"; // SECURITY VIOLATION! } // ❌ NEVER DO THIS - API keys in code public class RiksdagenClient { private static final String API_KEY = "sk_live_abc123def456"; // EXPOSED! } ``` **SECURE ALTERNATIVES:** ```java // ✅ CORRECT - Use environment variables @Configuration public class DatabaseConfig { @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String dbUsername; @Value("${spring.datasource.password}") private String dbPassword; @Bean public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(dbUrl); config.setUsername(dbUsername); config.setPassword(dbPassword); return new HikariDataSource(config); } } // ✅ CORRECT - API keys from configuration @Service public class RiksdagenClient { private final String apiKey; public RiksdagenClient(@Value("${riksdagen.api.key}") String apiKey) { this.apiKey = apiKey; } } ``` ### Rule #2: Use Environment-Specific Configuration **Application Properties Structure:** ``` src/main/resources/ ├── application.yml # Defaults, no secrets ├── application-dev.yml # Development config ├── application-test.yml # Test config └── application-production.yml # Production config (secrets from env vars) ``` **application.yml (Safe to commit):** ```yaml spring: application: name: citizen-intelligence-agency datasource: # Values from environment variables url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/cia_dev} username: ${DATABASE_USERNAME:cia_user} password: ${DATABASE_PASSWORD} # No default for passwords! jpa: hibernate: ddl-auto: validate show-sql: false riksdagen: api: base-url: https://data.riksdagen.se/api key: ${RIKSDAGEN_API_KEY} # Must be provided via environment worldbank: api: base-url: https://api.worldbank.org/v2 key: ${WORLDBANK_API_KEY:} # Optional, empty default security: jwt: secret: ${JWT_SECRET} # Must be cryptographically random expiration: 86400 # 24 hours in seconds ``` **application-production.yml (Also safe):** ```yaml spring: datasource: # Production settings, but actual values from env vars hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 logging: level: root: WARN com.hack23.cia: INFO file: name: /var/log/cia/application.log ``` ### Rule #3: Environment Variables in Deployment **Docker Compose (Development):** ```yaml version: '3.8' services: cia-app: image: hack23/cia:latest environment: # Never commit .env file with real secrets DATABASE_URL: ${DATABASE_URL} DATABASE_USERNAME: ${DATABASE_USERNAME} DATABASE_PASSWORD: ${DATABASE_PASSWORD} RIKSDAGEN_API_KEY: ${RIKSDAGEN_API_KEY} JWT_SECRET: ${JWT_SECRET} env_file: - .env # Git-ignored file with secrets ``` **.env.example (Safe to commit as template):** ```bash # CIA Application Secrets # Copy to .env and fill in actual values # NEVER commit .env file! DATABASE_URL=jdbc:postgresql://localhost:5432/cia DATABASE_USERNAME=cia_user DATABASE_PASSWORD=CHANGE_ME RIKSDAGEN_API_KEY=your_api_key_here WORLDBANK_API_KEY=your_api_key_here JWT_SECRET=generate_with_openssl_rand_base64_64 ``` **.gitignore (MUST include):** ```gitignore # Secrets and credentials .env .env.local .env.production *.key *.pem *.p12 *.jks secrets/ credentials/ encrypt.properties # IDE secrets .idea/dataSources.xml .vscode/settings.json ``` ### Rule #4: Secrets Rotation Strategy **Quarterly Rotation Schedule:** ``` Q1: Rotate database passwords Q2: Rotate API keys Q3: Rotate JWT secrets Q4: Rotate encryption keys ``` **Rotation Process:** ```bash # 1. Generate new secret NEW_DB_PASSWORD=$(openssl rand -base64 32) # 2. Update application configuration (zero-downtime) kubectl set env deployment/cia-app DATABASE_PASSWORD=$NEW_DB_PASSWORD # 3. Update database psql -h db.example.com -U admin -c "ALTER USER cia_user PASSWORD '$NEW_DB_PASSWORD';" # 4. Verify application health kubectl rollout status deployment/cia-app # 5. Revoke old secret # (Keep for 24 hours in case of rollback) # 6. Document rotation in change log echo "$(date): Rotated database password" >> /var/log/secrets-rotation.log ``` ## Secrets Detection and Prevention ### Pre-Commit Hooks **Install git-secrets:** ```bash # Install git-secrets brew install git-secrets # macOS # or sudo apt-get install git-secrets # Ubuntu # Setup in repository cd /path/to/cia git secrets --install git secrets --register-aws git secrets --add 'password\s*=\s*["\'][^"\']{8,}["\']' git secrets --add 'apikey\s*=\s*["\'][^"\']{16,}["\']' git secrets --add 'secret\s*=\s*["\'][^"\']{16,}["\']' ``` **Custom Pre-Commit Hook (.git/hooks/pre-commit):** ```bash #!/bin/bash echo "Scanning for secrets..." # Check for common secret patterns if git diff --cached | grep -iE '(password|secret|api_?key|token)\s*[:=]\s*["\047][^"\047]{8,}["\047]'; then echo "❌ ERROR: Potential secret detected in staged files!" echo "Please remove hardcoded secrets and use environment variables." exit 1 fi # Check for specific file types that shouldn't be committed if git diff --cached --name-only | grep -E '\.(key|pem|p12|jks)$'; then echo "❌ ERROR: Attempting to commit key/certificate file!" exit 1 fi # Check for .env files if git diff --cached --name-only | grep -E '^\.env(\.|$)'; then echo "❌ ERROR: Attempting to commit .env file!" exit 1 fi echo "✅ No secrets detected" exit 0 ``` ### GitHub Actions Secret Scanning **.github/workflows/secret-scan.yml:** ```yaml name: Secret Scanning on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: gitleaks: name: Gitleaks Secret Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Run Gitleaks uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} - name: Upload SARIF report if: failure() uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif trufflehog: name: TruffleHog Secret Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: TruffleHog Scan uses: trufflesecurity/trufflehog@main with: path: ./ base: ${{ github.event.repository.default_branch }} head: HEAD ``` ## Secure Secrets Storage Solutions ### AWS Secrets Manager (Recommended for Production) **Java Integration:** ```java @Configuration public class SecretsManagerConfig { @Bean public SecretsManagerClient secretsManagerClient() { return SecretsManagerClient.builder() .region(Region.EU_WEST_1) .build(); } } @Service public class SecretsService { @Autowired private SecretsManagerClient secretsManager; private final Map<String, String> secretsCache = new ConcurrentHashMap<>(); public String getSecret(String secretName) { return secretsCache.computeIfAbsent(secretName, this::fetchSecret); } private String fetchSecret(String secretName) { GetSecretValueRequest request = GetSecretValueRequest.builder() .secretId(secretName) .build(); GetSecretValueResponse response = secretsManager.getSecretValue(request); return response.secretString(); } // Refresh secrets every hour @Scheduled(fixedRate = 3600000) public void refreshSecrets() { secretsCache.clear(); } } @Configuration public class DatabaseConfigWithSecretsManager { @Autowired private SecretsService secretsService; @Bean public DataSource dataSource() { // Fetch database credentials from Secrets Manager String dbSecret = secretsService.getSecret("cia/production/database"); // Parse JSON secret JSONObject secretJson = new JSONObject(dbSecret); String username = secretJson.getString("username"); String password = secretJson.getString("password"); String host = secretJson.getString("host"); HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:postgresql://" + host + ":5432/cia"); config.setUsername(username); config.setPassword(password); return new HikariDataSource(config); } } ``` **Create Secret in AWS:** ```bash # Create database credentials secret aws secretsmanager create-secret \ --name cia/production/database \ --description "CIA Production Database Credentials" \ --secret-string '{ "username": "cia_prod_user", "password": "GeneratedSecurePassword123!", "host": "cia-prod-db.xyz.eu-west-1.rds.amazonaws.com", "port": "5432", "database": "cia_production" }' # Grant application IAM role access aws secretsmanager put-resource-policy \ --secret-id cia/production/database \ --resource-policy '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::123456789:role/cia-app-role"}, "Action": "secretsmanager:GetSecretValue", "Resource": "*" }] }' ``` ### HashiCorp Vault (Alternative) **Java Integration:** ```java @Configuration public class VaultConfig { @Bean public VaultTemplate vaultTemplate() { VaultEndpoint endpoint = VaultEndpoint.create("vault.example.com", 8200); // Use token authentication (token from environment) TokenAuthentication authentication = new TokenAuthentication( System.getenv("VAULT_TOKEN") ); SslConfiguration ssl = SslConfiguration.forTrustStore( KeyStore.getInstance("PKCS12"), "changeit".toCharArray() ); return new VaultTemplate(endpoint, new ClientHttpRequestFactoryFactory().create( new ClientOptions(), ssl), authentication); } } @Service public class VaultSecretsService { @Autowired private VaultTemplate vaultTemplate; public String getDatabasePassword() { VaultResponse response = vaultTemplate .read("secret/data/cia/production/database"); return (String) response.getData().get("password"); } public Map<String, String> getRiksdagenApiConfig() { VaultResponse response = vaultTemplate .read("secret/data/cia/apis/riksdagen"); return response.getData(); } } ``` ### Spring Cloud Config Server (Encrypted Properties) **Config Server Setup:** ```yaml # bootstrap.yml spring: cloud: config: server: git: uri: https://github.com/Hack23/cia-config search-paths: '{application}' encrypt: enabled: true encrypt: key: ${CONFIG_SERVER_ENCRYPTION_KEY} ``` **Encrypted Properties:** ```yaml # cia-production.yml in config repo spring:
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub