$ shellfirm

CI/CD Pipelines

Use shellfirm as a safety gate in continuous integration and deployment pipelines

shellfirm can act as a safety gate in CI/CD pipelines, checking commands before they execute in production environments. Use shellfirm check to validate commands programmatically with clear exit codes.

Exit codes

Exit codeMeaning
0Command is safe (no patterns matched, or all matches below threshold)
1Command is risky (matches detected at or above threshold)

Basic usage

shellfirm check --command "kubectl delete namespace production" --test
echo $?  # 1 (risky)

shellfirm check --command "kubectl get pods" --test
echo $?  # 0 (safe)

The --test flag suppresses interactive prompts and returns only the exit code, which is what you want in CI environments.

For structured output, use --json:

shellfirm check --command "rm -rf /" --json

This returns a JSON risk assessment identical to what the MCP server produces.

GitHub Actions

Pre-deploy safety check

name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install shellfirm
        run: |
          curl -L https://github.com/kaplanelad/shellfirm/releases/latest/download/shellfirm-x86_64-unknown-linux-gnu.tar.gz | tar xz
          sudo mv shellfirm /usr/local/bin/

      - name: Validate deployment command
        run: |
          DEPLOY_CMD="kubectl apply -f k8s/production/"
          shellfirm check --command "$DEPLOY_CMD" --test
          if [ $? -ne 0 ]; then
            echo "::error::shellfirm blocked the deployment command"
            exit 1
          fi

      - name: Deploy
        run: kubectl apply -f k8s/production/

Check multiple commands

      - name: Safety check all deployment commands
        run: |
          set -e
          shellfirm check --command "helm upgrade --install app ./chart --set env=production" --test
          shellfirm check --command "kubectl rollout restart deployment/web -n production" --test

Block dangerous flags

      - name: Block dangerous git operations
        run: |
          # Fail the pipeline if any script uses --force or --no-verify
          for cmd in \
            "git push --force origin main" \
            "git push --no-verify" \
            "npm publish --force"
          do
            if ! shellfirm check --command "$cmd" --test; then
              echo "::error::Blocked dangerous command: $cmd"
              exit 1
            fi
          done

GitLab CI

deploy:
  stage: deploy
  before_script:
    - curl -L https://github.com/kaplanelad/shellfirm/releases/latest/download/shellfirm-x86_64-unknown-linux-gnu.tar.gz | tar xz
    - mv shellfirm /usr/local/bin/
  script:
    - shellfirm check --command "kubectl apply -f k8s/" --test
    - kubectl apply -f k8s/
  environment:
    name: production

Custom pipeline scripts

For any CI system, the pattern is the same:

#!/bin/bash
set -e

COMMAND="$1"

# Check with shellfirm
if ! shellfirm check --command "$COMMAND" --test; then
  echo "ERROR: shellfirm blocked command: $COMMAND"
  echo "Run 'shellfirm check --command \"$COMMAND\" --json' for details"
  exit 1
fi

# Command is safe, execute it
eval "$COMMAND"

Using JSON output for detailed reporting

In pipelines where you want detailed reporting, use --json:

RESULT=$(shellfirm check --command "$DEPLOY_CMD" --json)
ALLOWED=$(echo "$RESULT" | jq -r '.allowed')
SEVERITY=$(echo "$RESULT" | jq -r '.severity // "none"')

if [ "$ALLOWED" = "false" ]; then
  echo "Command blocked by shellfirm"
  echo "Severity: $SEVERITY"
  echo "$RESULT" | jq '.matched_rules[] | "\(.id): \(.description)"'
  exit 1
fi

Environment-specific configuration

CI environments often have different shellfirm configurations than developer machines. Set environment-specific settings:

# In CI, use stricter settings
export SHELLFIRM_CONFIG_PATH=/path/to/ci-settings.yaml

Or use project policies by including a .shellfirm.yaml in your repository root. The CI pipeline will automatically pick it up when running from the repository directory.