Files
gclo/SECURITY.md
james.maesandClaude Fable 5.2 1915ce2f94 docs(release): the documents say what 1.1.1 does, and the package manifests verify the file they name (#199)
Statements the release reviews of 1.1.1 found untrue at this commit, and two
gaps in the release tooling.

- Threat model: the version reviewed; an installed build contacts
  git.kof22.com for updates; the binaries are signed (the accepted risks named
  them unsigned) and T1 with the Scoop part of T2 is what is accepted; T2 and
  T11 say what ADR 0009 changed, and T11 is not marked mitigated as a whole
  while the copy to the release server is manual.
- SECURITY.md names 1.1.x as the supported line.
- README: the beta is a separate app with its own accounts; parallelism is
  under Sync options, after loading; the buttons have the names on screen; the
  app is built unpackaged, with no Developer Mode. CONTRIBUTING the same.
  docs/CLI.md shows a current version.
- RELEASING.md: the check that the server answers from outside comes before
  anything is tagged; a version that moves the updater is rehearsed with two
  prereleases read from that server; the copy to git.kof22.com is a numbered
  step; the packaging change is committed on Gitea; winget is updated by hand
  while the job would submit the GitHub URL; the engine package is numbered by
  its own public surface.
- Update-PackageManifests.ps1 downloads the file the manifests will name and
  compares its SHA-256 with that of the built file it is given, instead of
  asking only whether the URL answers; it writes the Scoop manifest with the
  repository's line endings.
- One vault test stored an entry in the credential namespace the installed
  app uses. It uses two test scopes now (#161).

Closes #183

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Signed-off-by: James Maes <james@kof22.com>
2026-11-11 06:20:47 +00:00

6.3 KiB

Security Policy

Reporting a vulnerability

Do not open a public issue for a security problem.

Report it privately through GitHub's private vulnerability reporting (the repository's Security tab, then Report a vulnerability). That is the only reporting channel; there is no security email address.

Security contact: James Maes (@KofTwentyTwo), maintainer.

Please include the affected version (Help → About gclo… in the app, or gclo --version), how to reproduce it, and the impact you see. A minimal reproduction is enormously helpful.

What to expect

gclo follows coordinated vulnerability disclosure. Timeframes are counted from the day the report arrives and come from the KofTwentyTwo security program (K22-SEC-40, K22-SEC-41):

Step Target
Acknowledge the report 7 days
Assess it: confirm or reject, with a severity 14 days
Release a fix for a CRITICAL vulnerability 7 days
Release a fix for a HIGH vulnerability 30 days
Release a fix for a MEDIUM vulnerability 90 days
Release a fix for a LOW vulnerability The next release
Publish the advisory (GitHub Security Advisory, CVE where applicable) When the fix ships, or 90 days after the report, whichever comes first

A vulnerability that is being actively exploited is announced through a security advisory within 72 hours of the maintainer becoming aware, with any available mitigation, even before a fix exists.

Reporters are credited in the advisory unless they ask not to be.

Supported versions

Version Security fixes
1.1.x (the latest release) Yes
Older No; upgrade to the latest release

Only the latest MINOR of the latest MAJOR receives fixes; a line stops receiving fixes when the next MINOR is released. When a new MAJOR is released, the previous MAJOR's last MINOR receives security fixes for 6 months. There are no maintenance branches beyond that.

Installed desktop builds update in place via Help → Check for updates; the CLI is updated by downloading the latest gclo-cli-win-x64-<version>.zip from the releases page or through Scoop.

Published vulnerabilities

Fixed vulnerabilities are published as GitHub Security Advisories with a CVE identifier, affected and fixed versions, and credit to the reporter.

How gclo handles your GitHub token

gclo works with GitHub Personal Access Tokens, so token safety is part of the design. The full picture is in the threat model.

  • Quick Sync tokens are kept in memory only. A token pasted into Quick Sync is used for the GitHub API and as the git HTTPS credential for the duration of the session, and is never written to disk, settings, or logs.
  • Saved-account tokens and the default token are persisted in the Windows Credential Manager, nowhere else. When you save an account (in the app or with gclo accounts add), or set a default token in Settings, the token is stored as a generic credential in the per-user Windows Credential Manager (DPAPI-protected, non-roaming) under a gclo:account:<id> target (gclo:<scope>:account:<id> when GCLO_DATA_DIR points the app at a non-default data directory, so an isolated data directory never sees the default profile's tokens), and removed when the account or token is deleted. It is never written to settings.json, accounts.json, or any log; those files hold only non-secret metadata. This is why accounts are Windows-only (K22-SEC-71).
  • The trust boundary of stored tokens is the Windows user account. Credential Manager protects a stored token from other users and from offline access, not from code running as the same user: any process you run can read it with CredRead, exactly as it can read your git credentials or browser cookies.
  • The app never redisplays a stored token. Editing an account shows an empty token box with a placeholder; the stored value is read only when it must be sent to GitHub. Activity-log entries about tokens record only that one was entered or replaced, and its length.
  • The CLI refuses tokens on the command line. There is deliberately no --token <value> option; tokens are accepted only via environment variable (--token-env, default GITHUB_TOKEN), a file (--token-file), or standard input (--token-stdin). See docs/CLI.md.
  • Clone in WSL hands the token to the distribution's git only through the environment (WSLENV) and an inline credential helper, never on a command line or in a file.
  • Secret-scanning push protection, gitleaks, and CodeQL run on this repository, so credentials cannot be committed and token-handling regressions are caught in CI.

If you find any code path where a token can end up in a file other than Credential Manager, in a log, in process output, on a command line, or redisplayed by the UI, that is a vulnerability: please report it through the channel above.

How releases are trusted

  • Releases are built only by the Release workflow from a tag that must be contained in main, after the full CI gates. Every published asset is listed in SHA256SUMS, carries a build-provenance attestation, and ships with a CycloneDX SBOM. See "Verifying a release" in the README.
  • Self-update downloads only from this project's releases on git.kof22.com and verifies each package against the release's releases.<channel>.json feed.
  • Setup.exe, the update stub and every gclo executable and library are Authenticode-signed with Azure Artifact Signing (SHA-256, RFC 3161 timestamp) in the release workflow, over OIDC with an identity that only this repository's release tags can use; no signing key or secret exists outside Azure. The workflow verifies the published assets with signtool verify /pa /all and fails if any shipped executable is unsigned or signed by another publisher. Check the publisher yourself with Get-AuthenticodeSignature (README, "Verifying a release").