Skip to content

Add documentation and enable signature verification for git submodules#5

Merged
adrelanos merged 1 commit intoKicksecure:masterfrom
assisted-by-ai:claude/review-sequoia-pgp-usage-5sQSx
Apr 1, 2026
Merged

Add documentation and enable signature verification for git submodules#5
adrelanos merged 1 commit intoKicksecure:masterfrom
assisted-by-ai:claude/review-sequoia-pgp-usage-5sQSx

Conversation

@assisted-by-ai
Copy link
Copy Markdown

Summary

This PR improves documentation clarity around git trust models and enables cryptographic signature verification for git submodule updates in the derivative-update process.

Key Changes

  • Submodule signature verification: Updated derivative-update to use git_verify_command_wrapper for submodule updates, enabling signature verification via merge.verifySignatures=true configuration.

  • Trust model documentation: Added comprehensive comments explaining the trust root strategy:

    • CI builds use 'HEAD' as trust root (acceptable for untrusted CI environments following TOFU model)
    • Non-redistributable builds use 'HEAD' as trust root (developer's own trusted checkout)
    • Redistributable builds use full history-based verification for stronger guarantees
  • TOFU security clarification: Added reference to TOFU (Trust On First Use) threat model documentation in git_sanity_test, noting that manual verification is required for stronger-than-TOFU security.

  • sq-git-wrapper clarification: Updated comments to document that sq-git-wrapper is actively used as gpg.openpgp.program for submodule signature verification, removing outdated "Unused/TODO" notes.

  • Signify key documentation: Added comments clarifying that signify keys are used by dm-prepare-release in the developer-meta-files package.

Implementation Details

The signature verification is now consistently applied across both redistributable and non-redistributable build paths in derivative-update, using the git_verify_command_wrapper array variable that configures the appropriate OpenPGP program for git operations.

https://claude.ai/code/session_018JRiKMycfRvtpzuK59NgwP

…nt threat model

- Use git_verify_command_wrapper for submodule updates in derivative-update
  so signature verification goes through sq-git-wrapper instead of system gpg
- Activate sq-git-wrapper (was marked unused, now used for submodule verification)
- Document CI trust-root=HEAD as by-design (CI untrusted, out of threat model)
- Document non-redistributable trust-root=HEAD as by-design (developer's own checkout)
- Document TOFU threat model with link to manual verification documentation
- Document signify keys are used by dm-prepare-release in developer-meta-files

https://claude.ai/code/session_018JRiKMycfRvtpzuK59NgwP
@adrelanos adrelanos merged commit 0e1b69c into Kicksecure:master Apr 1, 2026
adrelanos pushed a commit that referenced this pull request Apr 28, 2026
Bug fixes (under set -u)
- target_architecture_pretty_name was unset when dm-tor-update-repository
  and other dm-* helpers sourced help-steps/variables with
  dist_build_one_parsed=true. Arch-derived defaults
  (target_architecture_pretty_name, BUILD_KERNEL_PKGS, BUILD_HEADER_PKGS)
  moved out of parse-cmd into variables so they always run.
- --flavor internal forwarded the literal string "internal" as
  --architecture internal to cowbuilder / mmdebstrap. Renamed the flavor
  to --flavor source (the legitimate name); "internal" removed from the
  architecture validation list.
- mmdebstrap's args_filtered string-replacement chain matched against
  dist_build_target_arch and broke on cross-arch builds. Rewritten as a
  proper token walker (mmdebstrap_filter_args) that matches by option
  name, with per-token INFO log under xtrace. The wrapper no longer
  forwards args_passthrough to mmdebstrap; it constructs the full argv
  itself so caller --architectures cannot override the wrapper's value.
- dist_build_internal_run / "internalrun" abolished, renamed to
  dist_build_source_run / "source" across the build engine. Pure rename,
  no behavior change.
- --repo false on a redistributable build now errors instead of being
  silently overridden to true. Override knob:
  dist_build_redistributable_allow_no_repo=true via env or buildconfig.d.
- dist_server_with_upload_location_list_list was unbound in the
  source-flavor path; added an empty default.

Config precedence
- help-steps/variables: precedence order now documented
  (CLI > env > buildconfig.d > default).
- The unconditional build_remote_repo_enable="true" override converted
  to a default so CLI / env / buildconfig.d can take effect.

CI workflows added
- .github/workflows/lint.yml: offline lint (yaml + shellcheck) on
  debian:trixie. Fail-not-skip on missing tooling.
- .github/workflows/dry-run.yml: ./derivative-maker --dry-run true
  --flavor source --target source on tag push.
- .github/workflows/codeql.yml: CodeQL Python static analysis (the one
  Python script in this repo). Bash is covered by shellcheck.
- .github/workflows/scorecard.yml: OpenSSF Scorecard weekly audit.
- .github/dependabot.yml: weekly bumps for github-actions and docker
  ecosystems.

Workflow hardening (every workflow)
- permissions: contents: read at top level; per-job overrides (e.g.
  security-events: write for codeql / scorecard) only when needed.
- persist-credentials: false on every actions/checkout.
- Fork-PR guard: only runs for PRs from the same repo, or for non-PR
  triggers (push / tag / cron).
- Hard timeout-minutes on every job.
- Every uses: <action>@<sha> SHA-pinned, with provenance recorded in
  agents/github-actions-security.md (re-pin procedure committed).
- Container image: lines pinned to multi-arch index digest
  (debian:trixie@sha256:35b8...). Re-pin curl one-liner committed.
- run_automated_builder.yml gated on github.repository ==
  Whonix/derivative-maker so forks do not fail at vault decrypt.
  Marked "## XXX: hardcoded".

ci/ scripts (extracted from inline workflow shell)
- ci/lint-install.sh, ci/lint-diagnostics.sh, ci/lint-yaml.sh,
  ci/lint-shellcheck.sh: lint workflow steps.
- ci/dry-run-install.sh, ci/dry-run-derivative-maker.sh: dry-run
  workflow steps.
- ci/local-checks.sh: dispatcher that runs lint-yaml + lint-shellcheck
  for one-shot local pre-commit-style coverage.
- ci/pre-commit-hook: runs lint-yaml.sh; install via
  ln -s ../../ci/pre-commit-hook .git/hooks/pre-commit
- All scripts: CI=true guard with ALLOW_LOCAL=true override; printf
  instead of echo; end-of-options on cd / cat / tar / rm / git / awk
  where supported; for file_name (not for file) so the variable does
  not shadow the file command.

Lint scope changes
- Dropped sections in ci/local-checks.sh that no longer add value:
  bash_n (subsumed by shellcheck which calls bash -n internally),
  regression (deprecated tokens dist_build_internal_run, internalrun,
  --flavor internal are all gone from the tree), actionlint (not
  packaged in Debian; trust footprint discussed in
  agents/github-actions-security.md), variables_smoke (superseded by
  the dry-run.yml workflow which exercises ./derivative-maker --dry-run
  end-to-end).

shellcheck cleanup
- The codebase is shellcheck-clean at severity=info with three
  intentional exclusions (SC2086, SC2317, SC2016) - rationales in
  ci/lint-shellcheck.sh. Real findings (SC2162 read without -r,
  genuinely missing quotes) are surfaced.

Documentation
- agents/github-actions-security.md: workflow rules + pin provenance
  table + container digest re-pin procedure + "Why no actionlint".

Misc
- end-of-options -- on pushd / cat / grep call sites in
  help-steps/* and codespell-wrapper.
- codespell-wrapper no longer hardcodes ~/derivative-maker.
- Codex review on PR #5 addressed: --flavor callers migrated,
  args_passthrough not forwarded, --architectures filtered.

https://claude.ai/code/session_01BAQS9pE9zQYieV6Uys9Reo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants