Distribution and Deployment

Distribution and Deployment

The following files were used as context for generating this wiki page:

Purpose and Scope

This document describes how WSHawk is packaged, distributed, and deployed across different environments. It covers the automated CI/CD pipeline, distribution channels (PyPI and container registries), Docker image architecture, and deployment patterns for local development, CI/CD integration, and production Kubernetes environments.

For information about configuring WSHawk after deployment, see Configuration System. For details about the Web Management Dashboard deployment, see Dashboard Overview and Launch.


Distribution Architecture Overview

WSHawk employs a multi-channel distribution strategy with automated CI/CD pipelines that build and publish artifacts to three primary distribution channels.

graph TB
    subgraph SourceControl["Source Control"]
        GitHubRepo["GitHub Repository<br/>regaan/wshawk"]
    end
    
    subgraph CI["CI/CD Pipeline"]
        GHActions["GitHub Actions<br/>docker-build.yml<br/>ghcr-publish.yml"]
        BuildTriggers["Triggers:<br/>push to main<br/>tags v*<br/>pull_request"]
        QEMUSetup["QEMU Emulation<br/>docker/setup-qemu-action@v3"]
        BuildxSetup["Docker Buildx<br/>docker/setup-buildx-action@v3"]
        MetadataExtract["Metadata Extraction<br/>docker/metadata-action@v5"]
        MultiArchBuild["Multi-Arch Build<br/>linux/amd64<br/>linux/arm64"]
    end
    
    subgraph Registries["Distribution Channels"]
        PyPI["PyPI<br/>pip install wshawk<br/>Python Package Index"]
        DockerHub["Docker Hub<br/>rothackers/wshawk<br/>Public Registry"]
        GHCR["GitHub Container Registry<br/>ghcr.io/regaan/wshawk<br/>GITHUB_TOKEN Auth"]
    end
    
    subgraph TagStrategy["Tag Strategy"]
        LatestTag["latest<br/>is_default_branch"]
        SemverFull["3.0.0<br/>{{version}}"]
        SemverMinor["3.0<br/>{{major}}.{{minor}}"]
        SemverMajor["3<br/>{{major}}"]
        BranchTag["main<br/>ref/branch"]
    end
    
    subgraph Deployment["Deployment Targets"]
        LocalDev["Local Development<br/>docker-compose.yml<br/>pip install -e ."]
        CICDIntegration["CI/CD Integration<br/>GitHub Actions Jobs<br/>GitLab CI Pipelines"]
        K8sJobs["Kubernetes<br/>Jobs/CronJobs<br/>Scheduled Scanning"]
        ProdDocker["Production Docker<br/>Volume Mounts<br/>Environment Variables"]
    end
    
    GitHubRepo --> BuildTriggers
    BuildTriggers --> GHActions
    GHActions --> QEMUSetup
    GHActions --> BuildxSetup
    GHActions --> MetadataExtract
    
    QEMUSetup --> MultiArchBuild
    BuildxSetup --> MultiArchBuild
    MetadataExtract --> MultiArchBuild
    
    MultiArchBuild --> PyPI
    MultiArchBuild --> DockerHub
    MultiArchBuild --> GHCR
    
    MetadataExtract --> LatestTag
    MetadataExtract --> SemverFull
    MetadataExtract --> SemverMinor
    MetadataExtract --> SemverMajor
    MetadataExtract --> BranchTag
    
    LatestTag --> DockerHub
    LatestTag --> GHCR
    SemverFull --> DockerHub
    SemverFull --> GHCR
    SemverMinor --> DockerHub
    SemverMinor --> GHCR
    
    PyPI --> LocalDev
    DockerHub --> LocalDev
    DockerHub --> CICDIntegration
    DockerHub --> K8sJobs
    DockerHub --> ProdDocker
    GHCR --> CICDIntegration
    GHCR --> K8sJobs

Sources: .github/workflows/docker-build.yml:1-89, README.md:53-81


Package Distribution Channels

WSHawk is distributed through three official channels, each serving different deployment scenarios.

Distribution Channel Matrix

| Channel | URL | Authentication | Use Case | Installation Command | |---------|-----|----------------|----------|---------------------| | PyPI | pypi.org/project/wshawk | Public | Python environments, pip-based workflows | pip install wshawk | | Docker Hub | rothackers/wshawk | Public | Production containers, quick deployment | docker pull rothackers/wshawk | | GitHub Container Registry | ghcr.io/regaan/wshawk | GITHUB_TOKEN | CI/CD integration, private workflows | docker pull ghcr.io/regaan/wshawk |

