Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Source control and worktrees
.git
.git/**
.worktrees/

# Graphify artifacts
.graphify/
.graphifyignore
graphify-out/

# Dependency environments
**/.venv/
**/venv/
**/env/
**/ENV/
**/node_modules/

# Coverage, caches, and generated Python files
**/.coverage
**/.coverage.*
**/coverage/
**/htmlcov/
**/.cache/
**/.npm/
**/.nox/
**/.tox/
**/.mypy_cache/
**/.pytest_cache/
**/.ruff_cache/
**/.vite/
**/.eslintcache
**/__pycache__/
**/*.py[cod]

# Build outputs
**/build/
**/dist/
**/out/
**/.next/
**/*.egg-info/
**/wheels/

# Secrets and local configuration
**/.env
**/.env.*
!**/.env.example
**/.npmrc
**/.pypirc
**/.secrets/
**/secrets/
**/*credentials*.json
**/*.key
**/*.pem
**/id_ed25519*
**/id_rsa*

# Local application data and logs
/backups/
/data/
/backend/data/
**/*.db
**/*.sqlite
**/*.sqlite3
**/*.log
**/logs/
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ jobs:
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

Expand All @@ -236,7 +239,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ needs.prepare.outputs.docker_tags }}
labels: ${{ needs.prepare.outputs.docker_labels }}
Expand Down
42 changes: 25 additions & 17 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:

jobs:
# ──────────────────────────────────────────────
# Python SAST Bandit
# Python SAST - Bandit
# ──────────────────────────────────────────────
bandit:
name: Bandit (Python SAST)
Expand All @@ -25,20 +25,22 @@ jobs:

- uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version-file: '.python-version'

- name: Install Bandit
run: pip install bandit[toml]
run: |
python -m pip install --upgrade pip==25.3
pip install bandit[toml]

- name: Run Bandit scan
continue-on-error: true
run: |
bandit -r backend/app \
-f json \
-o bandit-results.json \
--severity-level medium \
--confidence-level medium \
-x 'backend/app/__pycache__' \
|| true
-x 'backend/app/__pycache__'

- name: Display results
if: always()
Expand All @@ -56,7 +58,7 @@ jobs:
retention-days: 30

# ──────────────────────────────────────────────
# Python dependency audit pip-audit
# Python dependency audit - pip-audit
# ──────────────────────────────────────────────
pip-audit:
name: pip-audit (Python Dependencies)
Expand All @@ -66,18 +68,20 @@ jobs:

- uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version-file: '.python-version'

- name: Install pip-audit
run: pip install pip-audit
run: |
python -m pip install --upgrade pip==25.3
pip install pip-audit

- name: Run pip-audit
continue-on-error: true
run: |
pip-audit \
-r backend/requirements.txt \
--format json \
--output pip-audit-results.json \
|| true
--output pip-audit-results.json

- name: Display results
if: always()
Expand All @@ -95,7 +99,7 @@ jobs:
retention-days: 30

# ──────────────────────────────────────────────
# JavaScript dependency audit npm audit
# JavaScript dependency audit - npm audit
# ──────────────────────────────────────────────
npm-audit:
name: npm audit (JS Dependencies)
Expand All @@ -105,18 +109,22 @@ jobs:

- uses: actions/setup-node@v6
with:
node-version: '24'
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json

- name: Install pinned npm
working-directory: frontend
run: npm install --global "$(node -p "require('./package.json').packageManager")"

- name: Install dependencies
working-directory: frontend
run: npm ci

- name: Run npm audit
working-directory: frontend
run: |
npm audit --json > npm-audit-results.json 2>&1 || true
continue-on-error: true
run: npm audit --json > npm-audit-results.json 2>&1

- name: Display results
if: always()
Expand All @@ -135,7 +143,7 @@ jobs:
retention-days: 30

# ──────────────────────────────────────────────
# Container image scanning Trivy
# Container image scanning - Trivy
# ──────────────────────────────────────────────
trivy:
name: Trivy (Container Scan)
Expand Down Expand Up @@ -172,7 +180,7 @@ jobs:
exit-code: '0'

# ──────────────────────────────────────────────
# Dockerfile linting Hadolint
# Dockerfile linting - Hadolint
# ──────────────────────────────────────────────
hadolint:
name: Hadolint (Dockerfile Lint)
Expand All @@ -196,7 +204,7 @@ jobs:
category: 'hadolint'

# ──────────────────────────────────────────────
# Secret scanning Gitleaks
# Secret scanning - Gitleaks
# ──────────────────────────────────────────────
gitleaks:
name: Gitleaks (Secret Detection)
Expand Down
89 changes: 65 additions & 24 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Set up Python 3.14
uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version-file: '.python-version'

