Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ updates:
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: Europe/Vienna
open-pull-requests-limit: 5
groups:
gradle-minor-and-patch:
update-types: [minor, patch]
Expand All @@ -16,8 +16,8 @@ updates:
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: Europe/Vienna
open-pull-requests-limit: 5
groups:
actions-minor-and-patch:
update-types: [minor, patch]
Expand All @@ -27,12 +27,24 @@ updates:
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: Europe/Vienna
open-pull-requests-limit: 5
groups:
python-minor-and-patch:
update-types: [minor, patch]

- package-ecosystem: pip
directory: /tests/fixtures/invalid_subject_oidc
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: Europe/Vienna
groups:
fixture-python-minor-and-patch:
update-types: [minor, patch]

# Best-effort Docker coverage; ARG/env indirection remains guarded by sbom-validate.
- package-ecosystem: docker
directories:
- /.devcontainer
Expand All @@ -42,8 +54,8 @@ updates:
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: Europe/Vienna
open-pull-requests-limit: 5
groups:
docker-minor-and-patch:
update-types: [minor, patch]
68 changes: 68 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Squarewise CodeQL

on:
push:
branches: [master]
pull_request:
branches: [master]
schedule:
- cron: '37 3 * * 1'
workflow_dispatch:

permissions:
contents: read

env:
JAVA_VERSION: '25'
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
# The manual extractor compiles every JVM module, including Kotlin sources.
GRADLE_OPTS: '-Dorg.gradle.jvmargs=-Xmx4g'

concurrency:
group: squarewise-codeql-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze ${{ matrix.language }}
runs-on: ubuntu-latest
timeout-minutes: 90
permissions:
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
include:
- language: java-kotlin
build-mode: manual
- language: python
build-mode: none
- language: actions
build-mode: none
steps:
- name: Check out repository
uses: actions/checkout@v7
with:
persist-credentials: false
- name: Set up Java
if: matrix.language == 'java-kotlin'
uses: actions/setup-java@v6
with:
distribution: microsoft
java-version: ${{ env.JAVA_VERSION }}
- name: Set up Gradle
if: matrix.language == 'java-kotlin'
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
- name: Initialize CodeQL
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Compile JVM production and test sources
if: matrix.language == 'java-kotlin'
run: ./gradlew testClasses --no-daemon --no-build-cache --console=plain
- name: Analyze
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
category: /language:${{ matrix.language }}
36 changes: 33 additions & 3 deletions docs/operations/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ and grant `pull-requests: read`, `id-token: write`, and `attestations: write` ex
at the calling job level (`ci`) so nested reusable workflow jobs (`lint`, `verify`, and other
artifact producers) can attest build provenance without escalating privileges across the workflow.

Security analysis is intentionally isolated in `codeql.yml`. It runs CodeQL on
pushes to `master`, pull requests targeting `master`, a weekly schedule, and
manual dispatch. Its matrix covers Java/Kotlin, all repository Python (including
`tests/`), and GitHub Actions. The Java/Kotlin lane uses Java 25 and a manual
`testClasses` Gradle build with the build cache disabled, ensuring CodeQL observes
both production and test compilation without executing tests. Python and Actions
use buildless analysis. The default high-precision query suite is used for every
lane; the repository's k6-only JavaScript files are intentionally outside this
security-focused matrix.

Fork pull requests use the unprivileged `pull_request` event. The workflow does
not inherit secrets, persist checkout credentials, or use `pull_request_target`;
its only job permissions are `contents: read` and `security-events: write`.
GitHub downgrades the token for fork code while still permitting CodeQL results
from a `pull_request` run to be uploaded. GitHub-configured maintainer approval
requirements for untrusted contributors apply and are not bypassed by this workflow.

CodeQL merge protection is staged separately from ordinary required status
checks. After successful default-branch, internal-PR, and approved fork-PR runs
and initial-alert triage, a dedicated default-branch ruleset is evaluated and
then activated for the CodeQL tool with non-security `errors` and security
`high_or_higher` thresholds. Lower-severity findings remain visible for planned
remediation, including findings confined to test code.

PR and non-master branch runs now calculate a changed-scope plan before the Gradle
matrix. The plan selects changed modules plus their reverse project dependents and
selects only the E2E streams affected by the changed paths. Master and manually
Expand All @@ -18,6 +42,8 @@ remain global checks where their tools need the complete repository; they are no
pretended to be module-local checks. The scope resolver is
`tools/ci/changed_scope.py`, with behavior tests in
`tests/tools/test_changed_scope.py`.
Changes under `tests/fixtures/invalid_subject_oidc/` select the edge stream so
fixture dependency updates exercise the negative OIDC path that consumes them.