PyPI Distribution

WSHawk is published to the Python Package Index for installation via pip. This is the recommended method for development environments and when integrating WSHawk into Python-based security toolchains.

# Standard installation
pip install wshawk

# With optional Playwright support for XSS verification
pip install wshawk
playwright install chromium

The PyPI distribution includes all Python packages, entry points defined in pyproject.toml, and payload files specified in MANIFEST.in. Package metadata such as version, dependencies, and entry points are defined in setup.py and pyproject.toml.

Docker Hub Distribution

The primary public container registry is Docker Hub under the rothackers/wshawk repository. Images are automatically pushed on every commit to main and on version tags matching v* pattern.

# Pull latest version
docker pull rothackers/wshawk:latest

# Pull specific version
docker pull rothackers/wshawk:3.0.0

Environment variable DOCKERHUB_REPO is set to rothackers/wshawk .github/workflows/docker-build.yml:15.

GitHub Container Registry Distribution

GHCR provides GitHub-integrated distribution, useful for CI/CD workflows that already use GitHub Actions. Authentication uses GITHUB_TOKEN, eliminating the need for separate credentials.

# Login to GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u ${{ github.actor }} --password-stdin

# Pull image
docker pull ghcr.io/regaan/wshawk:latest

The registry URL is defined as ghcr.io/${{ github.repository }} .github/workflows/docker-build.yml:16.

Sources: README.md:53-81, .github/workflows/docker-build.yml:15-16


CI/CD Pipeline Architecture

WSHawk's distribution is fully automated via GitHub Actions workflows. The pipeline builds multi-architecture Docker images and publishes them to both Docker Hub and GHCR.

graph TB
    subgraph Triggers["Pipeline Triggers"]
        PushMain["push to main branch"]
        PushTag["push tags v*"]
        PullRequest["pull_request to main"]
        ManualDispatch["workflow_dispatch"]
    end
    
    subgraph Setup["Build Environment Setup"]
        CheckoutRepo["actions/checkout@v4<br/>Clone Repository"]
        SetupQEMU["docker/setup-qemu-action@v3<br/>Enable ARM64 Emulation"]
        SetupBuildx["docker/setup-buildx-action@v3<br/>Multi-Platform Builder"]
    end
    
    subgraph Authentication["Registry Authentication"]
        VerifySecrets["Verify DOCKER_USERNAME<br/>Verify DOCKER_PASSWORD<br/>Skip on pull_request"]
        LoginDockerHub["docker/login-action@v3<br/>username: DOCKER_USERNAME<br/>password: DOCKER_PASSWORD"]
        LoginGHCR["docker/login-action@v3<br/>registry: ghcr.io<br/>username: github.actor<br/>password: GITHUB_TOKEN"]
    end
    
    subgraph MetadataGen["Metadata Generation"]
        ExtractMeta["docker/metadata-action@v5"]
        TagRules["Tag Rules:<br/>type=ref,event=branch<br/>type=ref,event=pr<br/>type=semver,pattern={{version}}<br/>type=semver,pattern={{major}}.{{minor}}<br/>type=semver,pattern={{major}}<br/>type=raw,value=latest"]
        ImageTargets["Image Targets:<br/>rothackers/wshawk<br/>ghcr.io/regaan/wshawk"]
    end
    
    subgraph BuildPush["Build and Push"]
        BuildAction["docker/build-push-action@v5"]
        BuildContext["context: .<br/>Dockerfile"]
        Platforms["platforms:<br/>linux/amd64<br/>linux/arm64"]
        CacheStrategy["cache-from: type=gha<br/>cache-to: type=gha,mode=max"]
        PushCondition["push: github.event_name != 'pull_request'"]
    end
    
    subgraph Testing["Image Testing"]
        PullTest["docker pull ghcr.io/...wshawk:latest"]
        HelpTest["docker run --rm ... --help"]
        DefensiveTest["docker run --rm<br/>--entrypoint wshawk-defensive<br/>... --help"]
    end
    
    PushMain --> CheckoutRepo
    PushTag --> CheckoutRepo
    PullRequest --> CheckoutRepo
    ManualDispatch --> CheckoutRepo
    
    CheckoutRepo --> SetupQEMU
    SetupQEMU --> SetupBuildx
    SetupBuildx --> VerifySecrets
    
    VerifySecrets --> LoginDockerHub
    VerifySecrets --> LoginGHCR
    
    LoginDockerHub --> ExtractMeta
    LoginGHCR --> ExtractMeta
    
    ExtractMeta --> TagRules
    ExtractMeta --> ImageTargets
    TagRules --> BuildAction
    ImageTargets --> BuildAction
    
    BuildAction --> BuildContext
    BuildAction --> Platforms
    BuildAction --> CacheStrategy
    BuildAction --> PushCondition
    
    PushCondition --> PullTest
    PullTest --> HelpTest
    HelpTest --> DefensiveTest

