استخدام البيانات السرية في سير العمل

مكتمل

لا يتم تمرير الأسرار تلقائيا إلى المشغلات عند تنفيذ مهام سير العمل. لتوفير سر لإجراء ما، يجب تعيين السر كمتغير إدخال أو بيئة في ملف سير العمل. لتحقيق ذلك، يمكنك استخدام سياق الأسرار كما هو موضح في المثال التالي:

يتطلب استخدام الأسرار بشكل فعال في مهام سير عمل GitHub Actions فهم كيفية الوصول إليها بأمان وتطبيقها بشكل مناسب والعمل ضمن حدودها. يغطي هذا القسم الأنماط والتقنيات العملية لدمج الأسرار في مهام سير عمل CI/CD.

الوصول إلى الأسرار في مهام سير العمل

لا تتوفر الأسرار تلقائيا لخطوات سير العمل. يجب عليك عرضها بشكل صريح من خلال المدخلات أو متغيرات البيئة باستخدام secrets السياق.

أنماط الاستخدام السرية الأساسية

name: Database Operations

on: [push]

jobs:
  database-operations:
    runs-on: ubuntu-latest
    steps:
      # Method 1: Using secrets as environment variables
      - name: Connect to database
        env:
          DB_USERNAME: ${{ secrets.DB_USERNAME }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
          DB_HOST: ${{ secrets.DB_HOST }}
        run: |
          # Use environment variables safely
          psql -h "$DB_HOST" -U "$DB_USERNAME" -d myapp <<EOF
          SELECT version();
          EOF

      # Method 2: Passing secrets to actions as inputs
      - name: Deploy application
        uses: my-org/deploy-action@v2
        with:
          api-key: ${{ secrets.DEPLOYMENT_API_KEY }}
          environment: production

      # Method 3: Using secrets in composite actions
      - name: Security scan
        uses: security-org/scan-action@v1
        with:
          token: ${{ secrets.SECURITY_SCAN_TOKEN }}
          severity-threshold: "high"

الاستخدام السري عبر القشرة

jobs:
  multi-shell-example:
    runs-on: ubuntu-latest
    steps:
      # Bash shell
      - name: Bash operations
        shell: bash
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          curl -H "Authorization: Bearer $API_TOKEN" \
               https://api.example.com/deploy

      # PowerShell
      - name: PowerShell operations
        shell: pwsh
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          $headers = @{ Authorization = "Bearer $env:API_TOKEN" }
          Invoke-RestMethod -Uri "https://api.example.com/status" -Headers $headers

      # Python script
      - name: Python operations
        shell: python
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          import os
          import requests

          token = os.environ['API_TOKEN']
          headers = {'Authorization': f'Bearer {token}'}
          response = requests.get('https://api.example.com/data', headers=headers)
          print(f"Status: {response.status_code}")

أنماط الاستخدام السري المتقدمة

الاستخدام السري المشروط

name: Environment-Aware Deployment

on:
  push:
    branches: [main, develop, "feature/*"]

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      # Set secrets as job-level environment variables for conditional access
      PROD_API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
      STAGING_API_KEY: ${{ secrets.STAGING_API_KEY }}
      DEV_API_KEY: ${{ secrets.DEVELOPMENT_API_KEY }}
    steps:
      - name: Determine target environment
        id: env
        run: |
          if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
            echo "target=production" >> $GITHUB_OUTPUT
            echo "api_key_var=PROD_API_KEY" >> $GITHUB_OUTPUT
          elif [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
            echo "target=staging" >> $GITHUB_OUTPUT
            echo "api_key_var=STAGING_API_KEY" >> $GITHUB_OUTPUT
          else
            echo "target=development" >> $GITHUB_OUTPUT
            echo "api_key_var=DEV_API_KEY" >> $GITHUB_OUTPUT
          fi

      - name: Deploy to environment
        run: |
          # Use indirect variable reference
          API_KEY_VAR="${{ steps.env.outputs.api_key_var }}"
          API_KEY="${!API_KEY_VAR}"

          echo "Deploying to ${{ steps.env.outputs.target }} environment"
          ./deploy.sh --environment=${{ steps.env.outputs.target }} --api-key="$API_KEY"

التحقق السري والفحوصات الصحية

name: Secret Health Validation

jobs:
  validate-secrets:
    runs-on: ubuntu-latest
    steps:
      - name: Validate required secrets
        env:
          REQUIRED_SECRETS: |
            API_KEY=${{ secrets.API_KEY }}
            DATABASE_URL=${{ secrets.DATABASE_URL }}
            REDIS_URL=${{ secrets.REDIS_URL }}
        run: |
          echo "$REQUIRED_SECRETS" | while IFS='=' read -r name value; do
            if [ -z "$value" ]; then
              echo "ERROR: Missing required secret: $name"
              exit 1
            else
              echo "OK: Secret $name is present"
            fi
          done

      - name: Test secret functionality
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
        run: |
          # Test API key
          if curl -f -H "Authorization: Bearer $API_KEY" https://api.example.com/health; then
            echo "API key is valid"
          else
            echo "ERROR: API key validation failed"
            exit 1
          fi

          # Test database connection
          if pg_isready -d "$DATABASE_URL"; then
            echo "Database connection is healthy"
          else
            echo "ERROR: Database connection failed"
            exit 1
          fi

التكوين السري والتحول

name: Complex Secret Handling

jobs:
  process-secrets:
    runs-on: ubuntu-latest
    steps:
      - name: Compose configuration from secrets
        env:
          # Individual secret components
          DB_HOST: ${{ secrets.DB_HOST }}
          DB_PORT: ${{ secrets.DB_PORT }}
          DB_USER: ${{ secrets.DB_USER }}
          DB_PASS: ${{ secrets.DB_PASSWORD }}
          DB_NAME: ${{ secrets.DB_NAME }}

          # SSL certificate components
          SSL_CERT: ${{ secrets.SSL_CERTIFICATE }}
          SSL_KEY: ${{ secrets.SSL_PRIVATE_KEY }}
          SSL_CA: ${{ secrets.SSL_CA_CERTIFICATE }}
        run: |
          # Create connection string
          CONNECTION_STRING="postgresql://$DB_USER:$DB_PASS@$DB_HOST:$DB_PORT/$DB_NAME?sslmode=require"

          # Write SSL files securely
          echo "$SSL_CERT" > /tmp/client-cert.pem
          echo "$SSL_KEY" > /tmp/client-key.pem
          echo "$SSL_CA" > /tmp/ca-cert.pem

          # Set proper permissions
          chmod 600 /tmp/client-key.pem
          chmod 644 /tmp/client-cert.pem /tmp/ca-cert.pem

          # Use composed configuration
          psql "$CONNECTION_STRING" \
            --set=sslcert=/tmp/client-cert.pem \
            --set=sslkey=/tmp/client-key.pem \
            --set=sslrootcert=/tmp/ca-cert.pem \
            -c "SELECT version();"

          # Clean up sensitive files
          rm -f /tmp/client-*.pem /tmp/ca-cert.pem

العمل مع المنطق الشرطي

استخدام الأسرار في العبارات الشرطية

نظرا لأنه لا يمكن الرجوع إلى الأسرار بشكل مباشر في if الظروف ، استخدم متغيرات البيئة كوسطاء:

name: Conditional Secret Usage

jobs:
  conditional-deployment:
    runs-on: ubuntu-latest
    env:
      # Make secrets available as environment variables
      DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
      FEATURE_FLAG_API_KEY: ${{ secrets.FEATURE_FLAG_API_KEY }}
      MONITORING_TOKEN: ${{ secrets.MONITORING_TOKEN }}
    steps:
      - name: Deploy if deployment key exists
        if: ${{ env.DEPLOY_KEY != '' }}
        run: |
          echo "Deploying with available deployment key"
          ./deploy.sh --key="$DEPLOY_KEY"

      - name: Enable feature flags if configured
        if: ${{ env.FEATURE_FLAG_API_KEY != '' }}
        run: |
          echo "Configuring feature flags"
          feature-flags configure --api-key="$FEATURE_FLAG_API_KEY"

      - name: Setup monitoring if token available
        if: ${{ env.MONITORING_TOKEN != '' }}
        run: |
          echo "Setting up monitoring"
          monitoring setup --token="$MONITORING_TOKEN"

      - name: Fallback for missing secrets
        if: ${{ env.DEPLOY_KEY == '' }}
        run: |
          echo "WARNING: No deployment key available, running in dry-run mode"
          ./deploy.sh --dry-run

معالجة الحالات المتعددة

name: Multi-Condition Secret Logic

jobs:
  smart-deployment:
    runs-on: ubuntu-latest
    env:
      PROD_KEY: ${{ secrets.PRODUCTION_KEY }}
      STAGING_KEY: ${{ secrets.STAGING_KEY }}
      CANARY_ENABLED: ${{ secrets.CANARY_DEPLOYMENT_ENABLED }}
    steps:
      - name: Production deployment
        if: ${{ github.ref == 'refs/heads/main' && env.PROD_KEY != '' }}
        run: |
          echo "Production deployment with canary: $CANARY_ENABLED"
          if [ "$CANARY_ENABLED" = "true" ]; then
            ./deploy.sh --environment=production --canary --key="$PROD_KEY"
          else
            ./deploy.sh --environment=production --key="$PROD_KEY"
          fi

      - name: Staging deployment
        if: ${{ github.ref == 'refs/heads/develop' && env.STAGING_KEY != '' }}
        run: |
          echo "🔧 Staging deployment"
          ./deploy.sh --environment=staging --key="$STAGING_KEY"

      - name: Missing configuration warning
        if: ${{ (github.ref == 'refs/heads/main' && env.PROD_KEY == '') || (github.ref == 'refs/heads/develop' && env.STAGING_KEY == '') }}
        run: |
          echo "WARNING: Missing deployment keys for target environment"
          echo "Branch: ${{ github.ref }}"
          echo "Production key available: ${{ env.PROD_KEY != '' }}"
          echo "Staging key available: ${{ env.STAGING_KEY != '' }}"

أفضل ممارسات الأمان في مهام سير العمل

تقليل نطاق التعرض السري

name: Scoped Secret Access

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        # No secrets needed for checkout

      - name: Build application
        run: |
          npm install
          npm run build
        # No secrets needed for build

      - name: Deploy application (secrets only here)
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: |
          # Secret only available in this specific step
          ./deploy.sh --token="$DEPLOY_TOKEN"

التعامل الآمن مع الأخطاء مع الأسرار

name: Safe Secret Error Handling

jobs:
  secure-operations:
    runs-on: ubuntu-latest
    steps:
      - name: Safe secret usage with error handling
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: |
          # Disable bash debugging to prevent secret exposure
          set +x

          # Capture command output without exposing secrets
          if output=$(api-call --key="$API_KEY" 2>&1); then
            echo "API call successful"
            echo "$output" | grep -v "$API_KEY"  # Filter out any secret remnants
          else
            exit_code=$?
            echo "ERROR: API call failed with exit code: $exit_code"
            # Don't log the actual error which might contain the secret
            echo "Check API key validity and network connectivity"
            exit $exit_code
          fi

كشف الدوران السري

name: Secret Rotation Detection

on:
  schedule:
    - cron: "0 8 * * *" # Daily at 8 AM

jobs:
  check-secret-rotation:
    runs-on: ubuntu-latest
    steps:
      - name: Check secret age and validity
        env:
          API_KEY: ${{ secrets.API_KEY }}
          WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
        run: |
          # Test current secret validity
          if curl -f -H "Authorization: Bearer $API_KEY" https://api.example.com/auth/validate; then
            echo "Current API key is valid"
          else
            echo "ERROR: API key validation failed - rotation may be needed"
            
            # Notify team via webhook
            curl -X POST "$WEBHOOK_URL" \
              -H "Content-Type: application/json" \
              -d '{"text": "🔐 API key rotation needed for repository: ${{ github.repository }}"}'
          fi

فهم القيود والحلول البديلة

قيود الحجم السرية

name: Large Secret Handling

jobs:
  handle-large-secrets:
    runs-on: ubuntu-latest
    steps:
      # For secrets under 48KB - direct usage
      - name: Use normal secret
        env:
          SMALL_CONFIG: ${{ secrets.APPLICATION_CONFIG }}
        run: |
          echo "$SMALL_CONFIG" > config.json

      # For larger secrets - use encrypted storage
      - name: Handle large secret
        env:
          # Store encryption passphrase as secret (under 48KB)
          DECRYPTION_KEY: ${{ secrets.LARGE_SECRET_DECRYPTION_KEY }}
        run: |
          # Download encrypted large secret from repository
          curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
               -o encrypted-config.enc \
               https://api.github.com/repos/${{ github.repository }}/contents/secrets/large-config.enc

          # Decrypt using the passphrase secret
          openssl enc -aes-256-cbc -d -in encrypted-config.enc -out large-config.json -pass pass:"$DECRYPTION_KEY"

          # Use the decrypted configuration
          cat large-config.json | jq '.database.connection_string'

          # Clean up
          rm -f encrypted-config.enc large-config.json

قيود مستودع الشوكة

name: Fork-Aware Secret Usage

on: [push, pull_request]

jobs:
  secure-ci:
    runs-on: ubuntu-latest
    steps:
      - name: Check if secrets are available
        env:
          # GITHUB_TOKEN is always available, others may not be in forks
          HAS_API_KEY: ${{ secrets.API_KEY != '' }}
        run: |
          echo "Running in fork: ${{ github.event.pull_request.head.repo.fork }}"
          echo "Secrets available: $HAS_API_KEY"

      - name: Full integration tests (only for main repo)
        if: ${{ !github.event.pull_request.head.repo.fork && secrets.API_KEY != '' }}
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: |
          echo "🔐 Running full integration tests with secrets"
          npm run test:integration

      - name: Limited tests (for forks)
        if: ${{ github.event.pull_request.head.repo.fork || secrets.API_KEY == '' }}
        run: |
          echo "🔓 Running limited tests without secrets"
          npm run test:unit

يساعدك فهم هذه الأنماط والقيود على بناء مهام سير عمل قوية تتعامل مع الأسرار بأمان مع الحفاظ على الوظائف عبر سياقات التنفيذ المختلفة وتكوينات المستودع.