The scope job keeps human diagnostics on the step log and writes only the
resolver's machine-readable `name=value` records to `$GITHUB_OUTPUT`. A
Expand Down Expand Up @@ -120,9 +146,13 @@ The Expense Core matrix shard also runs the opt-in PostgreSQL tests against the
other shards retain their normal test configuration.
Jobs use Microsoft Build of OpenJDK. Python dependencies
and tooling are deterministically managed via `pyproject.toml` and `uv.lock`.
Dependabot checks Gradle, GitHub Actions, uv, and repository Docker manifests on
one bounded weekly schedule from `.github/dependabot.yml`; minor and patch
updates are grouped per ecosystem to avoid unnecessary pull-request churn.
Dependabot checks Gradle, GitHub Actions, the root uv project, the standalone
OIDC fixture's pip manifest, and Dockerfiles on one bounded weekly schedule from
`.github/dependabot.yml`; minor and patch updates are grouped per ecosystem to
avoid unnecessary pull-request churn. Docker coverage is best-effort because
container image tags remain centralized in `infra/versions.env.example`, while
Dockerfiles and Compose use `ARG`/environment indirection; `make sbom-validate`
remains the authoritative container-version drift guard.
CI workflows install dependencies via the immutable commit
`astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7` (the `v10.2.0` tag)
with `uv sync --frozen --no-build`, running tools and scripts via
Expand Down
16 changes: 16 additions & 0 deletions docs/security/supply-chain-evidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ security hygiene passed: scanned 1035 tracked files
The script is run in CI as part of the `security-hygiene` Make target and the
`_reusable-ci.yml` workflow.

### CodeQL static analysis

The advanced CodeQL workflow analyzes Java/Kotlin, repository Python, and
GitHub Actions on `master`, pull requests targeting `master`, a weekly schedule,
and manual dispatch. Java/Kotlin production and test sources are compiled with
the repository Gradle wrapper under Java 25; Python analysis includes operational
tools and tests. The workflow uses the default high-precision query suite.

Fork pull requests execute only through the unprivileged `pull_request` event,
without inherited secrets or persisted checkout credentials. No
`pull_request_target` path executes contributor-controlled code. Merge
protection remains staged until hosted default-branch, internal-PR, and fork-PR
results are captured and the initial alert baseline is triaged; the target
policy reports every finding and blocks non-security errors plus high-or-higher
security alerts.

### Image hardening baseline

All application container images use:
Expand Down
1 change: 1 addition & 0 deletions docs/tasks/board.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ query classification, and evidence gates are complete.
| PR-48 | coordinator | done | Add CI dependency vulnerability review gate |
| PR-49 | coordinator | done | Bound GraphQL transport request sizes |
| PR-50 | coordinator | done | Remediate six independent PR #19 correctness and resource findings |
| OPS-33 | coordinator | in_progress | Advanced CodeQL analysis for master, PRs, and approved fork PRs |
| AUTH-01 | coordinator | done | Provider-neutral OIDC authentication hardening baseline and implementation tracker |
| AUTH-02 | coordinator | done | Remove implicit authentication identities with full boundary evidence |
| AUTH-03 | coordinator | done | Fail-closed provider-neutral OIDC resource-server validation |
Expand Down
10 changes: 8 additions & 2 deletions docs/tasks/details/DOC-28.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ durable task specifications, acceptance criteria, validation, and evidence.
completed tasks.
4. Issue forms apply the repository label taxonomy and provide a maintainer task
form for objective, dependencies, owned paths, acceptance, and validation.
5. Dependabot monitors Gradle, GitHub Actions, uv, and Docker manifests on one
bounded weekly schedule.
5. Dependabot monitors Gradle, GitHub Actions, the root uv project, the
standalone OIDC fixture's pip manifest, and Dockerfiles on one bounded
weekly schedule.
6. One stable required CI result aggregates selected verification jobs, and the
default-branch ruleset requires it together with reviewed, resolved PRs.
7. Repository guidance names one authority per concern and preserves durable
Expand Down Expand Up @@ -86,6 +87,11 @@ git diff --check
blocked-by relationships or a `blocked` label instead of a Waiting status.
- A Backlog table is the Jira-style overview for Backlog and Ready work, grouped
by Workstream and retaining native parent/sub-issue hierarchy.
- Dependabot's Docker updater is retained as best-effort coverage for direct
Dockerfile references. The repository's authoritative image tags remain
centralized in `infra/versions.env.example`; Dockerfile `ARG` references and
Compose environment indirection are not updated by Dependabot, so
`make sbom-validate` remains the local container-version drift guard.
- Repository milestone #1 (`Production readiness`) is assigned to epics #20/#21
and release-gated children #23-#26/#28-#31. The owner reports all configured
Project workflows active; public project data does not expose their settings.
Expand Down
2 changes: 1 addition & 1 deletion docs/tasks/details/OPS-32.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ E2E artifact-preparation failure must fail the gate.
6. Global repository-wide checks remain explicitly documented as global and are
not misrepresented as changed-module checks.
7. Scope behavior has typed unit tests for full, documentation-only, shared
library, E2E-only, and build-configuration changes.
library, E2E-only, OIDC-fixture, and build-configuration changes.
8. The Gradle build applies Develocity plugin 4.5.0; CI Gradle invocations
publish tagged Build Scans without affecting local publication behavior.