Build Trigger Configuration

The pipeline is triggered by four event types defined in .github/workflows/docker-build.yml:3-12:

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]
  workflow_dispatch:
  • push to main: Builds and pushes latest tag
  • push tags v*: Builds and pushes semantic version tags (e.g., v3.0.03.0.0, 3.0, 3, latest)
  • pull_request: Builds only (no push) for validation
  • workflow_dispatch: Manual trigger for ad-hoc builds

Multi-Architecture Build Support

WSHawk supports both linux/amd64 and linux/arm64 architectures via QEMU emulation. This is configured in .github/workflows/docker-build.yml:29-33:

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

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

The build action specifies both platforms .github/workflows/docker-build.yml:80:

platforms: linux/amd64,linux/arm64

This ensures WSHawk can run on x86_64 servers, ARM-based cloud instances (AWS Graviton), and Apple Silicon Macs.

Semantic Versioning Tag Strategy

The metadata extraction step generates multiple tags from a single version release using .github/workflows/docker-build.yml:56-69:

- name: Extract metadata
  id: meta
  uses: docker/metadata-action@v5
  with:
    images: |
      ${{ env.DOCKERHUB_REPO }}
      ${{ env.GHCR_REPO }}
    tags: |
      type=ref,event=branch
      type=ref,event=pr
      type=semver,pattern={{version}}
      type=semver,pattern={{major}}.{{minor}}
      type=semver,pattern={{major}}
      type=raw,value=latest,enable={{is_default_branch}}

Tag generation example for v3.0.0:

| Input Tag | Generated Tags | Description | |-----------|---------------|-------------| | v3.0.0 | 3.0.0 | Full semantic version | | v3.0.0 | 3.0 | Major.minor (allows patch updates) | | v3.0.0 | 3 | Major version only | | v3.0.0 | latest | Always points to most recent release |

Secret Management

Docker Hub authentication requires two secrets to be configured in the GitHub repository:

  • DOCKER_USERNAME: Docker Hub username
  • DOCKER_PASSWORD: Docker Hub access token or password

Secret verification occurs in .github/workflows/docker-build.yml:35-39:

- name: Verify Secrets Presence
  if: github.event_name != 'pull_request'
  run: |
    if [ -z "${{ secrets.DOCKER_USERNAME }}" ]; then 
      echo "::error::DOCKER_USERNAME secret is MISSING"; exit 1
    fi

GHCR authentication uses the automatic GITHUB_TOKEN provided by GitHub Actions .github/workflows/docker-build.yml:48-54.

Build Caching Strategy

The pipeline uses GitHub Actions cache to accelerate builds .github/workflows/docker-build.yml:78-79:

cache-from: type=gha
cache-to: type=gha,mode=max

This caches Docker layers between builds, significantly reducing build time for incremental changes.

Automated Testing

After successful push, the pipeline validates the image .github/workflows/docker-build.yml:82-88:

- name: Test Docker image
  if: github.event_name != 'pull_request'
  run: |
    docker pull ${{ env.GHCR_REPO }}:latest
    docker run --rm ${{ env.GHCR_REPO }}:latest --help
    docker run --rm --entrypoint wshawk-defensive ${{ env.GHCR_REPO }}:latest --help

This verifies:

  1. Image is pullable from GHCR
  2. Default entrypoint (wshawk) executes successfully
  3. Alternative entrypoint (wshawk-defensive) is accessible

Sources: .github/workflows/docker-build.yml:1-89, .github/workflows/ghcr-publish.yml:1-50


Docker Image Build Configuration

