Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0acf506
Restore CodeQL coverage via advanced setup, with a Go analysis that w…
Aug 22, 2026
7731615
Use `queries: code-quality`, and give the extractor the host-executor…
Aug 22, 2026
59d4bda
Ship the CodeQL design note
Aug 22, 2026
520fa41
Add an aggregate `CodeQL gate` job so the lever is one check, not four
Aug 22, 2026
f90a42d
Print CodeQL findings to the job log, and document the two gating levers
Aug 22, 2026
5ae15f1
Give each scanner one job: ruff owns Python, CodeQL owns taint, Semgr…
Aug 22, 2026
def55c5
Fix every scanner finding and make the scanners block
Aug 22, 2026
358bcbc
Report scan coverage, not just the verdict
Aug 22, 2026
056a882
Pass runner.temp through env, not inline in the run: block
Aug 22, 2026
8d4cf23
Apply ruff format to the Python tree
Aug 22, 2026
db43ec8
Gate the scanners through ci-gate/Dev gate, audit npm deps, enforce f…
Aug 22, 2026
745fe6d
Close every scanner follow-up: B/SIM/S fixed+enabled, security-extend…
Aug 22, 2026
47a1e58
Move the CodeQL/Semgrep cron alarm to a workflow_run watcher
Aug 22, 2026
06ad52a
Harden fleet_ref against fork-PR refs; fix the canary path; file:line…
Aug 22, 2026
39b4743
Record the extended-suite verification and the untrusted-checkout fix…
Aug 22, 2026
4856815
Merge pull request #1246 from ElcanoTek/claude/codeql-advanced-setup-…
bradflaugher Aug 22, 2026
7b405e8
Close three own-rows authorization holes on the task surface
Aug 22, 2026
e90fc99
CodeQL: gate on High-and-above plus a reviewed accepted-findings regi…
Aug 22, 2026
9a573e8
Fix a vacuous CodeQL gate, and harden the CI supply chain
Aug 22, 2026
9340efd
Remove dead code, close the CI permission gaps, settle two stale claims
Aug 22, 2026
e2ff6a6
Attribute the fixtures that the own-rows edit gate now requires
Aug 22, 2026
054e9f0
Trim the unlinked planning scratchpad to its one live plan
Aug 22, 2026
68da691
Give the tool-output redactor the connector secrets it never had
Aug 22, 2026
5003949
Correct every false and stale claim the audit found in the docs
Aug 22, 2026
8e17eba
Revert generated next-env.d.ts churn
Aug 22, 2026
a88dd9d
Record why the forced final summary is exempt from the ceiling guard
Aug 22, 2026
373dcec
Merge pull request #1247 from ElcanoTek/claude/enterprise-security-au…
bradflaugher Aug 22, 2026
a8e21b3
Kubernetes as a first-class deployment: pluggable sandbox backend + H…
bradflaugher Aug 22, 2026
754745b
CI: lint the workflows themselves, close two green-but-vacuous holes,…
Aug 23, 2026
849c5bc
Add PR/issue templates, a contributor-facing CI section, and correct …
Aug 23, 2026
2161202
Remove automatic merging and the unenforced DCO requirement
Aug 23, 2026
60d8abd
Reconcile the CI docs with the workflows, and close two residual expo…
Aug 23, 2026
7439ad8
CI review: lint the workflows themselves, close two green-but-vacuous…
bradflaugher Aug 23, 2026
df9602b
Kubernetes: let a sandbox image serve the bundle's doc reads
Aug 23, 2026
35890f0
Drop three unused nolint:gosec directives
Aug 23, 2026
4c9a12c
Merge pull request #1251 from ElcanoTek/claude/zeta-kubernetes-config…
bradflaugher Aug 23, 2026
82231f7
Reconcile AGENTS.md with the tree it describes
claude Aug 23, 2026
cba62ee
Reconcile AGENTS.md with the tree it describes (#1252)
bradflaugher Aug 23, 2026
e44e9ca
Merge remote-tracking branch 'origin/dev' into claude/agents-review-f…
claude Aug 23, 2026
f60767e
Make ci.yml's pg_dump major assertion able to pass
claude Aug 23, 2026
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
31 changes: 17 additions & 14 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,28 @@
# - Require a pull request before merging (no direct pushes to `main`).
# - Require status checks to pass, with "branches up to date" (strict) ON. The
# SINGLE required check is the `CI gate` job in .github/workflows/ci.yml: it
# `needs` every other CI job (Go build / vet / lint / test — which also runs
# vet, the -race lane and govulncheck; Web lint / test / build; Playwright
# mocked; Playwright live; the gitleaks secret scan; and the Grype
# container-image CVE scan) and fails unless each
# one succeeded or was cleanly skipped. Requiring that one aggregate check
# `needs` EVERY other job in that file — the docs-only classifier; the
# gitleaks secret scan; the actionlint workflow lint; the migration DDL
# lint; the Helm chart lint; Go build / vet / lint / test (which also runs
# the -race lane and govulncheck); the ruff Python lint; CodeQL and Semgrep
# (called as reusable workflows); Web lint / typecheck / test / build with
# both npm audits; Playwright mocked; Playwright live; and the Grype
# container-image CVE scan — and fails unless each
# one succeeded or was cleanly skipped.
# Do not maintain this list by hand alone: scripts/check_gate_needs_test.go
# fails `make test` if any job in ci.yml is missing from `ci-gate`'s needs. Requiring that one aggregate check
# rather than each job by name is what lets a docs-only PR skip the heavy jobs
# without being left blocked on a required check that never reported.
# - Block force-pushes (non-fast-forward) and branch deletion.
# Deliberately NOT enabled — a CI-only gate so the sole maintainer can self-merge
# a green PR — are required approvals and Code Owner review (see the note above).
#
# Dependabot auto-merge interaction: .github/workflows/auto-merge-dependabot.yml
# enables `gh pr merge --auto` on PATCH-level bumps only, and the required `CI
# gate` check holds that merge until CI is green. Because Code Owner review is
# NOT currently required, such a patch PR auto-merges on green CI with no human
# approval — INCLUDING a github-actions patch bump that touches a CODEOWNERS-
# matched path like .github/workflows/. To force a human gate on those sensitive
# paths, turn on Code Owner review in the ruleset; minor and major bumps already
# wait for a human regardless.
# Dependabot interaction: there is no auto-merge in this repository. Every
# dependency bump — every ecosystem, every bump level — is merged by a human, so
# a github-actions bump touching a CODEOWNERS-matched path like
# .github/workflows/ cannot land unattended. Turning on Code Owner review in the
# ruleset would additionally force review by the owner named below rather than
# any maintainer.
# ---------------------------------------------------------------------------

# Catch-all: every file has an owner so nothing is silently unowned. Specific
Expand Down Expand Up @@ -81,7 +84,7 @@
/internal/sched/db/migrations/ @bradflaugher

# CI gates and dependency/agent automation — these workflows ARE the merge
# guarantees, including the Dependabot auto-merge path.
# guarantees.
/.github/workflows/ @bradflaugher
/.github/dependabot.yml @bradflaugher
/.github/CODEOWNERS @bradflaugher
44 changes: 44 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Bug report
description: Something in fleet does not behave as documented.
labels: [bug]
body:
- type: markdown
attributes:
value: |
For a **security vulnerability**, stop and read
[SECURITY.md](https://github.com/ElcanoTek/fleet/blob/main/SECURITY.md)
instead — do not file it here.
- type: textarea
id: what-happened
attributes:
label: What happened
description: What you observed, and what you expected instead.
validations: {required: true}
- type: textarea
id: repro
attributes:
label: Steps to reproduce
description: The smallest sequence that shows the problem.
placeholder: |
1. fleet serve with ...
2. ...
3. Observed: ...
validations: {required: true}
- type: textarea
id: version
attributes:
label: Version and environment
description: >-
Output of `fleet version` (or the commit you built from), your OS, and
whether Podman is running rootless. `fleet doctor` output is ideal.
render: shell
validations: {required: true}
- type: textarea
id: logs
attributes:
label: Relevant logs
description: >-
Redact before pasting. fleet brokers credentials host-side precisely so
they never reach a log, but check anyway.
render: shell
validations: {required: false}
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Blank issues are disabled so the security contact link below is unmissable.
# SECURITY.md and CODE_OF_CONDUCT.md both say "do not open a public issue for a
# vulnerability", and until now the New Issue button offered a blank box with no
# such warning — the one moment a reporter is most likely to get it wrong.
blank_issues_enabled: false
contact_links:
- name: Report a security vulnerability (private)
url: https://github.com/ElcanoTek/fleet/blob/main/SECURITY.md
about: Please do NOT open a public issue. SECURITY.md has the private
disclosure process and the response SLA.
- name: Contributing guide
url: https://github.com/ElcanoTek/fleet/blob/main/CONTRIBUTING.md
about: Build, test and lint commands, the CI gates, and PR conventions.
39 changes: 39 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Feature request
description: Propose a capability or a change to how fleet behaves.
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: The problem
description: >-
What are you trying to do that fleet makes hard or impossible? Describe
the situation rather than the solution you have in mind.
validations: {required: true}
- type: textarea
id: proposal
attributes:
label: What you would like fleet to do
validations: {required: true}
- type: dropdown
id: invariant
attributes:
label: Does this touch one of the invariants in AGENTS.md?
description: >-
The mandatory sandbox, host-side credentials, the single governed loop,
no secrets in the repo, honest docs, or client content living in an
out-of-repo bundle. If yes, it needs an ADR — say so here and we can
work out the shape before anyone writes code.
options:
- "No — this is additive and does not touch an invariant"
- "Yes — or I am not sure"
validations: {required: true}
- type: textarea
id: bundle
attributes:
label: Could this ship as a client-config bundle instead?
description: >-
fleet is an engine; per-customer MCP servers, personas, protocols and
prompts belong in a bundle rather than in this repo. If you think this
genuinely needs an engine change, say why the bundle cannot express it.
validations: {required: false}
33 changes: 33 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!--
Thanks for contributing to fleet. The prose boxes matter more than the
checkboxes — a reviewer can verify a checkbox themselves, but only you can
explain why.
-->

## What changed, and why

<!-- One or two paragraphs. What problem does this solve? -->

## How you verified it

<!--
Name what you actually ran, not what you intended to run. `make lint`,
`make test`, `make ci-web`, the mocked Playwright suite, a manual check —
and what it said. "CI will tell us" is not a verification.
-->

## Scope and deviations

<!--
Per AGENTS.md: what shipped, what deviated from the issue, and what you
deliberately deferred. If nothing deviated, say so — that is a useful
sentence, not a wasted one.
-->

---

- [ ] `CHANGELOG.md` updated, if this is a user-visible change
- [ ] A design note (`docs/<FEATURE>.md`) added, if this ships a feature
- [ ] An ADR added or superseded in `docs/adr/`, if this adds, weakens or
reverses an invariant — required in the *same* PR
- [ ] The diff is scoped to one change (no unrelated refactors)
5 changes: 5 additions & 0 deletions .github/codeql-accepted-findings.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@
"rule": "js/insecure-temporary-file",
"file": "web/e2e/test-auth-key.ts",
"reason": "Test-only, and the reported defect is fixed as far as it can be without changing the cross-process rendezvous contract: the write is now O_EXCL (flag \"wx\") at mode 0600 with crypto random bytes in the sibling name, so it cannot follow or clobber a pre-planted symlink and does not leave the private half world-readable. The query recognizes only mkdtemp as safe, but the fixed path is a deliberate rendezvous — playwright.config.ts is loaded in the main process AND re-imported in every worker, which must all read the same throwaway keypair. The key is generated per run, protects nothing real, and is never committed."
},
{
"rule": "go/command-injection",
"file": "internal/sandbox/host.go",
"reason": "hostImpl.runBash executing caller-supplied shell (`bash -c req.Command`) IS the component's contract: it is the unsandboxed TEST/DEV-ONLY executor, compiled solely behind the fleet_host_executor build tag (#159) — a release `go build ./...` contains the fail-closed stub in host_disabled.go and MockMode refuses to boot without the tag, so this sink cannot ship in a production binary (ADR-0002's enforcement). Every production tool call runs through the container or kubernetes backend instead. The same line already carries the equivalent gosec waiver ('shell execution is the purpose of this tool'). The finding surfaced on #1249 because the diff-informed PR run intersected the flow's path (sandbox.go/pool.go edits), not because a new source reached the sink."
}
]
}
33 changes: 13 additions & 20 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
# release. This is a deliberate defense against fast typosquat / account-takeover
# attacks, where a compromised version is published and then yanked once the
# ecosystem flags it — by the time Dependabot proposes the bump, that window has
# usually closed. It matters most for patch bumps, which the auto-merge workflow
# (`.github/workflows/auto-merge-dependabot.yml`) merges on its own once CI is
# green: the cooldown keeps a minutes-old patch from being proposed (and thus
# auto-merged) before the ecosystem has had a chance to scrutinize it. Cooldown
# applies to version updates only, never to Dependabot security updates, so
# urgent CVE fixes are not delayed.
# usually closed. Every bump here is merged by a human (this repository has no
# auto-merge), so the cooldown is not load-bearing on its own; what it buys is
# that a reviewer is never looking at a release the ecosystem has not yet had a
# chance to scrutinize. Cooldown applies to version updates only, never to
# Dependabot security updates, so urgent CVE fixes are not delayed.
#
# Schema (key `cooldown`, integer `*-days` sub-keys; supported for gomod and npm;
# applies to version updates only):
Expand Down Expand Up @@ -113,15 +112,12 @@ updates:
# CVE fixes are never delayed behind dev.
target-branch: dev
open-pull-requests-limit: 10
# Wait before proposing freshly published releases (see header). Patch is the
# tightest gate because auto-merge-dependabot.yml auto-merges patch bumps.
# Wait before proposing freshly published releases (see header).
cooldown:
default-days: 7
# 7, not 14: the supply-chain argument in the header is about the
# AUTO-MERGE path, and auto-merge-dependabot.yml merges patch only —
# a major is never auto-merged, so delaying it protects nothing and
# costs up to 14 days of visibility (cooldown + the weekly interval)
# before anyone even learns the major exists.
# 7, not 14 for a major: a long delay protects nothing here — a major is
# reviewed by a human either way — and costs up to 14 days of visibility
# (cooldown + the weekly interval) before anyone even learns it exists.
semver-major-days: 7
semver-minor-days: 7
semver-patch-days: 3
Expand Down Expand Up @@ -156,11 +152,9 @@ updates:
# Same supply-chain cooldown as gomod (see header).
cooldown:
default-days: 7
# 7, not 14: the supply-chain argument in the header is about the
# AUTO-MERGE path, and auto-merge-dependabot.yml merges patch only —
# a major is never auto-merged, so delaying it protects nothing and
# costs up to 14 days of visibility (cooldown + the weekly interval)
# before anyone even learns the major exists.
# 7, not 14 for a major: a long delay protects nothing here — a major is
# reviewed by a human either way — and costs up to 14 days of visibility
# (cooldown + the weekly interval) before anyone even learns it exists.
semver-major-days: 7
semver-minor-days: 7
semver-patch-days: 3
Expand All @@ -180,8 +174,7 @@ updates:
#
# Know what a green build means here: no CI job exercises this service, and
# `@nationaldesignstudio/rampart` is pre-1.0 (^0.1.3), where a MINOR bump is
# allowed to break. Auto-merge cannot touch these (it gates on patch only),
# so they land in human review — which is the right outcome, not a gap.
# allowed to break. Like every other bump here, these land in human review.
- package-ecosystem: npm
directory: "/scripts/rampart-service"
schedule:
Expand Down
74 changes: 0 additions & 74 deletions .github/workflows/auto-merge-dependabot.yml

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
benchmarks:
name: Subsystem throughput benchmarks
runs-on: ubuntu-latest
timeout-minutes: 60

