## Summary This PR tightens repository quality enforcement around markdown and documentation. It adds `markdownlint` to the `cicd-checks` workflow, expands pre-commit coverage so markdown files are checked repo-wide, and cleans up the PP-58 documentation set to keep it aligned with the new policy. ## What changed - Added a `Markdownlint Check` entry to `.gitea/workflows/cicd-checks.yaml` - Added `markdownlint` to pre-commit and widened prettier coverage to include markdown files across the repo - Updated `README.md` to satisfy markdownlint line-length rules - Normalized the PP-58 documentation set: - `docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - `docs/adr/ADR003-deployable_runtime_image_contract.md` - `docs/DEVELOPMENT.md` - `docs/CICD_MULTI_STAGE_BUILD.md` - `docs/CICD_TROUBLESHOOTING_GUIDE.md` - `docs/SECURE_DOCKER_CICD.md` ## Validation - `pre-commit run markdownlint --files README.md docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - `pre-commit run prettier --files README.md docs/DEPLOYABLE_RUNTIME_CONTRACT.md` - Workflow YAML validation returned no errors ## Notes This change does not alter application runtime behavior. It only strengthens CI and documentation quality enforcement. Co-authored-by: copilotcoder <copilotcoder@darkhelm.org> Reviewed-on: #68
3.1 KiB
3.1 KiB
Secure Docker CI/CD with BuildKit Secrets
This document explains how our CI/CD pipeline securely handles SSH keys using Docker BuildKit secrets.
🔒 Security Benefits
Before (Insecure)
ARG SSH_PRIVATE_KEY
RUN echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- ❌ SSH key stored in Docker image layers
- ❌ Visible in
docker history - ❌ Can be extracted from images
- ❌ Security vulnerability
After (Secure)
RUN --mount=type=secret,id=ssh_private_key \
cp /run/secrets/ssh_private_key ~/.ssh/id_rsa && \
# ... use key ... && \
rm -rf ~/.ssh
- ✅ SSH key never stored in image layers
- ✅ Not visible in
docker history - ✅ Cannot be extracted from final image
- ✅ Secure by design
🏗️ CI/CD Pipeline Implementation
Gitea Actions Workflow
The CI workflow files under .gitea/workflows/ now use:
-
Docker BuildKit Enabled
export DOCKER_BUILDKIT=1 -
Secure Secret Mounting
# Create temporary SSH key file echo "${SSH_PRIVATE_KEY}" > /tmp/ssh_key chmod 600 /tmp/ssh_key # Build with secret mount docker build -f Dockerfile.cicd \ --secret id=ssh_private_key,src=/tmp/ssh_key \ -t cicd:latest . # Clean up immediately rm -f /tmp/ssh_key
Local Development
Use the secure build script:
./scripts/build-cicd-secure.sh plex-playlist-cicd:latest
🔧 Required Setup
1. Gitea Secrets Configuration
Ensure these secrets are configured in your Gitea repository:
SSH_PRIVATE_KEY: Your private SSH key for git operationsGITEA_TOKEN: Token for pushing to container registry
2. Docker BuildKit Support
- Gitea Actions: Automatically enabled with
DOCKER_BUILDKIT=1 - Local builds: Requires Docker 18.09+ with BuildKit enabled
- CI runners: Ensure BuildKit support in your runner environment
📋 Best Practices Applied
- Temporary Files: SSH keys are written to temporary files and immediately removed
- File Permissions: SSH keys get proper 600 permissions
- Multi-stage Security: Keys are cleaned up within the same RUN command
- No ARG Secrets: Never pass secrets via build arguments
- Dockerignore Protection:
.dockerignoreprevents accidental secret inclusion
🧪 Testing Security
Verify no secrets in image:
# Build the image
./scripts/build-cicd-secure.sh test-image
# Check history (should show no secrets)
docker history test-image
# Try to find SSH keys (should find none)
docker run --rm test-image find / -name "*rsa*" -o -name "*ssh*" 2>/dev/null
🚀 Migration Checklist
- Updated Dockerfile.cicd to use
--mount=type=secret - Removed insecure
ARG SSH_PRIVATE_KEY - Modified CI/CD workflow to use BuildKit secrets
- Added
.dockerignorepatterns for SSH keys - Created secure build script
- Documented security improvements