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
30 changes: 30 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Require maintainer review for build, release, signing, and policy surfaces.
# CODEOWNERS is enforced only when branch protection requires code owner
# reviews; see docs/signing/signpath-readiness.md for the server-side status.

* @HelloThisWorld

# CI and automation
/.github/ @HelloThisWorld

# Build, packaging, installer, and release engineering
/scripts/winterm/ @HelloThisWorld
/build/ @HelloThisWorld
/packaging/ @HelloThisWorld
/custom.props @HelloThisWorld
/Directory.Build.props @HelloThisWorld
/Directory.Build.targets @HelloThisWorld

# Version, branding, and release metadata
/src/winterm/Branding/ @HelloThisWorld
/src/winterm-tools/ @HelloThisWorld

# Policies
/CODE_SIGNING_POLICY.md @HelloThisWorld
/PRIVACY.md @HelloThisWorld
/SECURITY.md @HelloThisWorld
/SUPPORT.md @HelloThisWorld
/LICENSE @HelloThisWorld
/NOTICE.md @HelloThisWorld
/THIRD_PARTY_NOTICES.md @HelloThisWorld
/docs/signing/ @HelloThisWorld
76 changes: 76 additions & 0 deletions CODE_SIGNING_POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# winTerm code signing policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

This document is the canonical winTerm code signing policy. The website copy at
<https://winterm.dev/code-signing-policy> mirrors it; if they disagree, this
repository is authoritative.

## Current signing status

