// "Manages Docker secrets for GitLab stack projects, ensuring secrets are never in .env or docker-compose.yml, properly stored in ./secrets directory, and securely integrated with Docker secrets. Use when users need to create secrets, migrate from environment variables, validate secret configuration, audit secret usage, or ensure secrets are never committed to git."
| name | GitLab Stack Secrets Manager |
| description | Manages Docker secrets for GitLab stack projects, ensuring secrets are never in .env or docker-compose.yml, properly stored in ./secrets directory, and securely integrated with Docker secrets. Use when users need to create secrets, migrate from environment variables, validate secret configuration, audit secret usage, or ensure secrets are never committed to git. |
This skill manages secrets for GitLab stack projects, ensuring secrets are stored securely, never exposed in configuration files, and properly integrated with Docker secrets.
Activate this skill when the user requests:
CRITICAL RULES - Never violated:
Step 1: Determine the Operation
Ask yourself what the user wants to do:
Step 2: Gather Context
Check current project state:
Review docker-compose.yml:
Scan for security issues:
When: User wants to create new secrets
Step 1: Validate Prerequisites
ls -ld ./secrets
mkdir -p ./secrets
chmod 700 ./secrets
Step 2: Determine Secret Details
Ask the user (or infer from context):
Step 3: Create Secret File
echo -n "secret-value" > ./secrets/secret_name
chmod 600 ./secrets/secret_name
Step 4: Update docker-compose.yml
Add to top-level secrets section:
secrets:
secret_name:
file: ./secrets/secret_name
Add to appropriate service:
services:
myservice:
secrets:
- secret_name
Step 5: Verify .gitignore
Ensure ./secrets is excluded:
/secrets/
/secrets/*
!secrets/.gitkeep
When: User wants to validate secret configuration, or as part of other operations
Step 1: Directory Structure Validation
Check ./secrets exists:
[ -d ./secrets ] && echo "exists" || echo "missing"
Check permissions (should be 700):
stat -c "%a" ./secrets # Linux
stat -f "%OLp" ./secrets # macOS
Check ownership (not root):
ls -ld ./secrets
Step 2: Secret Files Validation
List all secret files:
find ./secrets -type f ! -name .gitkeep
For each file, check:
Step 3: docker-compose.yml Validation
Parse secrets section:
Check service secret references:
secrets: key, not environment varsCRITICAL: Scan for secrets in environment variables:
Step 4: .env File Validation
CRITICAL: Scan .env for secrets:
If secrets found in .env:
Step 5: Git Safety Check
Verify .gitignore excludes ./secrets:
grep -q "secrets" .gitignore
Check if any secrets are staged:
git status --porcelain | grep secrets/
Check git history for secrets (if requested):
git log --all --full-history -- ./secrets/
Step 6: Generate Validation Report
🔐 Secrets Validation Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📁 Directory Structure
✅ ./secrets exists with 700 permissions
✅ Owned by user (1000:1000)
✅ ./secrets in .gitignore
📄 Secret Files (3)
✅ db_password - 600 permissions, 32 bytes
✅ api_key - 600 permissions, 64 bytes
⚠️ jwt_secret - 644 permissions (should be 600)
🐳 Docker Integration
✅ 3 secrets defined in docker-compose.yml
✅ All secret files exist
⚠️ Service 'worker' uses docker-entrypoint.sh
❌ CRITICAL SECURITY ISSUES
❌ .env contains secrets:
* DB_PASSWORD=supersecret123
* API_KEY=sk_live_abc123
** IMMEDIATE ACTION REQUIRED **
❌ docker-compose.yml environment variables contain secrets:
* Service 'app' - JWT_SECRET in environment
** MUST MIGRATE TO DOCKER SECRETS **
✅ Git Safety
✅ No secrets in git staging
✅ .gitignore properly configured
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Status: FAILED (2 critical issues)
🔧 IMMEDIATE ACTIONS REQUIRED
1. Migrate secrets from .env to Docker secrets
2. Remove secrets from docker-compose.yml environment
3. Fix permissions on jwt_secret file
When: Secrets found in .env or docker-compose.yml environment variables
CRITICAL: This is a security issue that must be fixed
Step 1: Identify Secrets to Migrate
Scan .env for secret patterns:
grep -E "(PASSWORD|SECRET|KEY|TOKEN|API)" .env
Scan docker-compose.yml environment sections:
# Look for patterns in environment variables
List all detected secrets with:
Step 2: Confirm with User
Present findings and ask:
Step 3: Create Secret Files
For each secret to migrate:
echo -n "$value" > ./secrets/secret_name
chmod 600 ./secrets/secret_name
Step 4: Update Service Configurations
For each service using the secret:
_FILE suffix:
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
Step 5: Clean Up
Step 6: Verification
When: Need to generate secure random secrets
Step 1: Determine Format Requirements
Common formats:
Step 2: Determine Length
Standard lengths:
Step 3: Generate Secret
Use cryptographically secure methods:
# Alphanumeric (32 chars)
openssl rand -base64 32 | tr -d '/+=' | head -c 32
# Hex (64 chars)
openssl rand -hex 32
# Base64 (32 bytes)
openssl rand -base64 32
# UUID
uuidgen
# Custom (e.g., 16 alphanumeric)
LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16
Step 4: Store Securely
echo -n "$secret" > ./secrets/secret_name
chmod 600 ./secrets/secret_name
When: User wants to audit secret usage, find leaks, or review security
Step 1: Secret Inventory
List all secrets with details:
Step 2: Usage Analysis
For each secret:
Step 3: Find Unused Secrets
Step 4: Leak Detection
Check common leak locations:
.env file (CRITICAL):
grep -E "(PASSWORD|SECRET|KEY|TOKEN)" .env
docker-compose.yml environment (CRITICAL):
Configuration files:
grep -r "password\|secret\|key" ./config/
Git history:
git log -p --all -S "secret-pattern"
Docker logs:
Step 5: Permission Audit
Check all files in ./secrets:
find ./secrets -type f -not -perm 600
Check directory permissions:
[ "$(stat -c '%a' ./secrets)" = "700" ]
Check ownership:
find ./secrets -user root
Step 6: Generate Audit Report
Include:
When: Container doesn't support native Docker secrets
Step 1: Determine Necessity
Check if container supports secrets:
_FILE suffix ✅Only create entrypoint if:
_FILE suffix supportStep 2: Identify Required Secrets
List secrets that need to be loaded:
Step 3: Generate Entrypoint Script
#!/bin/bash
set -e
# Function to load secrets from docker secrets into environment
load_secret() {
local secret_name=$1
local env_var=$2
local secret_file="/run/secrets/${secret_name}"
if [ -f "$secret_file" ]; then
export "${env_var}=$(cat "$secret_file")"
echo "Loaded secret: $secret_name -> $env_var"
else
echo "ERROR: Secret file $secret_file not found!" >&2
exit 1
fi
}
# Load all required secrets
load_secret "db_password" "DB_PASSWORD"
load_secret "api_key" "API_KEY"
load_secret "jwt_secret" "JWT_SECRET"
# Execute the main command
exec "$@"
Step 4: Set Permissions
chmod +x docker-entrypoint.sh
Step 5: Update docker-compose.yml
services:
myservice:
entrypoint: /docker-entrypoint.sh
command: ["original-command"]
volumes:
- ./docker-entrypoint.sh:/docker-entrypoint.sh:ro
secrets:
- db_password
- api_key
Step 6: Document
Add comment explaining why entrypoint is needed:
# docker-entrypoint.sh required because this container
# doesn't support Docker secrets natively
When managing secrets:
These are must-pass security criteria:
User: "Set up secrets for my database"
1. Check current state
- ./secrets missing → create it
- docker-compose.yml has DB_PASSWORD in environment → CRITICAL ISSUE
2. Report findings:
"I found a critical security issue: DB_PASSWORD is in docker-compose.yml
environment variables. I'll migrate this to Docker secrets."
3. Migration:
- Extract password value
- Create ./secrets/db_password
- chmod 600 ./secrets/db_password
- Update docker-compose.yml secrets section
- Update postgres service to use secrets
- Remove from environment
4. Verification:
- Run validation
- Confirm no secrets in compose
- Check .gitignore
- Verify permissions
5. Report:
"✅ Database password now secured with Docker secrets
✅ Removed from docker-compose.yml environment
✅ File permissions set correctly
✅ Added to .gitignore"
This skill ensures secrets are managed securely and never exposed in configuration files or version control.