Dockerfile Multi-Stage Build

The WSHawk Docker image is built using a multi-stage Dockerfile pattern (referenced but not shown in provided files). The build process installs system dependencies, Python packages, and Playwright browsers.

Build Context Exclusions

Files excluded from the Docker build context are defined in .dockerignore:1-72. Key exclusions include:

| Category | Patterns | Rationale | |----------|----------|-----------| | Python Artifacts | __pycache__/, *.pyc, dist/, build/ | Build-time generated files | | Virtual Environments | venv/, env/, wshawk_venv/ | Environment-specific dependencies | | Test Artifacts | .pytest_cache/, .coverage, .hypothesis/ | Testing infrastructure not needed in production | | Reports | reports/, *.html, *.log | Runtime-generated output | | Documentation | docs/, *.md (except README.md) | Not needed in container runtime | | CI/CD | .github/, .gitlab-ci.yml | Build configuration only |

This reduces the Docker build context size and prevents sensitive local files from being included in the image.

Sources: .dockerignore:1-72


Docker Compose for Local Development

The project includes a docker-compose.yml configuration for local development and testing scenarios.

graph LR
    subgraph ComposeServices["docker-compose.yml Services"]
        WSHawkService["wshawk service<br/>build: .<br/>network_mode: host"]
        VulnServer["vulnerable-server service<br/>python:3.11-slim<br/>port 8765"]
    end
    
    subgraph Volumes["Volume Mounts"]
        ReportsVol["./reports:/app/reports<br/>Persist scan reports"]
        ExamplesVol["./examples:/app<br/>Test server content"]
    end
    
    subgraph Network["Networking"]
        HostNetwork["host network<br/>Direct WebSocket access"]
        BridgeNetwork["wshawk-network<br/>bridge driver"]
    end
    
    subgraph Entrypoint["Interactive Usage"]
        BashShell["entrypoint: /bin/bash<br/>stdin_open: true<br/>tty: true"]
    end
    
    WSHawkService --> ReportsVol
    WSHawkService --> HostNetwork
    WSHawkService --> BashShell
    
    VulnServer --> ExamplesVol
    VulnServer --> BridgeNetwork

Service Configuration

The wshawk service is configured for interactive development docker-compose.yml:4-18:

wshawk:
  build: .
  container_name: wshawk
  network_mode: host
  volumes:
    - ./reports:/app/reports
  entrypoint: /bin/bash
  stdin_open: true
  tty: true

Key features:

  • network_mode: host: Provides direct access to localhost WebSocket servers without Docker networking overhead
  • entrypoint: /bin/bash: Drops into interactive shell for manual testing
  • stdin_open: true + tty: true: Enables interactive terminal

Vulnerable Test Server

A companion service provides a basic test server docker-compose.yml:20-31:

vulnerable-server:
  image: python:3.11-slim
  ports:
    - "8765:8765"
  volumes:
    - ./examples:/app
  command: python3 -m http.server 8765

This allows testing WSHawk against a local target without external dependencies.

Usage Pattern

# Start services
docker-compose up -d

# Enter WSHawk container
docker-compose exec wshawk bash

# Inside container, run scans
wshawk ws://localhost:8765
wshawk-defensive wss://production-server.com

# View reports on host
ls -lh reports/

# Cleanup
docker-compose down

Sources: docker-compose.yml:1-36


Docker Deployment Patterns

Basic Docker Run Commands

# Quick scan with default settings
docker run --rm rothackers/wshawk ws://target.com

# Advanced scan with all features
docker run --rm rothackers/wshawk wshawk-advanced \
  ws://target.com \
  --smart-payloads \
  --playwright \
  --full

# Defensive validation
docker run --rm rothackers/wshawk wshawk-defensive wss://your-server.com

Volume Mounts for Report Persistence

Scan reports and traffic logs are generated inside the container at /app/reports. To persist these to the host:

docker run --rm \
  -v $(pwd)/reports:/app/reports \
  rothackers/wshawk ws://target.com

This mounts the host's ./reports directory to /app/reports inside the container, making all generated files accessible after the container exits.

Environment Variable Configuration

WSHawk supports configuration via environment variables. Common examples:

# Web dashboard with authentication
docker run -d \
  -p 5000:5000 \
  -e WSHAWK_WEB_PASSWORD='secure-password' \
  -e WSHAWK_API_KEY='api-key-for-automation' \
  rothackers/wshawk --web --host 0.0.0.0 --port 5000