The latest public release, winTerm 1.1.3, is **not Authenticode-signed**. The
SignPath Foundation certificate has not been issued for this project, and no
signed winTerm binaries exist yet. Windows may display Unknown Publisher or a
SmartScreen warning for the current Setup EXE. Verify every download against
`SHA256SUMS.txt` from the same official
[GitHub Release](https://github.com/HelloThisWorld/winTerm/releases/latest).
This section changes only after a downloaded release artifact passes
Authenticode verification.

## Roles

- Authors and committers: [HelloThisWorld](https://github.com/HelloThisWorld)
- Reviewers: [HelloThisWorld](https://github.com/HelloThisWorld)
- Approvers: [HelloThisWorld](https://github.com/HelloThisWorld)

Changes from external contributors are accepted only through pull requests
reviewed by a maintainer. Review explicitly covers source code, CI
configuration, GitHub Actions workflows, build and packaging scripts,
dependency downloads, and signing-related configuration. See
[CONTRIBUTING.md](CONTRIBUTING.md).

## Build provenance

Official winTerm releases are built from this public repository by GitHub
Actions on GitHub-hosted runners, starting from an immutable release tag that
must match `src/winterm/Branding/version.json`. Release assets are published
with SHA-256 checksums, SBOMs, and GitHub artifact attestations, and every
Draft Release asset is re-downloaded and verified before publication. See
[.github/workflows/release.yml](.github/workflows/release.yml) and
[docs/release-process.md](docs/release-process.md).

## Release signing approval

Every release signing request requires manual approval by an approver listed
above. No artifact outside the official release pipeline is signed.

## Artifact scope and ownership

winTerm is based on the Microsoft Terminal open-source codebase (pinned
baseline `release-1.25@1cea42d433253d95c4487a3037db48197b5e72f4`, see
[docs/upstream-sync.md](docs/upstream-sync.md)). For signing purposes:

- **winTerm-owned binaries** built from `src/winterm-tools` and the branded
installer (`winTerm.exe` launcher, `winterm-shim.exe`, the Inno Setup EXE)
carry `ProductName` `winTerm` and version metadata derived from
`src/winterm/Branding/version.json`.
- **Modified upstream outputs** (`WindowsTerminal.exe`, `OpenConsole.exe`,
`Microsoft.Terminal.*.dll`, and related binaries) are compiled from this
repository's source tree, which modifies Microsoft Terminal under its MIT
license.
- **Third-party redistributables** (for example `Microsoft.UI.Xaml` and
Visual C++ runtime components) come from their upstream packages and are
not signed by this project.

## Privacy

See [PRIVACY.md](PRIVACY.md). winTerm does not collect command text, terminal
output, clipboard content, Workspace contents, working-directory paths, or
usage analytics.

## Installation and removal

[docs/user/installation.md](docs/user/installation.md) documents what the
installer changes on a system; [docs/user/uninstall.md](docs/user/uninstall.md)
documents standard removal, which does not touch Microsoft Windows Terminal,
`wt.exe`, WSL, PowerShell profiles, or global fonts.
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,15 @@ Do not claim a build, package, architecture, signature, installer, or runtime te
## Pull requests

Describe scope, tests, security and privacy impact, accessibility impact, package impact, schema impact, and known limitations. Release pull requests must link the current release checklist and record signing, architecture, install, upgrade, uninstall, and coexistence status.

## External contributions and protected review areas

Every change from an external contributor is accepted only through a pull request reviewed and approved by a maintainer listed in `CODE_SIGNING_POLICY.md`. Maintainer review must explicitly cover, in addition to the code itself:

- CI configuration and every file under `.github/workflows/`;
- build, packaging, installer, and release scripts under `scripts/winterm/` and `build/`;
- anything that downloads a dependency, tool, or other build input, including pinned URLs, versions, and hashes;
- signing configuration, release metadata, and version/branding sources such as `src/winterm/Branding/`;
- the policy documents `CODE_SIGNING_POLICY.md`, `PRIVACY.md`, and `SECURITY.md`.

Changes in these areas must never be merged on the strength of passing checks alone.
4 changes: 2 additions & 2 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ winTerm does not collect general usage analytics. It does not collect or upload

## Network and optional features

- **Update checks are off.** winTerm 1.0 contains no enabled update request path because explicit user consent is not yet implemented. A future opt-in request may contain only application version, architecture, release channel, and public release metadata.
- **Update checks are off.** Current winTerm releases contain no enabled update request path because explicit user consent is not yet implemented. A future opt-in request may contain only application version, architecture, release channel, and public release metadata.
- **Crash-report upload is off by default** and remains opt-in. Local crash metadata is not uploaded unless the user explicitly chooses a reviewed, redacted report.
- **Diagnostic bundles are created only when the user requests one.** They exclude terminal output, commands, clipboard data, environment variables, SSH configuration, full settings, raw Workspace files, full paths, tokens, email addresses, and connection strings by default.

Expand All @@ -16,7 +16,7 @@ winTerm may store settings, named Workspaces, recovery snapshots, imported Theme

## User control

Diagnostic bundles are generated and shared by the user. Review a bundle before attaching it to a report. Crash upload, if introduced after 1.0, must remain disabled until the user opts in and must be independently reversible.
Diagnostic bundles are generated and shared by the user. Review a bundle before attaching it to a report. Crash upload, if introduced in a future release, must remain disabled until the user opts in and must be independently reversible.

## Removing local data

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ off and opt-in. See [PRIVACY.md](PRIVACY.md), [SECURITY.md](SECURITY.md), and

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

The canonical policy is [CODE_SIGNING_POLICY.md](CODE_SIGNING_POLICY.md).

### Roles

- Authors, committers, and reviewers:
Expand All @@ -111,10 +113,14 @@ Free code signing provided by SignPath.io, certificate by SignPath Foundation.
[HelloThisWorld](https://github.com/HelloThisWorld)

Official release artifacts are built from this public repository using
GitHub Actions.
GitHub Actions on GitHub-hosted runners, from an immutable release tag.

Every release signing request requires manual approval.

**Current status:** the latest public release is not Authenticode-signed; no
SignPath certificate has been issued yet. See
[CODE_SIGNING_POLICY.md](CODE_SIGNING_POLICY.md) for the authoritative status.

See [PRIVACY.md](PRIVACY.md) for the winTerm privacy policy.

## License and upstream
Expand Down
4 changes: 2 additions & 2 deletions SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

## Supported releases

The latest public Stable winTerm release is supported. A prerelease is supported for testing and feedback only. winTerm 1.0.2 is the current Stable release.
The latest public Stable winTerm release is supported. A prerelease is supported for testing and feedback only. The current Stable release is always the version published at the [latest official Release](https://github.com/HelloThisWorld/winTerm/releases/latest).

## Platforms and architectures

- Windows 11 x64 is the intended fully supported platform after clean installation, upgrade, uninstall, and runtime validation pass.
- Windows 11 ARM64 is unsupported unless an ARM64 asset is actually published with native build, install, and launch evidence.
- Windows 10 is unsupported for the winTerm 1.0 Stable commitment.
- Windows 10 is unsupported for the winTerm Stable commitment.

## Shells and feature levels

Expand Down
5 changes: 5 additions & 0 deletions docs/releases/1.1.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,8 @@ Publisher: `helloThisWorld`. Tag: `v1.1.3`.
The v1.1.3 Setup EXE is not Authenticode-signed. Windows may display Unknown
Publisher or a SmartScreen warning. Download only from the official GitHub
Release and verify the file against `SHA256SUMS.txt` before running it.

## Policies

- [Code signing policy](https://github.com/HelloThisWorld/winTerm/blob/main/CODE_SIGNING_POLICY.md)
- [Privacy policy](https://github.com/HelloThisWorld/winTerm/blob/main/PRIVACY.md)
108 changes: 108 additions & 0 deletions docs/signing/signpath-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# SignPath Foundation readiness

Status of the winTerm application for free OSS code signing from SignPath
Foundation, audited 2026-07-28 against <https://signpath.org/terms.html>,
<https://signpath.org/apply>,
<https://docs.signpath.io/trusted-build-systems/github>, and
<https://docs.signpath.io/origin-verification/>.

The latest public release is winTerm 1.1.3 (`v1.1.3`,
`winTerm-1.1.3-setup-x64.exe`, `winTerm-1.1.3-portable-x64.zip`,
`SHA256SUMS.txt`, SBOMs, `release-metadata.json`, GitHub attestations). The
Setup EXE is **not Authenticode-signed**.

## Completed in this repository

- Canonical [CODE_SIGNING_POLICY.md](../../CODE_SIGNING_POLICY.md) with the
exact SignPath attribution sentence, roles (Authors/Committers, Reviewers,
Approvers), manual-approval statement, build provenance, artifact
ownership boundaries, and the honest current unsigned status.
- README `Code signing policy` section visible on the repository homepage,
linking the canonical policy and stating the current unsigned status.
- [CONTRIBUTING.md](../../CONTRIBUTING.md) explicit external-contribution
review policy covering CI, workflows, build/packaging scripts, dependency
downloads, and signing configuration.
- [.github/CODEOWNERS](../../.github/CODEOWNERS) covering workflows, release
scripts, packaging, version/branding metadata, and policy documents.
- [PRIVACY.md](../../PRIVACY.md) version-neutral wording; validated by
`scripts/winterm/test-privacy.ps1` (no analytics, no update requests, crash
upload off/opt-in, diagnostics user-initiated, uninstall data behavior).
- Release workflow ([.github/workflows/release.yml](../../.github/workflows/release.yml))
builds from an immutable tag that must match
`src/winterm/Branding/version.json`, exclusively on GitHub-hosted
runners, with a pinned and signature-verified Inno Setup toolchain, an
exact release-asset allowlist, SHA-256 checksums, SPDX + CycloneDX SBOMs,
GitHub artifact attestations, and re-download verification before and
after publication.
- `winterm-shim.rc` version resources aligned with the canonical version
metadata (1.1.3), and `scripts/winterm/verify-version.ps1` now fails on any
future `winTerm.exe`/`winterm-shim.exe` version-resource drift.
- `scripts/winterm/generate-release-artifacts.ps1` no longer duplicates the
Signing section (the guard now recognizes "not Authenticode-signed") and
ensures every future Release body links the Code signing policy and the
Privacy policy.
- Release notes source `docs/releases/1.1.3.md` carries the Signing section
and policy links.
- Website <https://winterm.dev> (separate `winterm-site` repository):
`Code signing policy` link on the homepage download area and footer, the
policy page with the exact attribution sentence, roles, manual approval,
current unsigned status, and privacy/installation/uninstall links.

## Verified externally (rechecked 2026-07-28)

- Latest public Release `v1.1.3` exists with the expected asset list and is
explicitly unsigned in its notes.
- The published v1.1.3 Release body currently duplicates the Signing
section; a corrected body (single Signing section plus policy links) is
applied from `docs/releases/1.1.3.md` without touching the tag or assets.
- Repository metadata: `HelloThisWorld/winTerm` is public, MIT-licensed, and
**not** marked as a GitHub fork (see Blocked).

## Known gaps in already-published artifacts

- The binaries inside the published v1.1.3 packages predate the shim
version-resource fix: `winTerm.exe` and `winterm-shim.exe` report
ProductVersion 1.0.0 / FileVersion 1.0.8.0, while `WindowsTerminal.exe`
correctly reports 1.1.3. Published release assets are immutable and are
not replaced; the next release will carry consistent metadata enforced by
`verify-version.ps1`.
- `OpenConsole.exe` and `elevate-shim.exe` are upstream-derived binaries
built without version resources. Decide before configuring SignPath
artifacts whether they are in signing scope; if so, they need version
resources in a future release.

## Manual prerequisites (cannot be completed from this repository)

- GitHub account MFA enabled for `HelloThisWorld`.
- SignPath account creation and MFA enabled.
- Submitting the SignPath Foundation application.
- Installing the SignPath GitHub App and granting it repository access.
- SignPath-side organization, project, artifact configuration, and signing
policies; configuring the manual approver.
- `SIGNPATH_API_TOKEN` (or equivalent) as a repository secret. Do not add
placeholder IDs, slugs, or tokens to workflows before the SignPath
configuration exists; the release workflow must keep succeeding unsigned
until then.
- GitHub server-side branch protection / rulesets requiring code-owner
review for the protected paths in `.github/CODEOWNERS`.
- After certificate issuance: integrate the SignPath step into
`release.yml` (artifacts uploaded via `actions/upload-artifact` before the
signing request), then re-verify Authenticode signature, product/version
metadata, hashes, and install/uninstall on the signed outputs before
publication.

## Blocked / needs SignPath confirmation

- **Upstream fork visibility (high priority).** winTerm is modified
Microsoft Terminal (pinned baseline
`release-1.25@1cea42d433253d95c4487a3037db48197b5e72f4`, integration
process in [docs/upstream-sync.md](../upstream-sync.md)), but the GitHub
repository is not a GitHub-visible fork of `microsoft/terminal`
(`fork: false`, no parent). SignPath's modified-upstream terms expect the
project to "visibly fork" upstream. Recreating the repository as a GitHub
fork or rewriting history is intentionally out of scope. Next step for the
maintainer: ask SignPath whether the pinned-baseline provenance documented
here and in `upstream-sync.md` satisfies the requirement, or whether a
visible-fork migration is required before approval.
- SignPath Foundation's subjective review of project reputation and
popularity.
30 changes: 25 additions & 5 deletions scripts/winterm/generate-release-artifacts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,34 @@ function Ensure-ReleaseNotesSigningDisclosure
)

$notes = Get-Content -LiteralPath $Path -Raw
if ($Status -eq 'unsigned' -and $notes -notmatch '(?i)unsigned|not code-signed')
$additions = @()

# "unsigned", "not code-signed", and "not Authenticode-signed" all count as
# an existing disclosure; a narrower match here previously duplicated the
# Signing section on the published Release.
if ($Status -eq 'unsigned' -and $notes -notmatch '(?i)\bunsigned\b|not\s+(?:code|authenticode)[-\s]signed')
{
$disclosure = @(
$additions += @(
'## Signing'
''
'The Setup EXE is not code-signed. Windows may display a SmartScreen warning; verify the downloaded file against `SHA256SUMS.txt` before running it.'
) -join [Environment]::NewLine
$updatedNotes = $notes.TrimEnd() + [Environment]::NewLine + [Environment]::NewLine + $disclosure + [Environment]::NewLine
'The Setup EXE is not Authenticode-signed. Windows may display Unknown Publisher or a SmartScreen warning; verify the downloaded file against `SHA256SUMS.txt` before running it.'
)
}

if ($notes -notmatch '(?i)code signing policy')
{
if ($additions.Count -gt 0) { $additions += '' }
$additions += @(
'## Policies'
''
'- [Code signing policy](https://github.com/HelloThisWorld/winTerm/blob/main/CODE_SIGNING_POLICY.md)'
'- [Privacy policy](https://github.com/HelloThisWorld/winTerm/blob/main/PRIVACY.md)'
)
}

if ($additions.Count -gt 0)
{
$updatedNotes = $notes.TrimEnd() + [Environment]::NewLine + [Environment]::NewLine + ($additions -join [Environment]::NewLine) + [Environment]::NewLine
[IO.File]::WriteAllText($Path, $updatedNotes, [Text.UTF8Encoding]::new($false))
}

Expand Down
6 changes: 4 additions & 2 deletions scripts/winterm/test-release-workflow.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ try
}
foreach ($required in @(
'Ensure-ReleaseNotesSigningDisclosure',
'The Setup EXE is not code-signed.',
'SHA256SUMS.txt'
'The Setup EXE is not Authenticode-signed.',
'SHA256SUMS.txt',
'Code signing policy',
'Privacy policy'
))
{
if (-not $releaseGenerator.Contains($required))
Expand Down
7 changes: 7 additions & 0 deletions scripts/winterm/verify-version.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ try
Assert-Condition ($hostResource.Contains("`"FileVersion`", `"$($version.packageVersion)\0`"")) 'Terminal host display file version matches release metadata'
Assert-Condition ($hostResource.Contains("`"ProductVersion`", `"$($version.applicationVersion)\0`"")) 'Terminal host display product version matches release metadata'

$shimResource = Get-Text 'src\winterm-tools\winterm-shim\winterm-shim.rc'
Assert-Condition ($shimResource.Contains("FILEVERSION $packageVersionTuple")) 'Shim launcher file version matches release metadata'
Assert-Condition ($shimResource.Contains("PRODUCTVERSION $packageVersionTuple")) 'Shim launcher numeric product version matches release metadata'
Assert-Condition ($shimResource.Contains("`"FileVersion`", `"$($version.packageVersion)\0`"")) 'Shim launcher display file version matches release metadata'
Assert-Condition ($shimResource.Contains("`"ProductVersion`", `"$($version.applicationVersion)\0`"")) 'Shim launcher display product version matches release metadata'
Assert-Condition ($shimResource.Contains('"ProductName", "winTerm\0"')) 'Shim launcher product name is winTerm'

Assert-Condition ((Get-Text 'src\winterm\Workspaces\Model\WorkspaceDescriptor.h').Contains('WorkspaceSchemaVersion{ 2 }')) 'Workspace model remains at Schema version 2'
Assert-Condition ((Get-Text 'src\winterm\Workspaces\Model\WorkspaceDescriptor.h').Contains('DockingModelVersion{ 1 }')) 'Workspace model remains at Docking version 1'
Assert-Condition ((Get-Text 'src\winterm\Shell\Protocol\ShellIntegrationProtocol.h').Contains('ShellProtocolVersion{ 1 }')) 'Shell protocol remains at version 1'
Expand Down
Loading