diff --git a/.github/workflows/compile-ai-docs-from-gcs.yaml b/.github/workflows/compile-ai-docs-from-gcs.yaml index 268bffee38..b4a0535bd4 100644 --- a/.github/workflows/compile-ai-docs-from-gcs.yaml +++ b/.github/workflows/compile-ai-docs-from-gcs.yaml @@ -8,22 +8,13 @@ on: types: [ai-docs-source-updated] workflow_dispatch: - inputs: - create_release: - description: 'Create a GitHub release with the bundle' - required: false - default: 'false' - type: choice - options: - - 'true' - - 'false' concurrency: group: compile-ai-docs-${{ github.ref }} cancel-in-progress: false permissions: - contents: write # For creating/updating releases + contents: read id-token: write # For GCP workload identity federation packages: write # For pushing to GHCR # TODO: Split into separate compile (read-only) and publish (write) jobs @@ -56,7 +47,6 @@ jobs: objects.githubusercontent.com:443 pypi.org:443 raw.githubusercontent.com:443 - release-assets.githubusercontent.com:443 rekor.sigstore.dev:443 run.googleapis.com:443 us-central1-run.googleapis.com:443 @@ -64,7 +54,6 @@ jobs: storage.googleapis.com:443 timestamp.sigstore.dev:443 tuf-repo-cdn.sigstore.dev:443 - uploads.github.com:443 - name: Checkout edu repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -295,23 +284,45 @@ jobs: --role "roles/run.invoker" \ --project "$PROJECT_ID" || true + - name: Sign bundle files + if: github.ref == 'refs/heads/main' + run: | + cd static/downloads + cosign sign-blob chainguard-ai-docs.tar.gz \ + --yes \ + --bundle=chainguard-ai-docs.tar.gz.bundle + cosign sign-blob chainguard-ai-docs.md \ + --yes \ + --bundle=chainguard-ai-docs.md.bundle + echo "Bundle files signed" + - name: Upload bundle back to GCS for distribution env: COMMIT_SHA: ${{ github.sha }} EVENT_NAME: ${{ github.event_name }} run: | echo "Uploading compiled bundle to GCS..." - + # Upload the compiled bundle for easy distribution gcloud storage cp static/downloads/chainguard-ai-docs.tar.gz \ gs://academy-all-docs/compiled/chainguard-ai-docs.tar.gz \ --project=chainguard-academy - + # Upload checksums gcloud storage cp static/downloads/checksums.txt \ gs://academy-all-docs/compiled/checksums.txt \ --project=chainguard-academy - + + # Upload cosign bundle files for artifact verification (only present on main branch builds) + if [ -f "static/downloads/chainguard-ai-docs.tar.gz.bundle" ]; then + gcloud storage cp static/downloads/chainguard-ai-docs.tar.gz.bundle \ + gs://academy-all-docs/compiled/chainguard-ai-docs.tar.gz.bundle \ + --project=chainguard-academy + gcloud storage cp static/downloads/chainguard-ai-docs.md.bundle \ + gs://academy-all-docs/compiled/chainguard-ai-docs.md.bundle \ + --project=chainguard-academy + fi + # Create and upload compilation metadata python3 -c " import json, datetime, os @@ -324,58 +335,9 @@ jobs: with open('/tmp/compilation-metadata.json', 'w') as f: json.dump(meta, f, indent=2) " - + gcloud storage cp /tmp/compilation-metadata.json \ gs://academy-all-docs/compiled/metadata.json \ --project=chainguard-academy - - echo "✓ Bundle uploaded to GCS" - - - name: Sign bundle files - if: github.ref == 'refs/heads/main' - run: | - cd static/downloads - cosign sign-blob chainguard-ai-docs.tar.gz \ - --yes \ - --bundle=chainguard-ai-docs.tar.gz.bundle - cosign sign-blob chainguard-ai-docs.md \ - --yes \ - --bundle=chainguard-ai-docs.md.bundle - echo "Bundle files signed" - - name: Create GitHub Release - if: github.ref == 'refs/heads/main' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - TAG="ai-docs-$(date -u +%Y%m%d-%H%M%S)" - - gh release create "$TAG" \ - --title "AI Documentation Bundle $TAG" \ - --notes "Chainguard AI documentation bundle for use with AI coding assistants." \ - --latest \ - static/downloads/chainguard-ai-docs.tar.gz \ - static/downloads/chainguard-ai-docs.tar.gz.bundle \ - static/downloads/chainguard-ai-docs.md \ - static/downloads/chainguard-ai-docs.md.bundle \ - static/downloads/chainguard-ai-docs.zip \ - static/downloads/image-catalog.json \ - static/downloads/checksums.txt \ - scripts/mcp-server.py \ - scripts/mcp-requirements.txt - - echo "Release $TAG created" - - - name: Clean up old releases - if: github.ref == 'refs/heads/main' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Keep only the 10 most recent dated releases; delete older ones - gh release list --limit 100 --json tagName,createdAt \ - | jq -r '[.[] | select(.tagName | test("^ai-docs-[0-9]{8}-[0-9]{6}$"))] | sort_by(.createdAt) | reverse | .[10:] | .[].tagName' \ - | while read -r tag; do - echo "Deleting old release: $tag" - gh release delete "$tag" --yes --cleanup-tag - done - echo "Release cleanup complete" \ No newline at end of file + echo "✓ Bundle uploaded to GCS" \ No newline at end of file diff --git a/content/ai-docs-security.md b/content/ai-docs-security.md index 4d7a27f384..658efc0535 100644 --- a/content/ai-docs-security.md +++ b/content/ai-docs-security.md @@ -86,22 +86,14 @@ Example patterns we redact: ## Verification Guide -### Direct Download Verification +### Container Image Verification -```bash -# 1. Download files -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/chainguard-ai-docs.tar.gz -curl -LO https://github.com/chainguard-dev/edu/releases/latest/download/chainguard-ai-docs.tar.gz.bundle +Verify the container image signature before pulling documentation: -# 2. Verify signature (using cosign v3 bundle format) -cosign verify-blob \ - --bundle chainguard-ai-docs.tar.gz.bundle \ +```bash +cosign verify ghcr.io/chainguard-dev/ai-docs:latest \ --certificate-identity-regexp ".*github.com/chainguard-dev/edu.*" \ - --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - chainguard-ai-docs.tar.gz - -# 3. Extract contents -tar -xzf chainguard-ai-docs.tar.gz + --certificate-oidc-issuer https://token.actions.githubusercontent.com ``` ## Build Frequency diff --git a/content/developer-resources.md b/content/developer-resources.md index 6c48bbeb97..7dded6fdd1 100644 --- a/content/developer-resources.md +++ b/content/developer-resources.md @@ -13,7 +13,7 @@ toc: false ## AI-Ready Documentation Bundle -This page provides compiled Chainguard documentation optimized for use with AI coding assistants like Claude, ChatGPT, GitHub Copilot, and others. Choose between our cryptographically signed direct downloads or our secure container distribution. +This page provides compiled Chainguard documentation optimized for use with AI coding assistants like Claude, ChatGPT, GitHub Copilot, and others. Access it through our secure container image or as a standalone Python MCP server. ### What's Included @@ -40,12 +40,6 @@ Choose your preferred distribution method: For enhanced security and verification, we recommend using the Chainguard container image. It includes built-in verification, runs as non-root, and is built on our secure wolfi-base image. -### GitHub Release - -| Format | Description | Verification | -|--------|-------------|-------------| -| [Latest Release](https://github.com/chainguard-dev/edu/releases/latest) | Cryptographically signed documentation bundle | Includes Cosign signatures and certificates | - ### Container Distribution Pull the secure, Chainguard-based container with embedded documentation: @@ -119,7 +113,7 @@ Add to your `claude_desktop_config.json`: - Searchable and queryable documentation - Perfect for automated workflows - Works with Claude Desktop, Cursor, and other MCP-compatible tools -- Also available as a [standalone Python script](https://github.com/chainguard-dev/edu/releases/latest) (no Docker required) +- Also available as a [standalone Python script](/mcp-server-ai-docs/#standalone-installation-without-docker) (no Docker required) [**Full MCP Server Documentation →**](/mcp-server-ai-docs/) @@ -137,7 +131,7 @@ docker run --rm -v $(pwd):/output ghcr.io/chainguard-dev/ai-docs:latest extract

Available Security Features