Skip to content
Merged

150 #58

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f8e1a94
feat(auth): add Azure Entra ID (OpenID Connect) authentication
alvagante Jun 10, 2026
7559dd7
chore(release): bump version to 1.5.0
alvagante Jun 10, 2026
c622278
docs: add upgrade guide and update documentation for v1.5.0
alvagante Jun 11, 2026
e52abe8
chore(specs): organize and archive completed feature specifications
alvagante Jun 11, 2026
ba68bb9
feat(console): implement console integration framework with session m…
alvagante Jun 13, 2026
c568b51
test(console): add comprehensive test coverage for widget grid and fr…
alvagante Jun 18, 2026
72fcf8f
feat(frontend): add Puppet Agent Actions widget and improve UI integr…
alvagante Jun 18, 2026
5e18766
chore(docker): build sqlite3 from source for musl/glibc compatibility
alvagante Jun 18, 2026
d014e32
feat(frontend): add SSO callback handling and improve auth guard logic
alvagante Jun 19, 2026
b1e6afe
feat(security): implement command-whitelist enforcement and fix execu…
alvagante Jul 2, 2026
600ef83
fix(security): improve Entra ID SSO rate limit bypass and endpoint ro…
alvagante Jul 6, 2026
bde7cbe
feat(inventory): add PQL query support to parallel execution modal
alvagante Jul 15, 2026
597dd5a
Fixing tests
alvagante Jul 15, 2026
6b2ea0d
Tests e2e cleanup and docs for tests flakiness
alvagante Aug 26, 2026
63c4a79
fix(tests): root-cause and fix backend suite flakiness
alvagante Aug 26, 2026
ee7fb20
docs: refine flakiness diagnosis with mechanism verification
alvagante Aug 26, 2026
f485312
feat(security): enforce RBAC on infrastructure routes (S01)
alvagante Sep 9, 2026
bbf2dd7
feat(security): enforce per-route and per-tool authorization on infra ro
alvagante Sep 10, 2026
cc42513
feat(security): durable session and permission revocation
alvagante Sep 10, 2026
7d84333
feat(security): scope MCP tool authorization to the session caller
alvagante Sep 10, 2026
b4f9533
feat(security): gate entitlement administration behind rbac:admin (A07)
alvagante Sep 10, 2026
af461d4
feat(security): harden SSO, SSH trust, and initial setup (A08/A09)
alvagante Sep 10, 2026
583a19e
feat(database): make execution storage writes transaction-scoped (A12)
alvagante Sep 11, 2026
78d4aca
feat(deployment): harden image builds and Helm rotation (A10/A11)
alvagante Sep 11, 2026
9fc99c1
feat(execution): complete durable batch lifecycle
alvagante Sep 11, 2026
baf818a
feat(execution): standardize mutation retries and durable idempotency
alvagante Sep 11, 2026
11be2b2
feat(console): wire provider connections and enforce session lifecycle
alvagante Sep 11, 2026
212e7d9
fix(streaming): report terminal status and release stream state
alvagante Sep 11, 2026
80634f6
fix(inventory): unify the generic lifecycle credential and action policy
alvagante Sep 11, 2026
acfa3bf
test(ci): gate components, PostgreSQL, E2E flows and the whole tree
alvagante Sep 11, 2026
6b0d6e0
docs: correct operational references and gate API contracts
alvagante Sep 12, 2026
f4798d3
fix(security): bound workloads and sanitize diagnostic exports
alvagante Sep 12, 2026
eca4f97
fix(deployment): enforce the supported single-process topology
alvagante Sep 12, 2026
12c247c
fix(runtime): bound shutdown and provider reads and reconcile restart…
alvagante Sep 12, 2026
4642dbc
Complete execution lifecycle remediation
alvagante Sep 13, 2026
d91b6ce
Add compiled backend script to Docker build contexts
alvagante Sep 13, 2026
7dfdded
Harden Docker images against known base-image CVEs
alvagante Sep 13, 2026
fbdd3ec
Allow CI image scan to fail without blocking the pipeline
alvagante Sep 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .github/workflows/chart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Helm chart checks