Expand Down
113 changes: 113 additions & 0 deletions docs/tasks/details/OPS-33.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# OPS-33: Advanced CodeQL analysis

## Status

In progress. Local workflow implementation and validation are owned by the
coordinator; hosted default-branch, internal-PR, and fork-PR evidence is still
required before closure.

## Objective

Add an isolated advanced CodeQL workflow that analyzes Java/Kotlin, repository
Python, and GitHub Actions on the default branch and pull requests, including
approved pull requests from forks. Keep untrusted fork code away from secrets
and privileged workflow triggers.

## Dependencies

- `OPS-04`
- `OPS-05`
- `OPS-15`
- `OPS-24`
- `PR-21`

All dependencies are complete.

## Owned paths and handoff

- `.github/workflows/codeql.yml`
- CodeQL sections in `docs/operations/ci.md`
- CodeQL sections in `docs/security/supply-chain-evidence.md`
- `docs/tasks/details/OPS-33.md`
- Coordinator-owned tracking updates in `docs/tasks/registry.yaml`,
`docs/tasks/board.md`, and `docs/tasks/progress.md`

The coordinator grants this task a scoped handoff from active tasks `OPS-20`,
`DOC-28`, and `OPS-32` for the paths above. Existing reusable and caller CI
workflows remain outside this task.

## Acceptance criteria

1. CodeQL runs on pushes to `master`, pull requests targeting `master`, a
weekly schedule, and manual dispatch.
2. The matrix analyzes `java-kotlin`, `python`, and `actions` with the default
high-precision query suite.
3. The Java/Kotlin lane compiles production and test sources with Java 25 and
the repository Gradle wrapper without running tests or restoring compiled
task outputs.
4. Fork pull requests use `pull_request`, receive no repository secrets, and
never execute through `pull_request_target`.
5. Actions use least-privilege permissions and immutable references required by
repository policy.
6. Python analysis includes both operational tooling and tests. Low and medium
findings remain reported; staged merge protection later blocks errors and
high-or-higher security alerts for the CodeQL tool.
7. Local workflow, tracking, security-hygiene, and whitespace validations pass;
hosted evidence and limitations are recorded accurately.

## Validation commands

```text
./gradlew testClasses --dry-run --no-daemon --console=plain
make workflow-validate
uv run --frozen --no-build python -m unittest tools.coverage.test_report_tools
uv run --frozen --no-build python tools/contracts/validate.py
uv run --frozen --no-build python tools/contracts/validate_public_surface.py
make security-hygiene
git diff --check
```

## Expected hosted evidence

- Successful `java-kotlin`, `python`, and `actions` analyses on `master`.
- Successful analyses and uploaded results for one internal pull request and
one approved fork pull request.
- Tool Status coverage for all three languages and an initial-alert triage.
- A separate default-branch CodeQL ruleset evaluated before activation with
`errors` and `high_or_higher` thresholds.

## Implementation principles

The workflow is independent from the existing reusable CI, adds no application
dependency or custom abstraction, reuses the repository's Java/Gradle setup,
and keeps one security-analysis definition. A separate JavaScript lane is
intentionally omitted because the tracked JavaScript is limited to non-shipping
k6 load probes.

## Local implementation evidence (2026-10-27)

- Added the isolated three-lane workflow with the documented triggers,
least-privilege permissions, immutable CodeQL references, and manual JVM
extraction build.
- `./gradlew testClasses --no-daemon --no-build-cache --console=plain` passed
all 50 actionable tasks in 31 seconds.
- `make workflow-validate`, direct PyYAML parsing, both contract validators,
`make security-hygiene`, the focused immutable-action policy test, and
`git diff --check` passed.
- The full `tools.coverage.test_report_tools` module remains red on 13 failures
and two errors that predate this task: stale QA-10 source/report counts,
references to retired error infrastructure and a removed coverage-inventory
workflow job, and unavailable generated JaCoCo ledger data. Its focused
action-reference policy passes with the new workflow.
- Hosted CodeQL runs, initial-alert triage, fork execution, and the evaluated
then active merge-protection ruleset remain pending until this commit is
available on GitHub.
- Local implementation commit: `bdf0536ee8af9b0bcb0e8c5503d713b288ea8178`.

## Hosted PR-55 follow-up (2026-10-27)

The first hosted CodeQL run (`40510007886`) passed the Python and Actions lanes
but the Java/Kotlin lane failed while compiling `:app:accounts:compileKotlin`
with `java.lang.OutOfMemoryError: Java heap space` (job `122209107187`). The
workflow now gives the manual Gradle extraction build a 4 GiB heap through
`GRADLE_OPTS`; the replacement hosted run and fork-PR evidence remain pending.
Loading
Loading