services:
postgres:
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/build-sandbox-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ jobs:
build:
name: Build sandbox (no push)
runs-on: ubuntu-latest
timeout-minutes: 45
env:
BUNDLE_DIR: ${{ inputs.bundle_dir }}
steps:
Expand All @@ -112,6 +113,31 @@ jobs:
# actions/untrusted-checkout under security-extended; the same pattern in
# publish-sandbox-image.yml was hardened symmetrically even though the
# query's privileged/taint split happened to flag neither variant there.)
- name: Validate bundle_dir
# `fleet_ref`, which reaches the SAME build-script invocation, got a
# character allow-list, a bare-SHA refusal and a GITHUB_OUTPUT-newline
# fix. `bundle_dir` got nothing, and the asymmetry is the whole reason
# this exists — there is no shell injection here (it goes through `env:`
# and is quoted at every use), but nothing stopped `../../.fleet-core`
# or an absolute path from silently repointing the build at a different
# manifest. The reusable workflow runs in the CALLER's context with the
# caller's token, so the blast radius is a client repo misbuilding its
# own image; this is defence in depth and consistency, not a live hole.
env:
REQUESTED: ${{ inputs.bundle_dir }}
run: |
set -euo pipefail
case "$REQUESTED" in
""|.) ;;
/*)
echo "::error::bundle_dir must be relative to the caller repo, not absolute."; exit 1 ;;
*..*)
echo "::error::bundle_dir must not contain '..' — it may only name a path inside the caller repo."; exit 1 ;;
*[!a-zA-Z0-9._/-]*)
echo "::error::bundle_dir contains a character outside [A-Za-z0-9._/-]. Refused before the build."; exit 1 ;;
esac
echo "bundle_dir accepted: '${REQUESTED:-.}'"

- name: Pin fleet_ref to collaborator-controlled refs
id: pin
env:
Expand Down
Loading
Loading