on:
pull_request:
paths: ['charts/**', 'scripts/deployment/**', '.github/workflows/chart.yml']
push:
branches: [main, develop]
paths: ['charts/**', 'scripts/deployment/**', '.github/workflows/chart.yml']

jobs:
render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- uses: azure/setup-helm@v4
with:
version: v4.2.4
- run: npm ci --ignore-scripts
- run: helm dependency build charts/pabawi
- run: helm lint charts/pabawi
- run: node --test scripts/deployment/chart.test.mjs
148 changes: 126 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,26 @@ jobs:
lint-and-test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
node-version-file: '.nvmrc'

- name: Install dependencies
run: npm ci
run: npm ci --ignore-scripts

- name: Run approved dependency scripts
run: npm run install:approved

- name: Rebuild native modules
run: npm rebuild bcrypt sqlite3 ssh2 --ignore-scripts=false
- name: Verify install-script policy
run: node --test scripts/supply-chain/install-approved.test.mjs

- name: Check documentation contracts
run: node --test scripts/documentation/contracts.test.mjs

- name: Run ESLint
run: npm run lint
Expand All @@ -40,30 +42,132 @@ jobs:
run: npx tsc --noEmit
working-directory: ./frontend

- name: Check Svelte components
run: npm run check:components

- name: Run unit tests
run: npm test -- --silent

- name: Build backend
run: npm run build:backend
run: node --test scripts/compilation/backend.test.mjs

- name: Verify built-server shutdown signals
run: node scripts/deployment/process-smoke.mjs

- name: Build frontend
run: npm run build:frontend

docker-build-test:
postgres-suite:
# The migration, transaction and upgrade tests that only run when a real
# PostgreSQL server is reachable. Without this job they are skipped
# everywhere except a maintainer's laptop (finding I10).
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_USER: pabawi
POSTGRES_PASSWORD: pabawi
POSTGRES_DB: pabawi
ports: ['5432:5432']
options: >-
--health-cmd "pg_isready -U pabawi"
--health-interval 5s
--health-timeout 5s
--health-retries 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- run: npm ci --ignore-scripts
- run: npm run install:approved
- name: Run the backend suite against PostgreSQL
run: npx vitest run --silent
working-directory: ./backend
env:
TEST_DATABASE_URL: postgres://pabawi:pabawi@localhost:5432/pabawi

e2e:
# The assembled app, served as it ships, against the hermetic SSH fixture.
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- run: npm ci --ignore-scripts
- run: npm run install:approved
- run: npx playwright install --with-deps chromium
- run: npm run test:e2e
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
secret-scan:
# The pre-commit hook excludes docs, tests and e2e fixtures. This job scans
# them too, so a credential committed under an excluded path is still
# caught before merge (finding I10).
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install detect-secrets==1.5.0
- name: Scan the tracked tree against the reviewed baseline
run: bash scripts/quality/secret-scan.sh

dependency-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Audit the reviewed lockfile
run: npm audit --json --audit-level=high > npm-audit.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: npm-audit
path: npm-audit.json