- name: Cache pip dependencies
uses: actions/cache@v5
Expand All @@ -34,7 +34,7 @@ jobs:
- name: Install dependencies
working-directory: backend
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade pip==25.3
pip install -r requirements.txt
pip install -r requirements-dev.txt

Expand Down Expand Up @@ -66,9 +66,13 @@ jobs:
- name: Set up Node.js 24
uses: actions/setup-node@v6
with:
node-version: '24'
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json

- name: Install pinned npm
working-directory: frontend
run: npm install --global "$(node -p "require('./package.json').packageManager")"

- name: Install dependencies
working-directory: frontend
Expand Down Expand Up @@ -101,21 +105,25 @@ jobs:
- name: Set up Python 3.14
uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version-file: '.python-version'

- name: Set up Node.js 24
uses: actions/setup-node@v6
with:
node-version: '24'
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json

- name: Install Python dependencies
working-directory: backend
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade pip==25.3
pip install ruff mypy
pip install -r requirements.txt

- name: Install pinned npm
working-directory: frontend
run: npm install --global "$(node -p "require('./package.json').packageManager")"

- name: Install Node dependencies
working-directory: frontend
Expand All @@ -131,7 +139,8 @@ jobs:

- name: Type check Python code
working-directory: backend
run: mypy app/ || true
run: mypy app/
continue-on-error: true

- name: Lint TypeScript code
working-directory: frontend
Expand All @@ -154,6 +163,21 @@ jobs:
- name: Build Docker image
run: |
docker build -t dockervault:test .

- name: Check runtime binaries
run: |
docker run --rm --entrypoint /bin/bash dockervault:test -o pipefail -c '
set -eu
for binary in rclone rsync ssh sftp sshpass age curl; do
command -v "$binary"
done
rclone version | grep -F "rclone v1.72.1"
rsync --version
ssh -V
sshpass -V
age --version
curl --version
'

- name: Run integration tests
run: |
Expand All @@ -163,16 +187,25 @@ jobs:
-v /var/run/docker.sock:/var/run/docker.sock:ro \
dockervault:test

# Wait for container to be healthy with retries
# Wait for backend liveness through nginx with retries
echo "Waiting for container to be ready..."
ready=false
for i in {1..30}; do
if curl -sf http://localhost:8080 > /dev/null 2>&1; then
echo "Frontend is ready!"
if health=$(curl -fsS http://localhost:8080/health 2>/dev/null) && \
[[ "$health" == *'"status":"healthy"'* ]]; then
echo "Backend is healthy through nginx!"
ready=true
break
fi
echo "Attempt $i/30 - waiting..."
sleep 2
done

if [ "$ready" != true ]; then
echo "Backend did not become healthy through nginx"
docker logs dockervault-test
exit 1
fi

# Show container logs for debugging
echo "=== Container logs ==="
Expand All @@ -181,16 +214,12 @@ jobs:

# Test frontend serves correctly
curl -f http://localhost:8080 || exit 1

# Test backend health directly (internal port)
docker exec dockervault-test curl -sf http://localhost:8000/health || echo "Backend health check not available"

# Test API through frontend proxy
curl -f http://localhost:8080/api/v1/docker/health || echo "API health check failed (may be expected without Docker socket)"

# Clean up
docker stop dockervault-test
docker rm dockervault-test
docker exec dockervault-test curl -fsS http://localhost:8000/health

# Test a public API endpoint through the nginx proxy
curl -fsS http://localhost:8080/api/v1/auth/status

- name: Clean up
if: always()
Expand All @@ -211,7 +240,7 @@ jobs:
- name: Set up Python 3.14
uses: actions/setup-python@v6
with:
python-version: '3.14'
python-version-file: '.python-version'

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.35.0
Expand All @@ -231,12 +260,24 @@ jobs:

- name: Run pip-audit on Python dependencies
working-directory: backend
continue-on-error: true
run: |
python -m pip install --upgrade pip==25.3
pip install pip-audit
pip-audit -r requirements.txt || true
pip-audit -r requirements.txt

- name: Set up Node.js 24
uses: actions/setup-node@v6
with:
node-version-file: '.node-version'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json

- name: Install pinned npm
working-directory: frontend
run: npm install --global "$(node -p "require('./package.json').packageManager")"

- name: Run npm audit on Node dependencies
working-directory: frontend
run: |
npm audit --audit-level high || true

continue-on-error: true
run: npm audit --audit-level high
Loading
Loading