# Integration credentials
docker run --rm \
  -e JIRA_API_TOKEN='token-value' \
  -e DEFECTDOJO_API_KEY='dd-key' \
  -v $(pwd)/wshawk.yaml:/app/wshawk.yaml \
  rothackers/wshawk ws://target.com

See Configuration System for complete environment variable reference.

Security Considerations

For production deployments, apply container security best practices:

# Run as non-root user (if supported by image)
docker run --rm \
  --user 1000:1000 \
  --read-only \
  --tmpfs /tmp \
  -v $(pwd)/reports:/app/reports:rw \
  rothackers/wshawk ws://target.com

# Resource limits
docker run --rm \
  --memory="512m" \
  --cpus="1.0" \
  rothackers/wshawk ws://target.com

Sources: README.md:64-81


CI/CD Integration Scenarios

GitHub Actions Integration

WSHawk can be integrated into GitHub Actions workflows for automated security scanning on every pull request or scheduled scans.

name: WebSocket Security Scan
on:
  pull_request:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM

jobs:
  wshawk-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Run WSHawk Scan
        run: |
          docker pull ghcr.io/regaan/wshawk:latest
          docker run --rm \
            -v ${{ github.workspace }}/reports:/app/reports \
            ghcr.io/regaan/wshawk:latest \
            wshawk-advanced ws://staging.example.com --full
      
      - name: Upload SARIF to GitHub Security
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: reports/wshawk.sarif

This workflow:

  1. Pulls the latest GHCR image (authentication via GITHUB_TOKEN)
  2. Runs a full scan against the staging environment
  3. Uploads SARIF results to GitHub Security tab

GitLab CI Integration

websocket_security_scan:
  stage: security
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker pull rothackers/wshawk:latest
    - docker run --rm 
        -v $(pwd)/reports:/app/reports 
        rothackers/wshawk 
        wshawk ws://${STAGING_WS_URL}
  artifacts:
    paths:
      - reports/
    reports:
      junit: reports/wshawk-junit.xml
  only:
    - merge_requests
    - schedules

SARIF Export for Security Dashboards

WSHawk can export findings in SARIF (Static Analysis Results Interchange Format) for integration with security dashboards. See Report Formats and Export for SARIF generation details.

Sources: README.md:64-81, .github/workflows/docker-build.yml:1-89


Kubernetes Deployment

One-Time Security Scan Job

For ad-hoc security assessments:

apiVersion: batch/v1
kind: Job
metadata:
  name: wshawk-scan-prod
  namespace: security
spec:
  template:
    spec:
      containers:
      - name: wshawk
        image: rothackers/wshawk:3.0.0
        command: ["wshawk-advanced"]
        args:
          - "wss://production-api.example.com/ws"
          - "--full"
          - "--smart-payloads"
        env:
        - name: JIRA_API_TOKEN
          valueFrom:
            secretKeyRef:
              name: wshawk-secrets
              key: jira-token
        volumeMounts:
        - name: reports
          mountPath: /app/reports
        - name: config
          mountPath: /app/wshawk.yaml
          subPath: wshawk.yaml
      volumes:
      - name: reports
        persistentVolumeClaim:
          claimName: wshawk-reports-pvc
      - name: config
        configMap:
          name: wshawk-config
      restartPolicy: Never

Scheduled CronJob for Regular Scans

For recurring security assessments:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: wshawk-weekly-scan
  namespace: security
spec:
  schedule: "0 3 * * 0"  # Every Sunday at 3 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: wshawk
            image: ghcr.io/regaan/wshawk:latest
            command: ["wshawk-advanced"]
            args:
              - "wss://api.example.com/ws"
              - "--playwright"
              - "--rate=5"
            env:
            - name: DEFECTDOJO_API_KEY
              valueFrom:
                secretKeyRef:
                  name: defectdojo-creds
                  key: api-key
            - name: WSHAWK_WEB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: wshawk-web-creds
                  key: password
            volumeMounts:
            - name: reports
              mountPath: /app/reports
          volumes:
          - name: reports
            persistentVolumeClaim:
              claimName: wshawk-reports-pvc
          restartPolicy: OnFailure

Multi-Service Scanning Deployment

For organizations with multiple WebSocket services:

