From ddf1549389f19a19147f5fb527fe9ff9d104b72a Mon Sep 17 00:00:00 2001 From: Jocelyn Lin Date: Wed, 4 Feb 2026 10:06:22 -0800 Subject: [PATCH] Implement proprietary path guardrails in GitHub workflows and pre-push hooks (#5703) * Implement proprietary path guardrails in GitHub workflows and pre-push hooks - Added a GitHub Actions workflow to check for proprietary paths in pull requests and pushes. - Introduced a pre-push hook to prevent pushing files from proprietary paths to the OSS repository. - Updated .gitignore to restrict certain application paths and added comments for clarity. * Add explicit permissions block to workflow Limit GITHUB_TOKEN to read-only access for security best practices. Co-Authored-By: Claude Opus 4.5 * Refactor pre-push hook to use grep pipeline Replace per-file loop with efficient grep operations. Removes is_proprietary function in favor of direct pattern matching. Co-Authored-By: Claude Opus 4.5 * Fix pre-push hook grep pipeline for husky compatibility Add || true to grep commands to prevent exit code 1 (no match) from aborting the subshell when husky's set -e is active. Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- .github/workflows/proprietary-path-guard.yml | 106 +++++++++++++++++++ .gitignore | 9 ++ .husky/pre-push | 79 ++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 .github/workflows/proprietary-path-guard.yml create mode 100755 .husky/pre-push diff --git a/.github/workflows/proprietary-path-guard.yml b/.github/workflows/proprietary-path-guard.yml new file mode 100644 index 000000000..8e0e71137 --- /dev/null +++ b/.github/workflows/proprietary-path-guard.yml @@ -0,0 +1,106 @@ +name: Proprietary Path Guard + +# ============================================================================= +# This workflow checks that PRs don't add files to proprietary paths. +# +# Proprietary paths: +# - extensions/ Reserved for enterprise extensions +# - apps/* Only apps/oss-app/ is allowed +# +# These paths are reserved for downstream forks and enterprise distributions. +# ============================================================================= + +on: + pull_request: + branches: [main, develop, master] + push: + branches: ['**'] + + # Manual trigger for testing + workflow_dispatch: + inputs: + reason: + description: 'Reason for manual run' + required: false + default: 'Testing' + +permissions: + contents: read + +jobs: + check-proprietary-paths: + name: Check for Proprietary Paths + runs-on: ubuntu-latest + if: github.repository == 'FlowiseAI/Flowise' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check for proprietary paths + id: check-paths + run: | + echo "🔍 Checking for proprietary paths..." + echo "Trigger: ${{ github.event_name }}" + echo "" + + # Get changed files based on event type + if [ "${{ github.event_name }}" = "pull_request" ]; then + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) + elif [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then + # Push to existing branch - compare with previous commit + CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }}) + else + # New branch - compare against default branch + CHANGED_FILES=$(git diff --name-only origin/${{ github.event.repository.default_branch }}...${{ github.sha }} 2>/dev/null || echo "") + fi + + echo "Files to check:" + echo "$CHANGED_FILES" | head -50 | sed 's/^/ /' + echo "" + + # Check for proprietary paths + VIOLATIONS="" + + while IFS= read -r file; do + [ -z "$file" ] && continue + + # Block all extensions/ + if echo "$file" | grep -qE "^extensions/"; then + VIOLATIONS="$VIOLATIONS$file\n" + continue + fi + + # Block all apps/ except apps/oss-app/ + if echo "$file" | grep -qE "^apps/"; then + if ! echo "$file" | grep -qE "^apps/oss-app/"; then + VIOLATIONS="$VIOLATIONS$file\n" + fi + fi + done <<< "$CHANGED_FILES" + + if [ -n "$VIOLATIONS" ]; then + echo "has_violations=true" >> $GITHUB_OUTPUT + echo "violations<> $GITHUB_OUTPUT + printf "%s" "$VIOLATIONS" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "❌ Files in proprietary paths detected!" + echo "" + printf "%s" "$VIOLATIONS" | sed 's/^/ ❌ /' + echo "" + echo "Proprietary paths:" + echo " - extensions/ (reserved for enterprise extensions)" + echo " - apps/* (only apps/oss-app/ is allowed)" + else + echo "has_violations=false" >> $GITHUB_OUTPUT + echo "✅ No proprietary paths detected" + fi + + - name: Fail if violations found + if: steps.check-paths.outputs.has_violations == 'true' + run: | + echo "::error::Files detected in proprietary paths. These paths are reserved for enterprise extensions." + exit 1 diff --git a/.gitignore b/.gitignore index 2f17096b6..391bcb685 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,12 @@ ## S/MIME message *.smime *.vsix + +# ============================================================================= +# Proprietary paths (should never exist in OSS) +# ============================================================================= +extensions/ + +# Only allow apps/oss-app, ignore all other apps +apps/*/ +!apps/oss-app/ diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 000000000..30b7f70e8 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,79 @@ +#!/bin/bash +[ -f "$(dirname "$0")/_/husky.sh" ] && . "$(dirname "$0")/_/husky.sh" + +# ============================================================================= +# OSS Guardrail: Prevent pushing proprietary code to OSS repository +# ============================================================================= + +# Paths that should NEVER go to OSS (explicitly blocked) +BLOCKED_PATHS="^extensions/" + +# Allowed apps (whitelist) - everything else in apps/ is blocked +ALLOWED_APPS="^apps/oss-app/" + +# Get the remote being pushed to +remote="$1" +url="$2" + +# Check if pushing to OSS remote (FlowiseAI/Flowise) +if echo "$url" | grep -qE "FlowiseAI/Flowise(\.git)?$"; then + echo "🔒 Pushing to OSS repo - checking for proprietary code..." + + # Read stdin for refs being pushed + while read local_ref local_sha remote_ref remote_sha; do + # Skip delete operations + if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then + continue + fi + + # Get list of files to check based on whether this is a new or existing branch + if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then + # New branch - check ALL files across ALL commits being pushed + # Find merge base with remote's main/master to determine the branch point + base=$(git merge-base "$local_sha" "$remote/main" 2>/dev/null || \ + git merge-base "$local_sha" "$remote/master" 2>/dev/null || \ + echo "") + if [ -n "$base" ]; then + # Found common ancestor - diff from there to get all new files + files_to_check=$(git diff --name-only "$base..$local_sha") + else + # No common ancestor - check all files in all commits on this branch + files_to_check=$(git log --name-only --pretty=format: "$local_sha" | sort -u) + fi + else + # Existing branch - check only files changed in new commits + files_to_check=$(git diff --name-only "$remote_sha..$local_sha") + fi + + # Check for proprietary paths + # Note: || true prevents grep's exit code 1 (no match) from aborting the subshell + violations=$( + { + echo "$files_to_check" | grep -E "$BLOCKED_PATHS" || true + echo "$files_to_check" | grep -E "^apps/" | grep -vE "$ALLOWED_APPS" || true + } 2>/dev/null | sort -u + ) + + if [ -n "$violations" ]; then + echo "" + echo "❌ BLOCKED: Push contains changes to proprietary paths!" + echo "" + echo "The following files cannot be pushed to OSS:" + echo "$violations" | sed 's/^/ - /' + echo "" + echo "Proprietary paths that are blocked:" + echo " - extensions/ (all extensions)" + echo " - apps/* (except apps/oss-app/)" + echo "" + echo "Only apps/oss-app/ is allowed in the OSS repository." + echo "" + echo "These paths are reserved for proprietary extensions." + echo "" + exit 1 + fi + done + + echo "✅ No proprietary code detected - push allowed" +fi + +exit 0