- name: Build Docker image (test)
uses: docker/build-push-action@v5
docker-build-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
variant: [bookworm, alpine, ubuntu]
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build and verify shipped image
run: |
file=Dockerfile
if [ "${{ matrix.variant }}" != bookworm ]; then file="Dockerfile.${{ matrix.variant }}"; fi
docker build --no-cache -f "$file" -t pabawi:test .
bash scripts/supply-chain/image-smoke.sh pabawi:test
mkdir -p artifacts
docker run --rm -i --entrypoint node pabawi:test < scripts/supply-chain/dependency-graph.cjs > artifacts/dependencies.json
docker build --no-cache --target backend-deps -f "$file" -t pabawi:deps-repeat .
docker run --rm -i --entrypoint node pabawi:deps-repeat < scripts/supply-chain/dependency-graph.cjs > artifacts/dependencies-repeat.json
cmp artifacts/dependencies.json artifacts/dependencies-repeat.json
if [ "${{ matrix.variant }}" = ubuntu ]; then
docker run --rm --entrypoint ruby pabawi:test /opt/bolt/test-winrm-rubyzip.rb
docker run --rm -i --entrypoint ruby pabawi:test < docker/bolt/dependency-graph.rb > artifacts/ruby-dependencies.json
docker build --no-cache --target bolt-builder -f "$file" -t pabawi:ruby-repeat .
docker run --rm -i --entrypoint ruby pabawi:ruby-repeat < docker/bolt/dependency-graph.rb > artifacts/ruby-dependencies-repeat.json
cmp artifacts/ruby-dependencies.json artifacts/ruby-dependencies-repeat.json
fi
- name: Scan shipped image and generate SBOM
continue-on-error: true
run: bash scripts/supply-chain/scan-image.sh pabawi:test artifacts
- name: Retain image evidence
if: always()
uses: actions/upload-artifact@v4
with:
context: .
push: false
tags: pabawi:test
cache-from: type=gha
cache-to: type=gha,mode=max
name: image-evidence-${{ matrix.variant }}
path: artifacts/*.json
109 changes: 75 additions & 34 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,104 @@ env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false

jobs:
build-and-publish:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [amd64, arm64]
permissions:
contents: write
contents: read
packages: write
id-token: write
attestations: write

steps:
- name: Checkout code
uses: actions/checkout@v4

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

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Extract release metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest
type=sha

- name: Build and push Docker image
id: build
tags: type=semver,pattern={{version}}
- name: Build release candidate locally
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
platforms: linux/${{ matrix.arch }}
load: true
push: false
tags: pabawi:candidate
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64

- name: Generate artifact attestation
cache-from: type=gha,scope=release-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=release-${{ matrix.arch }}
- name: Verify release candidate
env:
DOCKER_DEFAULT_PLATFORM: linux/${{ matrix.arch }}
run: |
bash scripts/supply-chain/image-smoke.sh pabawi:candidate
mkdir -p artifacts
docker run --rm -i --entrypoint node pabawi:candidate < scripts/supply-chain/dependency-graph.cjs > artifacts/dependencies.json
- name: Scan release candidate
run: bash scripts/supply-chain/scan-image.sh pabawi:candidate artifacts
- name: Retain release evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: release-evidence-${{ matrix.arch }}
path: artifacts/*.json
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push the verified image without rebuilding
id: push
run: |
tag="${REGISTRY}/${IMAGE_NAME}:${GITHUB_REF_NAME}-${{ matrix.arch }}"
docker tag pabawi:candidate "$tag"
docker push "$tag"
digest=$(docker inspect --format '{{index .RepoDigests 0}}' "$tag")
echo "digest=${digest#*@}" >> "$GITHUB_OUTPUT"
- name: Attest the verified image
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

create-release:
publish-manifest:
needs: build-and-publish
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish verified architecture images
run: |
version="${GITHUB_REF_NAME#v}"
image="${REGISTRY}/${IMAGE_NAME}"
tags=(--tag "$image:$version" --tag "$image:sha-${GITHUB_SHA:0:7}")
if [[ "$version" != *-* ]]; then
tags+=(--tag "$image:${version%.*}" --tag "$image:${version%%.*}" --tag "$image:latest")
fi
docker buildx imagetools create "${tags[@]}" \
"$image:${GITHUB_REF_NAME}-amd64" "$image:${GITHUB_REF_NAME}-arm64"

create-release:
needs: publish-manifest
runs-on: ubuntu-latest
permissions:
contents: write

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
node_modules/
node_modules_mac/
node_modules_cont/
charts/pabawi/charts/

# Build outputs
dist/
Expand Down Expand Up @@ -78,3 +79,6 @@ samples/stresstest/bolt/inventory.yaml
.claude/scheduled_tasks.lock
.claude/scheduled_tasks.json
# END swamp managed section
e2e/.auth/
test-results/
playwright-report/
Loading
Loading