Initial commit
This commit is contained in:
346
skills/secrets-management/SKILL.md
Normal file
346
skills/secrets-management/SKILL.md
Normal file
@@ -0,0 +1,346 @@
|
||||
---
|
||||
name: secrets-management
|
||||
description: Implement secure secrets management for CI/CD pipelines using Vault, AWS Secrets Manager, or native platform solutions. Use when handling sensitive credentials, rotating secrets, or securing CI/CD environments.
|
||||
---
|
||||
|
||||
# Secrets Management
|
||||
|
||||
Secure secrets management practices for CI/CD pipelines using Vault, AWS Secrets Manager, and other tools.
|
||||
|
||||
## Purpose
|
||||
|
||||
Implement secure secrets management in CI/CD pipelines without hardcoding sensitive information.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Store API keys and credentials
|
||||
- Manage database passwords
|
||||
- Handle TLS certificates
|
||||
- Rotate secrets automatically
|
||||
- Implement least-privilege access
|
||||
|
||||
## Secrets Management Tools
|
||||
|
||||
### HashiCorp Vault
|
||||
- Centralized secrets management
|
||||
- Dynamic secrets generation
|
||||
- Secret rotation
|
||||
- Audit logging
|
||||
- Fine-grained access control
|
||||
|
||||
### AWS Secrets Manager
|
||||
- AWS-native solution
|
||||
- Automatic rotation
|
||||
- Integration with RDS
|
||||
- CloudFormation support
|
||||
|
||||
### Azure Key Vault
|
||||
- Azure-native solution
|
||||
- HSM-backed keys
|
||||
- Certificate management
|
||||
- RBAC integration
|
||||
|
||||
### Google Secret Manager
|
||||
- GCP-native solution
|
||||
- Versioning
|
||||
- IAM integration
|
||||
|
||||
## HashiCorp Vault Integration
|
||||
|
||||
### Setup Vault
|
||||
|
||||
```bash
|
||||
# Start Vault dev server
|
||||
vault server -dev
|
||||
|
||||
# Set environment
|
||||
export VAULT_ADDR='http://127.0.0.1:8200'
|
||||
export VAULT_TOKEN='root'
|
||||
|
||||
# Enable secrets engine
|
||||
vault secrets enable -path=secret kv-v2
|
||||
|
||||
# Store secret
|
||||
vault kv put secret/database/config username=admin password=secret
|
||||
```
|
||||
|
||||
### GitHub Actions with Vault
|
||||
|
||||
```yaml
|
||||
name: Deploy with Vault Secrets
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Import Secrets from Vault
|
||||
uses: hashicorp/vault-action@v2
|
||||
with:
|
||||
url: https://vault.example.com:8200
|
||||
token: ${{ secrets.VAULT_TOKEN }}
|
||||
secrets: |
|
||||
secret/data/database username | DB_USERNAME ;
|
||||
secret/data/database password | DB_PASSWORD ;
|
||||
secret/data/api key | API_KEY
|
||||
|
||||
- name: Use secrets
|
||||
run: |
|
||||
echo "Connecting to database as $DB_USERNAME"
|
||||
# Use $DB_PASSWORD, $API_KEY
|
||||
```
|
||||
|
||||
### GitLab CI with Vault
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
image: vault:latest
|
||||
before_script:
|
||||
- export VAULT_ADDR=https://vault.example.com:8200
|
||||
- export VAULT_TOKEN=$VAULT_TOKEN
|
||||
- apk add curl jq
|
||||
script:
|
||||
- |
|
||||
DB_PASSWORD=$(vault kv get -field=password secret/database/config)
|
||||
API_KEY=$(vault kv get -field=key secret/api/credentials)
|
||||
echo "Deploying with secrets..."
|
||||
# Use $DB_PASSWORD, $API_KEY
|
||||
```
|
||||
|
||||
**Reference:** See `references/vault-setup.md`
|
||||
|
||||
## AWS Secrets Manager
|
||||
|
||||
### Store Secret
|
||||
|
||||
```bash
|
||||
aws secretsmanager create-secret \
|
||||
--name production/database/password \
|
||||
--secret-string "super-secret-password"
|
||||
```
|
||||
|
||||
### Retrieve in GitHub Actions
|
||||
|
||||
```yaml
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-west-2
|
||||
|
||||
- name: Get secret from AWS
|
||||
run: |
|
||||
SECRET=$(aws secretsmanager get-secret-value \
|
||||
--secret-id production/database/password \
|
||||
--query SecretString \
|
||||
--output text)
|
||||
echo "::add-mask::$SECRET"
|
||||
echo "DB_PASSWORD=$SECRET" >> $GITHUB_ENV
|
||||
|
||||
- name: Use secret
|
||||
run: |
|
||||
# Use $DB_PASSWORD
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### Terraform with AWS Secrets Manager
|
||||
|
||||
```hcl
|
||||
data "aws_secretsmanager_secret_version" "db_password" {
|
||||
secret_id = "production/database/password"
|
||||
}
|
||||
|
||||
resource "aws_db_instance" "main" {
|
||||
allocated_storage = 100
|
||||
engine = "postgres"
|
||||
instance_class = "db.t3.large"
|
||||
username = "admin"
|
||||
password = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)["password"]
|
||||
}
|
||||
```
|
||||
|
||||
## GitHub Secrets
|
||||
|
||||
### Organization/Repository Secrets
|
||||
|
||||
```yaml
|
||||
- name: Use GitHub secret
|
||||
run: |
|
||||
echo "API Key: ${{ secrets.API_KEY }}"
|
||||
echo "Database URL: ${{ secrets.DATABASE_URL }}"
|
||||
```
|
||||
|
||||
### Environment Secrets
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment: production
|
||||
steps:
|
||||
- name: Deploy
|
||||
run: |
|
||||
echo "Deploying with ${{ secrets.PROD_API_KEY }}"
|
||||
```
|
||||
|
||||
**Reference:** See `references/github-secrets.md`
|
||||
|
||||
## GitLab CI/CD Variables
|
||||
|
||||
### Project Variables
|
||||
|
||||
```yaml
|
||||
deploy:
|
||||
script:
|
||||
- echo "Deploying with $API_KEY"
|
||||
- echo "Database: $DATABASE_URL"
|
||||
```
|
||||
|
||||
### Protected and Masked Variables
|
||||
- Protected: Only available in protected branches
|
||||
- Masked: Hidden in job logs
|
||||
- File type: Stored as file
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Never commit secrets** to Git
|
||||
2. **Use different secrets** per environment
|
||||
3. **Rotate secrets regularly**
|
||||
4. **Implement least-privilege access**
|
||||
5. **Enable audit logging**
|
||||
6. **Use secret scanning** (GitGuardian, TruffleHog)
|
||||
7. **Mask secrets in logs**
|
||||
8. **Encrypt secrets at rest**
|
||||
9. **Use short-lived tokens** when possible
|
||||
10. **Document secret requirements**
|
||||
|
||||
## Secret Rotation
|
||||
|
||||
### Automated Rotation with AWS
|
||||
|
||||
```python
|
||||
import boto3
|
||||
import json
|
||||
|
||||
def lambda_handler(event, context):
|
||||
client = boto3.client('secretsmanager')
|
||||
|
||||
# Get current secret
|
||||
response = client.get_secret_value(SecretId='my-secret')
|
||||
current_secret = json.loads(response['SecretString'])
|
||||
|
||||
# Generate new password
|
||||
new_password = generate_strong_password()
|
||||
|
||||
# Update database password
|
||||
update_database_password(new_password)
|
||||
|
||||
# Update secret
|
||||
client.put_secret_value(
|
||||
SecretId='my-secret',
|
||||
SecretString=json.dumps({
|
||||
'username': current_secret['username'],
|
||||
'password': new_password
|
||||
})
|
||||
)
|
||||
|
||||
return {'statusCode': 200}
|
||||
```
|
||||
|
||||
### Manual Rotation Process
|
||||
|
||||
1. Generate new secret
|
||||
2. Update secret in secret store
|
||||
3. Update applications to use new secret
|
||||
4. Verify functionality
|
||||
5. Revoke old secret
|
||||
|
||||
## External Secrets Operator
|
||||
|
||||
### Kubernetes Integration
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
namespace: production
|
||||
spec:
|
||||
provider:
|
||||
vault:
|
||||
server: "https://vault.example.com:8200"
|
||||
path: "secret"
|
||||
version: "v2"
|
||||
auth:
|
||||
kubernetes:
|
||||
mountPath: "kubernetes"
|
||||
role: "production"
|
||||
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: database-credentials
|
||||
namespace: production
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: vault-backend
|
||||
kind: SecretStore
|
||||
target:
|
||||
name: database-credentials
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: username
|
||||
remoteRef:
|
||||
key: database/config
|
||||
property: username
|
||||
- secretKey: password
|
||||
remoteRef:
|
||||
key: database/config
|
||||
property: password
|
||||
```
|
||||
|
||||
## Secret Scanning
|
||||
|
||||
### Pre-commit Hook
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# .git/hooks/pre-commit
|
||||
|
||||
# Check for secrets with TruffleHog
|
||||
docker run --rm -v "$(pwd):/repo" \
|
||||
trufflesecurity/trufflehog:latest \
|
||||
filesystem --directory=/repo
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ Secret detected! Commit blocked."
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### CI/CD Secret Scanning
|
||||
|
||||
```yaml
|
||||
secret-scan:
|
||||
stage: security
|
||||
image: trufflesecurity/trufflehog:latest
|
||||
script:
|
||||
- trufflehog filesystem .
|
||||
allow_failure: false
|
||||
```
|
||||
|
||||
## Reference Files
|
||||
|
||||
- `references/vault-setup.md` - HashiCorp Vault configuration
|
||||
- `references/github-secrets.md` - GitHub Secrets best practices
|
||||
|
||||
## Related Skills
|
||||
|
||||
- `github-actions-templates` - For GitHub Actions integration
|
||||
- `gitlab-ci-patterns` - For GitLab CI integration
|
||||
- `deployment-pipeline-design` - For pipeline architecture
|
||||
Reference in New Issue
Block a user