apiVersion: batch/v1
kind: Job
metadata:
  name: wshawk-multi-service-scan
spec:
  parallelism: 3
  completions: 3
  template:
    spec:
      containers:
      - name: wshawk
        image: rothackers/wshawk:latest
        command: ["bash", "-c"]
        args:
          - |
            TARGETS=(
              "wss://service1.example.com/ws"
              "wss://service2.example.com/ws"
              "wss://service3.example.com/ws"
            )
            wshawk-advanced ${TARGETS[$JOB_COMPLETION_INDEX]} --full
        env:
        - name: JOB_COMPLETION_INDEX
          valueFrom:
            fieldRef:
              fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']
      restartPolicy: Never

Centralized DefectDojo Integration

For pushing findings to a centralized DefectDojo instance:

apiVersion: v1
kind: ConfigMap
metadata:
  name: wshawk-config
data:
  wshawk.yaml: |
    integrations:
      defectdojo:
        url: "https://defectdojo.security.internal"
        api_key: "env:DEFECTDOJO_API_KEY"
        engagement_id: 42
        auto_create_findings: true
        minimum_severity: "MEDIUM"
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: wshawk-to-defectdojo
spec:
  schedule: "0 */6 * * *"  # Every 6 hours
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: wshawk
            image: rothackers/wshawk:3.0
            args:
              - "wss://api.prod.example.com/ws"
              - "--full"
            volumeMounts:
            - name: config
              mountPath: /app/wshawk.yaml
              subPath: wshawk.yaml
          volumes:
          - name: config
            configMap:
              name: wshawk-config
          restartPolicy: OnFailure

Sources: README.md:23-37


Build Metadata and Packaging

Entry Points Definition

WSHawk defines four CLI entry points in pyproject.toml:

[project.scripts]
wshawk = "wshawk.__main__:main"
wshawk-interactive = "wshawk.interactive:main"
wshawk-advanced = "wshawk.scanner_v2:cli_main"
wshawk-defensive = "wshawk.defensive_validation:main"

These entry points are automatically registered during pip install and are available as commands in the container's PATH.

Package Metadata

Version information, dependencies, and project metadata are centralized in setup.py and pyproject.toml. The package includes:

  • Core dependencies: websockets, aiohttp, requests, pyyaml, colorama
  • Optional dependencies: playwright (for XSS verification)
  • Payload files: Included via MANIFEST.in specifications
  • Entry scripts: CLI commands for different operational modes

Image Entrypoint

The default Docker entrypoint is set to wshawk, allowing users to run:

docker run rothackers/wshawk ws://target.com

Alternative entrypoints can be specified:

docker run --rm --entrypoint wshawk-defensive rothackers/wshawk ws://target.com
docker run --rm --entrypoint wshawk-interactive rothackers/wshawk

Sources: README.md:84-110, .github/workflows/docker-build.yml:87


Distribution Security and Verification

Official Distribution Channels

As stated in README.md:3-14, only the following sources are official:

  1. GitHub Repository: https://github.com/regaan/wshawk
  2. PyPI: pip install wshawk
  3. Docker Hub: docker pull rothackers/wshawk
  4. GHCR: docker pull ghcr.io/regaan/wshawk

Verification Methods

To verify Docker image authenticity:

# Verify image digest
docker pull rothackers/wshawk:3.0.0
docker inspect rothackers/wshawk:3.0.0 | grep -A5 RepoDigests

# Verify GHCR image matches source repository
docker pull ghcr.io/regaan/wshawk:3.0.0
docker history ghcr.io/regaan/wshawk:3.0.0

To verify PyPI package integrity:

# Check package hash
pip download wshawk --no-deps
sha256sum wshawk-*.whl

# Verify package metadata
pip show wshawk

Registry Access Patterns

| Registry | Pull Authentication | Push Authentication | Rate Limits | |----------|-------------------|-------------------|-------------| | Docker Hub | Not required (public) | DOCKER_USERNAME + DOCKER_PASSWORD | 100 pulls/6hr (anonymous), 200 pulls/6hr (authenticated) | | GHCR | Not required (public repos) | GITHUB_TOKEN with packages:write | 5000 requests/hour | | PyPI | Not required | PyPI API token | 10 requests/second (downloads unlimited) |

Sources: README.md:3-14, .github/workflows/docker-build.yml:41-54