@wenathlan/saddle 1.8.10 → 1.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +646 -175
- package/README.md +12 -4
- package/dist/apps/registry.d.ts +1 -1
- package/dist/browser/recorder.d.ts +7 -13
- package/dist/browser/recorder.d.ts.map +1 -1
- package/dist/browser/recorder.js +42 -6
- package/dist/browser/recorder.js.map +1 -1
- package/dist/extension/build.d.ts.map +1 -1
- package/dist/extension/build.js +27 -3
- package/dist/extension/build.js.map +1 -1
- package/dist/extension/permissions.d.ts +2 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/engine.d.ts +10 -0
- package/dist/memory/engine.d.ts.map +1 -1
- package/dist/memory/engine.js +57 -7
- package/dist/memory/engine.js.map +1 -1
- package/dist/modes/resolve.d.ts +55 -0
- package/dist/modes/resolve.d.ts.map +1 -1
- package/dist/modes/resolve.js +9 -0
- package/dist/modes/resolve.js.map +1 -1
- package/dist/packager/manifest.d.ts +15 -0
- package/dist/packager/manifest.d.ts.map +1 -1
- package/dist/packager/manifest.js +36 -0
- package/dist/packager/manifest.js.map +1 -1
- package/dist/release/verify.d.ts +12 -0
- package/dist/release/verify.d.ts.map +1 -0
- package/dist/release/verify.js +112 -0
- package/dist/release/verify.js.map +1 -0
- package/dist/scrape/robots.js +1 -1
- package/dist/storage/s3compatible.d.ts +1 -0
- package/dist/storage/s3compatible.d.ts.map +1 -1
- package/dist/storage/s3compatible.js +43 -4
- package/dist/storage/s3compatible.js.map +1 -1
- package/dist/workflow/manifest.d.ts +1 -0
- package/dist/workflow/manifest.d.ts.map +1 -1
- package/dist/workflow/manifest.js +1 -0
- package/dist/workflow/manifest.js.map +1 -1
- package/dist/workflow/triggers.d.ts +28 -0
- package/dist/workflow/triggers.d.ts.map +1 -1
- package/dist/workflow/triggers.js +67 -1
- package/dist/workflow/triggers.js.map +1 -1
- package/docs/actionrecorder.md +12 -0
- package/docs/artifactavailability.md +60 -0
- package/docs/batches-1816-1820.md +13 -0
- package/docs/capabilityreport.md +13 -0
- package/docs/documentmap-1.8.12.md +17 -0
- package/docs/flatbuildresearch-1.8.11.md +29 -0
- package/docs/licenseaudit-1.8.12.md +21 -0
- package/docs/memoryengine.md +21 -0
- package/docs/nativeidentityresearch-1.8.11.md +69 -0
- package/docs/releaseassets.md +6 -2
- package/docs/s3compatible.md +12 -0
- package/docs/scanningresearch-1.8.11.md +17 -0
- package/docs/securityreferences-1.8.11.md +10 -0
- package/docs/securityresearch-1.8.11.md +19 -0
- package/docs/signingresearch-1.8.12.md +167 -0
- package/docs/signingwithoutcertificates.md +54 -0
- package/docs/signpathapplication.md +11 -0
- package/docs/sitemap.md +14 -0
- package/docs/tauri-glib-risk-1.8.11.md +11 -0
- package/docs/workflowinputs.md +17 -0
- package/extension/manifest.json +15 -2
- package/package.json +4 -1
- package/license.md +0 -203
- package/license.txt +0 -203
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Capability report
|
|
2
|
+
|
|
3
|
+
The `capabilityreport` contract produces a stable, serializable view of the execution, runtime, memory, file, dependency, visibility and pairing axes. It resolves every execution mode with caller-selected overrides and exposes the effective boolean capabilities for diagnostics, documentation and adapters.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const report = capabilityreport({
|
|
7
|
+
runtime: "unknown",
|
|
8
|
+
memory: "external",
|
|
9
|
+
pair: "with",
|
|
10
|
+
});
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The report explicitly labels host, port, credentials and provider as caller-owned. It does not start a process, open a socket, select a cloud service or promise that every target has an installed toolchain. It describes the library contract and preserves user choice across browser, desktop, mobile, CLI, binary and application modes.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Document map for 1.8.12
|
|
2
|
+
|
|
3
|
+
## Canonical root documents
|
|
4
|
+
|
|
5
|
+
Project policies, notices and contribution guidance remain at the repository root so package consumers and forge interfaces can discover them without entering `docs`. The canonical license is the extensionless `LICENSE` file containing the official unmodified GNU GPL v3.0 text. Human-readable project policies use one Markdown file per context: `acceptable-use-policy.md`, `authors.md`, `bug-report.md`, `cla.md`, `code-of-conduct.md`, `contributing.md`, `copyright.md`, `disclaimer.md`, `eula.md`, `export-control.md`, `governance.md`, `notice.md`, `privacy-policy.md`, `pull-request-template.md`, `security.md`, `support.md`, `terms-and-conditions.md`, `terms-of-use.md`, `third-party-notices.md` and `trademark-policy.md`.
|
|
6
|
+
|
|
7
|
+
The public scope README remains `/home/ubuntu/upload/README.md` and was not modified. The repository's own `README.md` remains a public project document and can receive release or signing-policy updates separately from the immutable scope reference.
|
|
8
|
+
|
|
9
|
+
## Removed exact duplicates
|
|
10
|
+
|
|
11
|
+
The following root `.txt` files were byte-identical copies of their Markdown counterparts and were removed: `authors.txt`, `code-of-conduct.txt`, `contributing.txt`, `copyright.txt`, `disclaimer.txt`, `notice.txt`, `privacy-policy.txt`, `security.txt`, `terms-and-conditions.txt`, `terms-of-use.txt` and `trademark-policy.txt`. The old `license.md` and `license.txt` were also removed because they duplicated a now-canonical root license context while carrying the obsolete proprietary view-only text.
|
|
12
|
+
|
|
13
|
+
The README files under `docs/plans` and `docs/talks9` were not treated as root policy duplicates. They preserve plan or conversation context and are intentionally outside the root legal-document set.
|
|
14
|
+
|
|
15
|
+
## Policy rule
|
|
16
|
+
|
|
17
|
+
A policy document may describe repository operations, hosted-service behavior, privacy, security, trademarks or community conduct, but it must not revoke rights granted by GPL-3.0-only. Third-party component licenses remain separate and are recorded through package manifests, lockfiles and release inventories.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Flat native build research for Saddle 1.8.11
|
|
2
|
+
|
|
3
|
+
The 1.8.11 migration follows the repository rule that project-owned code stays at the surface root and that generated `dist/` output is excluded from version control. The migration does not delete toolchain-owned files blindly: it separates Saddle-owned entrypoints from generated platform staging and verifies each build after the path change.
|
|
4
|
+
|
|
5
|
+
## Tauri desktop
|
|
6
|
+
|
|
7
|
+
The official Tauri project structure normally places the Rust project under `src-tauri/`, and the configuration file acts as a marker for the CLI to locate the Rust project [1]. Tauri also supports configuration extension through `--config`, but that feature merges configuration and does not itself guarantee a different Rust project directory [2]. The 1.8.11 implementation therefore tests the more direct layout: `desktop/tauri.conf.json`, `desktop/Cargo.toml`, `desktop/build.rs`, `desktop/lib.rs` and `desktop/main.rs`. The workflow invokes the CLI from `desktop/` so the configuration and Cargo manifest share one flat surface root.
|
|
8
|
+
|
|
9
|
+
The frontend remains outside the native surface at `web/dist/public`. The path is relative to `desktop/tauri.conf.json`, and the generated `dist/` directory stays ignored. Desktop `target/`, icon outputs and bundle staging also remain generated and are never release inputs unless they match the explicit artifact collector patterns.
|
|
10
|
+
|
|
11
|
+
## Android Capacitor
|
|
12
|
+
|
|
13
|
+
Android Gradle supports custom source directories through the module-level `sourceSets` block. The official Android guidance allows `java.srcDirs`, `res.srcDirs` and `manifest.srcFile` to point to project-defined paths outside the conventional `src/main` tree [3]. The 1.8.11 layout uses this capability for Saddle-owned files: `android/main/` for the activity host, `android/res/` for resources, `android/AndroidManifest.xml` for the manifest and root-level test directories where practical.
|
|
14
|
+
|
|
15
|
+
Capacitor 8 still generates its web staging, plugin metadata and Cordova bridge under its conventional Android project paths during `cap sync`. Those generated paths are toolchain-owned, ignored by Git and not treated as Saddle source. A validation step rejects tracked `android/app/src` project files while allowing the transient CI staging created by Capacitor. This keeps the repository flat without breaking the generator contract.
|
|
16
|
+
|
|
17
|
+
## iOS Capacitor
|
|
18
|
+
|
|
19
|
+
Capacitor generates an Xcode project, Swift Package Manager bridge and copied web resources. The generated `CapApp-SPM` package explicitly identifies itself as CLI-managed. The 1.8.11 migration therefore keeps the Xcode project and Capacitor-managed package paths as generated platform internals while ensuring Saddle-owned metadata, workflow configuration and documentation live at the `ios/` root. Flattening the internal Xcode group hierarchy would require abandoning the generated Capacitor project and would reduce reproducibility rather than improve it.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
The flat rule applies strictly to project-owned files. Desktop becomes fully flat at `desktop/`. Android moves the Saddle-owned activity, manifest, resources and tests to root-level paths and maps them through Gradle `sourceSets`; transient Capacitor files remain ignored. iOS keeps generator-owned Xcode internals but exposes a flat root contract and does not add a project-owned `src` directory. All workflows use release-tag version derivation and contain no credentials or fixed infrastructure endpoints.
|
|
24
|
+
|
|
25
|
+
## References
|
|
26
|
+
|
|
27
|
+
[1]: https://v2.tauri.app/start/project-structure/ "Tauri project structure"
|
|
28
|
+
[2]: https://v2.tauri.app/develop/configuration-files/ "Tauri configuration files"
|
|
29
|
+
[3]: https://developer.android.com/build/gradle-tips "Android Gradle tips and source set configuration"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# License audit for 1.8.12
|
|
2
|
+
|
|
3
|
+
## Current repository state
|
|
4
|
+
|
|
5
|
+
The repository contains three project license copies: `LICENSE`, `license.md` and `license.txt`. All three describe a custom Proprietary Source-Available License, View Only. They explicitly state that the software is not open source and prohibit copying, execution, modification, distribution and internal business use without written permission. `license.md` and `license.txt` contain minor author and link differences from `LICENSE`.
|
|
6
|
+
|
|
7
|
+
The package manifests do not match those documents. `package.json` declares `GPL-3.0-only`, `pom.xml` declares GNU GPL v3.0, `saddle.csproj` declares `GPL-3.0-only`, and `saddle.gemspec` declares `GPL-3.0`. This is a material licensing contradiction that must be resolved before a new release is tagged.
|
|
8
|
+
|
|
9
|
+
## Verified policy distinction
|
|
10
|
+
|
|
11
|
+
The Open Source Initiative requires an open source license to allow free redistribution, source distribution, derived works, and use in any field of endeavor, including business use [1]. The GNU GPL v3 grants permission to run and modify covered works and allows private works that are not conveyed without additional conditions; distribution activates the license obligations [2].
|
|
12
|
+
|
|
13
|
+
Therefore, “open source but only for our private use” is not one coherent license policy. A private or internal deployment is compatible with GPL use, but a license that prohibits other people from using, copying, modifying or distributing the software is source-available/proprietary, not OSI open source. The repository must choose one policy and express it consistently across the three license files, manifests, package metadata, README references and provider applications.
|
|
14
|
+
|
|
15
|
+
SignPath Foundation requires an OSI-approved open source license without commercial dual licensing for all components. It also requires active maintenance, an existing release, documented functionality, a public code-signing policy, verifiable builds and manual approval for every signed release [3]. The current view-only license would therefore be incompatible with the free SignPath Foundation route until the repository adopts and consistently declares an OSI-approved license.
|
|
16
|
+
|
|
17
|
+
## References
|
|
18
|
+
|
|
19
|
+
[1]: https://opensource.org/osd "Open Source Initiative: The Open Source Definition"
|
|
20
|
+
[2]: https://www.gnu.org/licenses/gpl-3.0.html "Free Software Foundation: GNU General Public License version 3"
|
|
21
|
+
[3]: https://signpath.org/terms.html "SignPath Foundation: Conditions for Open Source projects"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Memory engine
|
|
2
|
+
|
|
3
|
+
The `memoryengine` contract keeps a hot working set in process memory while using caller-owned storage backends as the durable side of the bridge. With no limits, the engine preserves its historical behavior. With `maxentries` or `maxbytes`, it evicts the least recently used object after a load or persist operation exceeds the selected bound.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { memoryengine } from "@wenathlan/saddle";
|
|
7
|
+
|
|
8
|
+
const memory = memoryengine({
|
|
9
|
+
backends: [storage],
|
|
10
|
+
maxentries: 128,
|
|
11
|
+
maxbytes: 64 * 1024 * 1024,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
await memory.persist("job-output", payload, { mimetype: "application/json" });
|
|
15
|
+
const object = await memory.load("job-output");
|
|
16
|
+
console.log(memory.stats());
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Eviction affects only the hot in-process cache. The engine persists data to every configured backend before updating the cache, and a later load can rehydrate an evicted object from the first backend that returns it. `stats()` reports entries, bytes, cache hits, cache misses, evictions and configured limits so a caller can tune the working set without treating storage as physical RAM.
|
|
20
|
+
|
|
21
|
+
The limits are optional non-negative integers. A payload larger than `maxbytes` remains persisted but is not retained in the hot cache. The engine does not create a host, port, credential, storage account or provider binding on behalf of the caller.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Saddle native identity research
|
|
2
|
+
|
|
3
|
+
## OpenCode comparison
|
|
4
|
+
|
|
5
|
+
The public OpenCode repository documents a desktop distribution alongside its CLI and package-manager routes. Its documented desktop matrix includes macOS Apple Silicon and Intel DMG installers, a Windows x64 executable, and Linux DEB, RPM and AppImage outputs. The comparison supports explicit platform and architecture naming in Saddle release assets, but it does not justify copying OpenCode branding, icons or implementation.
|
|
6
|
+
|
|
7
|
+
Source: [OpenCode repository and README](https://github.com/anomalyco/opencode)
|
|
8
|
+
|
|
9
|
+
## ZCode comparison
|
|
10
|
+
|
|
11
|
+
The public ZCode installation guide presents separate downloads for macOS Apple Silicon, macOS Intel, Windows x64, Windows ARM64 and Linux x64. Its Linux guidance uses an AppImage, while macOS uses a DMG to install an `.app` bundle and Windows uses an installer. This supports adding architecture-aware artifact labels and an explicit `.app` packaging path where the Apple runner supports it.
|
|
12
|
+
|
|
13
|
+
Source: [ZCode official installation guide](https://zcode.z.ai/en/docs/install)
|
|
14
|
+
|
|
15
|
+
## Saddle decisions
|
|
16
|
+
|
|
17
|
+
Saddle keeps one shared TypeScript library-first engine and uses flat, surface-owned build roots. The release matrix should distinguish architecture from package format, for example `saddle.browser.1.8.11.windows.x64.exe` and `saddle.browser.1.8.11.windows.arm64.exe`, instead of hiding architecture in a generic filename. The workflow must publish only artifacts actually built by the runner and must not claim a valid signature when signing credentials are absent.
|
|
18
|
+
|
|
19
|
+
Windows Authenticode, macOS Developer ID signing and notarization, Android release signing, and Apple provisioning remain caller-owned secret contracts. Public workflows can validate certificate presence, signer identity, timestamping and notarization status without embedding keys or manufacturing trust signals.
|
|
20
|
+
|
|
21
|
+
## Official signing constraints
|
|
22
|
+
|
|
23
|
+
Microsoft documents that Smart App Control accepts RSA-based code-signing certificates and does not currently support ECC signatures for this check. Trusted Signing is the preferred Microsoft route, while `signtool.exe` remains the command-line path for certificate-backed signing. An unsigned or locally signed binary cannot honestly be presented as trusted by the Saddle workflow.
|
|
24
|
+
|
|
25
|
+
Apple documents that macOS software distributed with Developer ID must be notarized, and that notarization scans for malicious components and code-signing issues. A production workflow therefore needs Developer ID signing, hardened runtime, a secure timestamp, notarization through `notarytool` or an equivalent service, and ticket stapling before the artifact is labeled notarized.
|
|
26
|
+
|
|
27
|
+
Sources: [Microsoft Smart App Control code signing](https://learn.microsoft.com/en-us/windows/apps/develop/smart-app-control/code-signing-for-smart-app-control) and [Apple notarizing macOS software](https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution).
|
|
28
|
+
|
|
29
|
+
## Windows without a private certificate
|
|
30
|
+
|
|
31
|
+
Microsoft's current comparison states that an MSIX package submitted through the Microsoft Store is re-signed by Microsoft at no certificate cost to the publisher. The same free treatment does not apply to an MSI or EXE submitted through the Store: those installers must already chain to a certificate trusted by Microsoft's root program. For direct distribution, Microsoft lists Azure Artifact Signing, traditional OV certificates, self-signed certificates and unsigned binaries as different trust levels; self-signed and unsigned outputs are for development or testing, not public trust. The page also identifies the SignPath Foundation as an open-source route worth evaluating rather than pretending that a generated self-signed key removes SmartScreen warnings.
|
|
32
|
+
|
|
33
|
+
Source: [Microsoft code signing options for Windows app developers](https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/code-signing-options).
|
|
34
|
+
|
|
35
|
+
## Apple distribution without an owned certificate
|
|
36
|
+
|
|
37
|
+
Apple's Developer ID guidance states that Gatekeeper checks for a Developer ID certificate when software is distributed outside the Mac App Store. The Developer ID certificate is generated from an Apple Developer account by the Account Holder, and notarization scans Developer ID-signed software before Apple issues the ticket used by Gatekeeper. There is no public framework that manufactures an Apple-trusted Developer ID certificate for an unrelated project. An open-source project must either distribute through the Mac App Store, use an authorized organization account, or publish an unsigned/test artifact with an explicit warning.
|
|
38
|
+
|
|
39
|
+
Source: [Apple Developer ID signing and notarization](https://developer.apple.com/developer-id/).
|
|
40
|
+
|
|
41
|
+
## Android distribution without owning the Play signing key
|
|
42
|
+
|
|
43
|
+
Android still requires every installable APK to be digitally signed. Google Play App Signing changes who protects the production app-signing key: the publisher keeps an upload key, while Google signs the distributed APKs. This helps an open-source project avoid operating the final Play signing key, but it does not remove the need for a Play Console account, an upload key and a release identity. Direct APK distribution outside Google Play still requires Saddle to sign the APK itself.
|
|
44
|
+
|
|
45
|
+
Source: [Android app signing and Play App Signing](https://developer.android.com/studio/publish/app-signing).
|
|
46
|
+
|
|
47
|
+
## Open-source Windows certificate route
|
|
48
|
+
|
|
49
|
+
The SignPath Foundation states that it can provide code-signing certificates for eligible open-source projects, keeps the private key in its hardware security module and verifies that the binary came from the project's public repository. This is a real external approval program, not a library that generates a universally trusted certificate locally. Saddle can apply to the program, but the workflow must remain disabled or unsigned until the project is accepted and the provider-specific integration is configured.
|
|
50
|
+
|
|
51
|
+
Source: [SignPath Foundation](https://signpath.org/).
|
|
52
|
+
|
|
53
|
+
## What the OpenCode workflow actually does
|
|
54
|
+
|
|
55
|
+
The public OpenCode publish workflow invokes `azure/artifact-signing-action` with an Azure Trusted Signing endpoint, account name and certificate profile. This explains how a visible open-source project can distribute signed Windows binaries: the project has access to an external signing service and repository or organization secrets. It is not evidence that OpenCode generates a universally trusted certificate from source code. Saddle can follow the same pattern after an Azure Artifact Signing or SignPath application is approved, but must keep its unsigned mode until then.
|
|
56
|
+
|
|
57
|
+
Source: [OpenCode publish workflow](https://raw.githubusercontent.com/anomalyco/opencode/dev/.github/workflows/publish.yml).
|
|
58
|
+
|
|
59
|
+
## What the Zed workflow demonstrates
|
|
60
|
+
|
|
61
|
+
The public Zed post-release workflow focuses on refreshing release pages, publishing a WinGet manifest and deploying documentation. It references organization secrets for those integrations and does not expose a locally generated signing certificate. This is consistent with the broader pattern: open-source projects can publish broadly, but platform trust comes from a store, a managed signing provider or a certificate held by the project organization.
|
|
62
|
+
|
|
63
|
+
Source: [Zed post-release workflow](https://raw.githubusercontent.com/zed-industries/zed/main/.github/workflows/after_release.yml).
|
|
64
|
+
|
|
65
|
+
## Safe GitHub Actions secret handling
|
|
66
|
+
|
|
67
|
+
GitHub's documentation says repository or environment secrets are created from the repository Settings page and injected through the `secrets` context. Secrets are not passed to fork-triggered workflows or Dependabot events, and GitHub recommends OIDC for cloud providers that support it so long-lived credentials can be avoided. Saddle must therefore configure signing only on trusted release events, never expose values in command arguments or logs, and keep manual test keys separate from production signing credentials.
|
|
68
|
+
|
|
69
|
+
Source: [Using secrets in GitHub Actions](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets).
|
package/docs/releaseassets.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Release assets
|
|
2
2
|
|
|
3
|
-
The Node-only release adapter creates deterministic metadata for caller-selected artifacts. For version `1.8.
|
|
3
|
+
The Node-only release adapter creates deterministic metadata for caller-selected artifacts. For version `1.8.12`, it writes dotted surface-specific names such as `sha256.desktop.1.8.12`, `manifest.desktop.1.8.12.json`, `sbom.desktop.1.8.12.cdx.json` and `provenance.desktop.1.8.12.intoto.jsonl`. The adapter rejects underscore-based public names and Rust build-helper executables. It never publishes, authenticates or selects a registry.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm run release:assets -- \
|
|
7
|
-
--version 1.8.
|
|
7
|
+
--version 1.8.12 \
|
|
8
8
|
--surface desktop \
|
|
9
9
|
--output build/release \
|
|
10
10
|
--artifact build/saddle.tgz \
|
|
@@ -15,3 +15,7 @@ npm run release:assets -- \
|
|
|
15
15
|
The artifact paths are supplied by the caller and are sorted before the checksum, manifest, SBOM and provenance files are written. Package dependencies are read from the root lockfile to build a compact component list. The output can be attached to a release or checked by a registry-specific workflow without adding credentials to the library.
|
|
16
16
|
|
|
17
17
|
The package also exports the adapter as `@wenathlan/saddle/release-assets`. It is intentionally Node-only because release metadata reads files and uses the Node crypto implementation; the transport-neutral root remains free of Node imports.
|
|
18
|
+
|
|
19
|
+
## Release matrix
|
|
20
|
+
|
|
21
|
+
The `releaseartifactmatrix(version, options)` contract in `packager/manifest.ts` describes the supported desktop, Android, iOS, container and browser-extension outputs in one deterministic structure. Each entry includes platform, architecture, dotted artifact names, checksum name, manifest name and the actual signing label supplied by the caller. It is descriptive only: it does not invoke a vendor toolchain, select a registry or imply that a platform trusts an unsigned artifact.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# S3-compatible storage listing
|
|
2
|
+
|
|
3
|
+
The `s3compatible` adapter accepts a caller-owned signer and now implements the S3 ListObjectsV2 contract in addition to put, get, head and delete. `list(prefix, options)` sends the `list-type=2` query, preserves the caller's prefix, follows continuation tokens and stops at a bounded page count.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const objects = await storage.list("runs/", {
|
|
7
|
+
maxkeys: 1000,
|
|
8
|
+
maxpages: 20,
|
|
9
|
+
});
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Each returned object follows the storage adapter shape with `key`, `sizebytes`, `sha256` from the provider ETag when present, content type, creation time and provider metadata. XML entities are decoded before keys are returned. The adapter rejects a non-advancing continuation token and never creates credentials or chooses an endpoint on behalf of the caller.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Saddle 1.8.11 scanning research
|
|
2
|
+
|
|
3
|
+
## OSV Scanner
|
|
4
|
+
|
|
5
|
+
The official OSV Scanner GitHub Action documents separate pull request and full scheduled scans. The full reusable workflow can run on pushes, schedules and releases, upload SARIF to GitHub code scanning, and fail when a vulnerability is found. The action requires `actions: read`, `contents: read` and `security-events: write` permissions for SARIF reporting.
|
|
6
|
+
|
|
7
|
+
Source: [OSV Scanner GitHub Action](https://google.github.io/osv-scanner/github-action/)
|
|
8
|
+
|
|
9
|
+
## Cargo audit
|
|
10
|
+
|
|
11
|
+
The official RustSec `cargo audit` documentation states that the tool audits dependencies for advisories in the RustSec database, operates on the top level Cargo project and requires Rust 1.74 or later. The Saddle workflow must run it against the resolved desktop `Cargo.lock`, keep any ignore entry narrowly justified, and prefer upgrading the vulnerable crate over suppressing the advisory.
|
|
12
|
+
|
|
13
|
+
Source: [RustSec cargo audit README](https://github.com/rustsec/rustsec/blob/main/cargo-audit/README.md)
|
|
14
|
+
|
|
15
|
+
## Pipeline decision
|
|
16
|
+
|
|
17
|
+
Saddle should combine CodeQL for source and workflow analysis, OSV Scanner for multi ecosystem dependency intelligence and SARIF, `cargo audit` for RustSec coverage, npm audit for Node lockfiles, dependency review on pull requests, secret scanning, SBOM generation and artifact level checks. The pipeline should distinguish existing baseline findings from newly introduced findings, while release gates fail closed for high or critical reachable vulnerabilities and for the specifically reported glib advisory.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Saddle 1.8.11 security references
|
|
2
|
+
|
|
3
|
+
Android requires APKs to be digitally signed. Google Play separates the app signing key from the upload key and recommends keeping signing data out of Gradle files and public source. The Saddle workflow must use repository secrets or an external signing service, emit a test signed artifact only when explicitly labeled as such, and never commit a keystore.
|
|
4
|
+
|
|
5
|
+
GitHub CodeQL supports JavaScript and TypeScript, Rust, Swift, Java and Kotlin, among other languages, as well as GitHub Actions workflows. Its findings can be displayed as code scanning alerts, and advanced setup can upload results to the repository. CodeQL complements, but does not replace, dependency advisory scanners such as `cargo audit`, npm audit and OSV based scanners.
|
|
6
|
+
|
|
7
|
+
Sources:
|
|
8
|
+
|
|
9
|
+
1. [Android app signing](https://developer.android.com/studio/publish/app-signing)
|
|
10
|
+
2. [GitHub CodeQL code scanning](https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-code-scanning)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Saddle 1.8.11 security research
|
|
2
|
+
|
|
3
|
+
## Advisory scope
|
|
4
|
+
|
|
5
|
+
The reported advisory is `GHSA-wrw7-89jp-8q8g`, also identified as `RUSTSEC-2024-0429`. It affects the Rust crate `glib` from version `0.15.0` through versions before `0.20.0`. The patched line is `glib >= 0.20.0`.
|
|
6
|
+
|
|
7
|
+
The issue is an unsound `VariantStrIter` implementation. The affected iterator methods can reach a mutable C out-argument through an immutable Rust reference, which can lead to undefined behavior and null pointer dereference crashes in optimized builds. GitHub classifies the advisory as **Moderate**, with CVSS 4.0 base score `6.9`; no CVE identifier is assigned.
|
|
8
|
+
|
|
9
|
+
The advisory is relevant to Saddle's native dependency graph because the desktop Tauri surface uses Rust and GTK/WebKit platform dependencies. The first remediation step is to inspect the resolved Cargo graph rather than assume that the direct application manifest is the only source of `glib`.
|
|
10
|
+
|
|
11
|
+
## Required checks
|
|
12
|
+
|
|
13
|
+
The security workflow must run `cargo tree` and `cargo audit` against the resolved desktop graph, report every `glib` version, and fail when an affected version is reachable in a release build. A direct dependency override must not be added blindly: GTK generation compatibility and the actual Tauri platform dependency graph must be checked before selecting an upgrade, patch release, or platform-specific mitigation.
|
|
14
|
+
|
|
15
|
+
## Sources
|
|
16
|
+
|
|
17
|
+
1. [GitHub Advisory Database: GHSA-wrw7-89jp-8q8g](https://github.com/advisories/GHSA-wrw7-89jp-8q8g)
|
|
18
|
+
2. [RustSec: RUSTSEC-2024-0429](https://rustsec.org/advisories/RUSTSEC-2024-0429.html)
|
|
19
|
+
3. [gtk-rs-core fix discussion](https://github.com/gtk-rs/gtk-rs-core/pull/1343)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Binary signing research for Saddle 1.8.12
|
|
2
|
+
|
|
3
|
+
## Scope and conclusion
|
|
4
|
+
|
|
5
|
+
This investigation covered 30 search queries across official Microsoft, Apple, Android and GitHub documentation; open-source project workflows; signing-tool repositories; Stack Overflow, Security Stack Exchange, Reddit and public community discussions; and academic or standards sources on provenance and reproducible builds. The central conclusion is direct: **an open-source library can implement signing formats, but it cannot mint a certificate that Windows already trusts**. Public trust comes from a platform root program, a store, a certificate authority, a managed signing provider or an approved open-source signing program.
|
|
6
|
+
|
|
7
|
+
The free options are therefore conditional rather than magical. Microsoft Store MSIX distribution can be re-signed by Microsoft. SignPath Foundation can sign eligible open-source projects. Google Play App Signing can protect the final Android key after the project creates an upload identity. Sigstore, Cosign, SLSA and in-toto can provide strong provenance and transparency, but they do not replace Authenticode for SmartScreen. macOS and iOS still require Apple program identities for public trust.
|
|
8
|
+
|
|
9
|
+
## Research matrix
|
|
10
|
+
|
|
11
|
+
| # | Question investigated | Evidence class | Decision |
|
|
12
|
+
| --: | ----------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| 1 | How does Authenticode establish Windows publisher identity? | Microsoft documentation | It validates a certificate chain and signature; a free local key does not become a public identity. |
|
|
14
|
+
| 2 | What signals does SmartScreen use? | Microsoft documentation | Publisher reputation and file-hash reputation both matter. |
|
|
15
|
+
| 3 | Does a new signed binary always avoid SmartScreen? | Microsoft documentation | No. New signed files can still produce an initial warning while reputation accumulates. |
|
|
16
|
+
| 4 | Does EV still bypass SmartScreen? | Microsoft documentation | No. Microsoft states that EV no longer provides the former instant bypass. |
|
|
17
|
+
| 5 | Does an unsigned binary inherit reputation? | Microsoft documentation | No. Unsigned versions begin with zero reputation for each new file. |
|
|
18
|
+
| 6 | Does Microsoft Store distribution avoid the warning? | Microsoft documentation | Store-distributed MSIX packages are re-signed by Microsoft and are the most reliable route. |
|
|
19
|
+
| 7 | Does the Store re-sign MSI and EXE installers? | Microsoft documentation | No. MSI/EXE submissions still require a trusted Authenticode chain. |
|
|
20
|
+
| 8 | Is Azure Artifact Signing free? | Microsoft documentation | It is a managed service with identity validation and a recurring cost; it is not an OSS certificate generator. |
|
|
21
|
+
| 9 | Does SignPath Foundation offer OSS signing? | SignPath Foundation | Yes, for eligible projects; the service verifies repository-to-binary linkage and keeps keys in an HSM. |
|
|
22
|
+
| 10 | Does SignPath issue a certificate locally? | SignPath Foundation | No. The provider controls the signing service and approval process. |
|
|
23
|
+
| 11 | Can `osslsigncode` create public trust? | Open-source repository | It can implement Authenticode signing, but trust still depends on the certificate and chain supplied to it. |
|
|
24
|
+
| 12 | Can Jsign create public trust? | Open-source repository | It can sign and timestamp PE, installer and script files; it does not create a trusted publisher identity. |
|
|
25
|
+
| 13 | Can SignTool create a public certificate? | Microsoft tooling | SignTool signs with an existing certificate and private key; it does not issue one. |
|
|
26
|
+
| 14 | Can Sigstore Cosign replace Authenticode? | Sigstore documentation | It provides keyless signatures and transparency for software artifacts, not a Windows Trusted Root certificate. |
|
|
27
|
+
| 15 | Can Fulcio or Rekor make SmartScreen trust a PE file? | Sigstore specifications | No evidence supports that substitution; use Sigstore as an integrity/provenance complement. |
|
|
28
|
+
| 16 | What does SLSA guarantee? | SLSA specification | It records how an artifact was built and can support verification; it does not establish Windows publisher reputation. |
|
|
29
|
+
| 17 | What does in-toto guarantee? | Academic and project sources | It protects supply-chain steps and provenance; it does not replace platform certificate trust. |
|
|
30
|
+
| 18 | Do reproducible builds remove SmartScreen warnings? | Standards and Microsoft behavior | No. They improve independent verification, not Microsoft publisher or hash reputation. |
|
|
31
|
+
| 19 | Can timestamping make an unsigned artifact trusted? | Authenticode tooling guidance | No. Timestamping preserves a valid signature after certificate expiry; it cannot create a signature. |
|
|
32
|
+
| 20 | Does signing only the installer cover embedded executables? | Installer signing guidance | No general assumption is safe; embedded PE files should be signed and verified independently. |
|
|
33
|
+
| 21 | Can MSIX test certificates be used for public users? | Microsoft MSIX guidance | No. Test certificates are for development or managed trust deployment. |
|
|
34
|
+
| 22 | Can Google Play sign Android releases? | Android documentation | Yes, Play App Signing protects the final app-signing key after an upload key is configured. |
|
|
35
|
+
| 23 | Can Google Play sign direct APK downloads? | Android documentation | No. Direct APK distribution requires the project to sign the APK. |
|
|
36
|
+
| 24 | Is Android upload-key generation free? | Android tooling | Key generation is free, but the identity and distribution account are still project responsibilities. |
|
|
37
|
+
| 25 | Can Apple Developer ID be generated by a library? | Apple documentation | No. It is associated with an Apple Developer Program account and Account Holder privileges. |
|
|
38
|
+
| 26 | Can macOS notarization be performed without Developer ID? | Apple documentation | No. Notarization is a service for Developer ID-signed software. |
|
|
39
|
+
| 27 | Can iOS provisioning be generated from source alone? | Apple documentation | No. It is tied to an Apple team, certificates and profiles. |
|
|
40
|
+
| 28 | How does OpenCode sign Windows binaries? | Public OpenCode workflow | It uses Azure Artifact Signing with provider credentials and certificate profile data. |
|
|
41
|
+
| 29 | What does Zed demonstrate? | Public Zed workflow | Release automation and package publishing can be open while provider and organization secrets remain private. |
|
|
42
|
+
| 30 | What do community reports say about free certificates? | Stack Overflow, Reddit and Security Stack Exchange | SignPath is repeatedly identified as the credible OSS route; anecdotal “certificate generators” do not establish platform trust. |
|
|
43
|
+
|
|
44
|
+
## Open-source tools versus trusted identities
|
|
45
|
+
|
|
46
|
+
The following tools are useful for Saddle, but none of them is a certificate authority:
|
|
47
|
+
|
|
48
|
+
| Tool or project | What it can do | What it cannot do |
|
|
49
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
50
|
+
| `osslsigncode` | Authenticode sign, timestamp, verify, remove and extract signatures for PE, CAB, CAT, MSI, APPX and scripts | Issue a Microsoft-trusted certificate |
|
|
51
|
+
| Jsign | Apache-licensed, cross-platform Authenticode signing, timestamping and verification for PE, MSI, MSIX, scripts and other formats; integrates with HSM and cloud key providers | Establish the publisher identity without a certificate or remote provider |
|
|
52
|
+
| SignTool | Native Windows signing and verification | Bypass certificate-chain or SmartScreen rules |
|
|
53
|
+
| `rcodesign` / `apple-codesign` | Open implementation of Apple signing and notarization client workflows | Create an Apple Developer ID identity |
|
|
54
|
+
| `apksigner` | Sign and verify Android APKs using a keystore | Create a Google Play publisher account or replace Play App Signing |
|
|
55
|
+
| Cosign / Sigstore | Keyless signatures, transparency and artifact verification | Make SmartScreen treat a PE file as Authenticode-signed |
|
|
56
|
+
| SLSA / in-toto | Build provenance, attestations and supply-chain integrity | Become a platform trust root |
|
|
57
|
+
| Reproducible-build tooling | Let independent parties rebuild and compare bytes | Remove first-download reputation warnings |
|
|
58
|
+
|
|
59
|
+
## Cost and trust classification
|
|
60
|
+
|
|
61
|
+
| Route | Direct cost | Identity requirement | SmartScreen/Gatekeeper result |
|
|
62
|
+
| ---------------------------- | ------------------------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------- |
|
|
63
|
+
| Self-signed test certificate | Free | None beyond local key control | Test or managed-enterprise trust only; public warnings remain |
|
|
64
|
+
| No signature | Free | None | Strong warning and possible enterprise/SAC block |
|
|
65
|
+
| Microsoft Store MSIX | Store and publisher onboarding costs may apply | Store account and certification | Microsoft re-signs the delivered MSIX |
|
|
66
|
+
| SignPath Foundation | Free for eligible OSS projects | Project review and provider acceptance | Provider signs the approved artifact |
|
|
67
|
+
| Azure Artifact Signing | Paid managed service; current Microsoft guidance lists approximately $10/month | Identity validation and cloud account | Valid signing; reputation still builds over time |
|
|
68
|
+
| Traditional OV certificate | Paid annual certificate | CA identity validation | Valid signing; new publisher/file reputation can still warn |
|
|
69
|
+
| EV certificate | Paid and operationally heavier | Stronger CA validation | No longer a SmartScreen bypass by itself |
|
|
70
|
+
| Apple Developer ID | Paid Apple membership | Apple Developer Program team | Developer ID signing plus notarization required |
|
|
71
|
+
| Google Play App Signing | Play developer account and project onboarding | Upload key and Play identity | Google signs store-delivered APKs |
|
|
72
|
+
| Sigstore | Often free for public CI identities | OIDC identity and policy | Verifiable provenance, not Authenticode trust |
|
|
73
|
+
|
|
74
|
+
## Safe techniques that actually help
|
|
75
|
+
|
|
76
|
+
The useful “tricks” are process improvements, not bypasses. Saddle should sign every nested PE file before signing the installer, use SHA-256 with a trusted timestamp service, preserve the exact bytes after signing, keep a stable publisher identity, publish checksums and SBOMs, attach GitHub artifact attestations, use protected release environments, restrict OIDC to tag-based jobs, and retain verification logs. A stable identity lets reputation accumulate; changing certificates or rebuilding different bytes for the same version works against that goal.
|
|
77
|
+
|
|
78
|
+
The most reliable Windows user experience is Microsoft Store MSIX. The most realistic direct-download route for Saddle is to apply to SignPath Foundation or use Azure Artifact Signing. Until one of those approvals exists, the workflow should publish `unsigned` or `test` status and never claim that Windows will accept the binary without a warning. A generated local certificate may be useful for CI validation, but it must not be used as a public trust claim.
|
|
79
|
+
|
|
80
|
+
The Sigstore Cosign quickstart confirms that keyless signing obtains a short-lived certificate from Fulcio after OIDC authentication, records the event in Rekor and verifies the bundle against the signing identity. This is valuable for a Saddle release manifest and supply-chain audit, but the Sigstore certificate is not an Authenticode certificate in the Microsoft Trusted Root Program. It should be attached as an integrity and provenance proof, not described as a SmartScreen bypass [7].
|
|
81
|
+
|
|
82
|
+
The SLSA build-provenance specification describes the builder, external parameters, resolved dependencies and output subjects of a build. That lets an independent verifier establish where, when and how an artifact was produced, but it does not assert that Windows trusts the publisher or that SmartScreen will suppress a warning. Saddle should use SLSA-compatible provenance alongside, not instead of, platform signing [8].
|
|
83
|
+
|
|
84
|
+
VSCodium is a particularly relevant open-source comparison. Its public distribution page says that the project builds and publishes its own Windows, macOS and Linux binaries, uses package-manager routes in addition to GitHub releases, and explicitly credits SignPath.io for free Windows code signing with a SignPath Foundation certificate. It also credits a separate macOS certificate contributor, showing that open-source projects commonly combine a community signing program for Windows with an independently held Apple identity rather than generating a universal certificate [23].
|
|
85
|
+
|
|
86
|
+
The SignPath GitHub integration confirms the “hidden” mechanism that can look like a certificate generator from the outside: the workflow uploads the unsigned artifact, submits it with `SIGNPATH_API_TOKEN`, organization/project/policy identifiers and the GitHub artifact ID, then downloads the provider-signed output. SignPath checks that the build was performed by the expected GitHub workflow and that origin metadata came from GitHub rather than the build script. This is a legitimate managed-signing route, not a reusable certificate embedded in an open-source repository [24]. VSCodium's workflow directory also shows separate build and publish jobs for Linux, macOS and Windows, which supports the conclusion that the project uses explicit platform lanes rather than one cross-platform certificate [25].
|
|
87
|
+
|
|
88
|
+
The additional provider search found OSSign, which advertises free code signing for qualifying open-source projects and requires an active project, a public automated build and public source review. Its page also states that applications were temporarily suspended because of a backlog. This is a promising second provider to evaluate, but it is still a managed service with eligibility and queue constraints, not a local certificate generator [26]. Let's Encrypt explicitly says that it issues free TLS certificates but does not issue certificates for code signing; using an ACME certificate for Authenticode would be a category error [27].
|
|
89
|
+
|
|
90
|
+
Two additional IDE comparisons clarify the boundary. Lite XL documents newer Windows releases as self-signed and asks users to perform a first-run trust step; this is honest development or community distribution, but it does not remove public SmartScreen warnings. KeePassXC, in contrast, publicly raised funds to purchase a four-year Authenticode certificate for its Windows and macOS installers. The pair demonstrates that open-source projects either disclose a self-signed route or acquire/provider a real identity; neither approach generates a universally trusted certificate from source code [28] [29].
|
|
91
|
+
|
|
92
|
+
Certum provides a less obvious but legitimate route: its Open Source Code Signing product is a paid certificate marketed to open-source developers, with the page displaying a current price and requiring a Certum cryptographic card and reader for activation. This is a conventional CA product with an open-source qualification, not a free generated key. Codegic is the opposite case: its own page says its free certificate is not from a publicly trusted CA and only removes the unknown-publisher warning after a root is manually trusted. It is suitable only for controlled environments and must not be presented as a public SmartScreen solution [30] [31].
|
|
93
|
+
|
|
94
|
+
### Passive release-manifest reverse engineering
|
|
95
|
+
|
|
96
|
+
The public release APIs were inspected without executing or installing any downloaded binary. VSCodium exposes separate Windows setup assets for `x64` and `arm64`, user and machine setup variants, each accompanied by hash files. Lite XL exposes Windows `i686` and `x86_64` archives/installers, macOS architecture-specific DMGs and Linux portable/AppImage outputs, while its documentation is explicit about self-signed Windows releases. KeePassXC publishes Windows MSI/ZIP, macOS DMG and Linux AppImage assets together with detached `.sig` and `.DIGEST` files. VimR's latest public release endpoint exposes a source archive rather than a universal signed app asset. These observations support a Saddle design with explicit per-platform lanes, architecture labels, detached integrity proofs and a separate platform-signing status rather than one generic “signed” flag [32] [33] [34] [35].
|
|
97
|
+
|
|
98
|
+
The KeePassXC release checklist adds a useful workflow pattern: it builds Windows `amd64` and `arm64` separately with an explicit signing identity, builds macOS `x86_64` and `arm64` with `--sign --notarize`, checks the installed binaries, signs release files with GPG and uploads signatures/digests alongside the assets. Its checklist also includes a Microsoft Store update, showing that direct-download signing and Store distribution are separate release surfaces [36]. VimR documents the same distinction in a simpler form: a normal release is signed and notarized, while `notarize=false` intentionally produces an ad-hoc signature for local development. The project therefore demonstrates a safe status model rather than a hidden universal key [37].
|
|
99
|
+
|
|
100
|
+
A passive byte inspection of a current KeePassXC MSI pair confirms that the `.DIGEST` asset is a textual SHA-256-style digest line, while the `.sig` asset begins with an ASCII-armored `PGP SIGNATURE` block. This is a reproducible pattern Saddle can adopt for detached integrity evidence, but it remains distinct from the embedded Windows Authenticode signature that controls publisher identity and SmartScreen behavior [34] [36].
|
|
101
|
+
|
|
102
|
+
SignServer Community is a genuine open-source signing engine and can centralize signing keys, policies and audit trails. Its own repository states that the Community edition is intended for learning, testing and prototyping rather than production, while production deployments require the commercial edition or an equivalent operational model. SignServer therefore provides a possible self-hosted engine for Saddle's internal signing architecture, but it does not grant a Microsoft-trusted root or a free public certificate; the operator still needs a valid CA/provider identity and secure key custody [38] [39].
|
|
103
|
+
|
|
104
|
+
The Eclipse Common Build Infrastructure documents a two-layer model that is useful for Saddle: projects sign all produced artifacts with a project-specific GPG web-of-trust key, and use platform code-signing certificates when deployment platforms can enforce them. Eclipse explicitly treats GPG as artifact integrity and platform signing as the mechanism that prevents platform warnings. The IntelliJ Platform comparison is different: it is an open-source foundation for building IDEs, but its source availability does not imply that every downstream IDE has the JetBrains publisher identity. In both cases, open source describes the code or build infrastructure, not a transferable signing identity [40] [41].
|
|
105
|
+
|
|
106
|
+
## Route classification for Saddle
|
|
107
|
+
|
|
108
|
+
| Classification | Route | 1.8.12 decision |
|
|
109
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| Verified public route | Microsoft Store MSIX/AppX | Add as an optional distribution lane; Microsoft signs the Store-delivered package. |
|
|
111
|
+
| Verified conditional route | SignPath Foundation | Apply with the public repository and reproducible GitHub workflow; integrate only after acceptance and policy identifiers are issued. |
|
|
112
|
+
| Verified conditional route | OSSign | Keep as a second application target; the current page reports a queue suspension, so it cannot be an immediate dependency. |
|
|
113
|
+
| Verified paid route | Azure Artifact Signing or Certum Open Source | Use only after account validation, billing/renewal acceptance and protected secret setup. |
|
|
114
|
+
| Verified integrity route | Cosign, GPG, detached digest, SLSA and in-toto | Add as release evidence; do not label it Authenticode or SmartScreen trust. |
|
|
115
|
+
| Controlled-environment route | Codegic, self-signed certificate or SignServer CE | Allow only in explicit `test` or `enterprise-root` mode; never claim public Windows trust. |
|
|
116
|
+
| Unsupported route | Let's Encrypt or an ordinary TLS ACME certificate | Reject because the issuer explicitly does not issue code-signing certificates. |
|
|
117
|
+
| Unsafe route | Scraped certificate, copied publisher metadata, reused third-party signature, reputation farming or “certificate generator” bypass | Reject outright; these create impersonation, malware and revocation risks. |
|
|
118
|
+
|
|
119
|
+
Academic measurements show why “a valid signature” is not the same as “safe software.” The USENIX study _The Broken Shield_ reports difficulties discovering abusive certificates, delays in revocation and failures in disseminating revocation information, which can leave clients trusting revoked certificates [21]. The arXiv study _Issued for Abuse_ documents underground trading of Authenticode certificates and connects that demand to attempts to bypass platform protections such as SmartScreen [22]. For Saddle, this means that a provider's identity review, HSM custody, protected release environment, provenance and revocation plan are security requirements, not optional decoration.
|
|
120
|
+
|
|
121
|
+
## 1.8.12 implementation plan
|
|
122
|
+
|
|
123
|
+
The next release should add an optional MSIX/AppX packaging lane, a SignPath or Azure provider adapter behind protected secrets, nested-PE signature verification, a signed-provenance bundle using Sigstore/SLSA-compatible metadata, and explicit release fields for `unsigned`, `caller-owned`, `provider-signed`, `store-signed` and `notarized`. The release must remain `1.8.12` only after the package manifests and release tag are intentionally bumped; the published `v1.8.11` tag must not be overwritten.
|
|
124
|
+
|
|
125
|
+
## References
|
|
126
|
+
|
|
127
|
+
[1]: https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/smartscreen-reputation "SmartScreen reputation for Windows app developers"
|
|
128
|
+
[2]: https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/code-signing-options "Code signing options for Windows app developers"
|
|
129
|
+
[3]: https://learn.microsoft.com/en-us/azure/artifact-signing/quickstart "Azure Artifact Signing quickstart"
|
|
130
|
+
[4]: https://signpath.org/ "SignPath Foundation"
|
|
131
|
+
[5]: https://github.com/mtrojnar/osslsigncode "osslsigncode"
|
|
132
|
+
[6]: https://github.com/ebourg/jsign "Jsign"
|
|
133
|
+
[7]: https://docs.sigstore.dev/quickstart/quickstart-cosign/ "Sigstore Cosign quickstart"
|
|
134
|
+
[8]: https://slsa.dev/spec/v1.2/build-provenance "SLSA build provenance"
|
|
135
|
+
[9]: https://in-toto.io/ "in-toto supply-chain integrity framework"
|
|
136
|
+
[10]: https://developer.apple.com/developer-id/ "Apple Developer ID"
|
|
137
|
+
[11]: https://developer.apple.com/programs/enroll/ "Apple Developer Program enrollment"
|
|
138
|
+
[12]: https://developer.android.com/studio/publish/app-signing "Android app signing and Play App Signing"
|
|
139
|
+
[13]: https://developer.android.com/tools/apksigner "Android apksigner"
|
|
140
|
+
[14]: https://raw.githubusercontent.com/anomalyco/opencode/dev/.github/workflows/publish.yml "OpenCode publish workflow"
|
|
141
|
+
[15]: https://raw.githubusercontent.com/zed-industries/zed/main/.github/workflows/after_release.yml "Zed post-release workflow"
|
|
142
|
+
[16]: https://docs.github.com/en/actions/concepts/security/openid-connect "GitHub Actions OpenID Connect"
|
|
143
|
+
[17]: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets "Using secrets in GitHub Actions"
|
|
144
|
+
[18]: https://www.usenix.org/conference/usenixsecurity19/presentation/torres-arias "in-toto: Providing farm-to-table guarantees for bits and bytes"
|
|
145
|
+
[19]: https://stackoverflow.com/questions/78848067/can-i-post-a-non-signed-msix-app-on-the-microsoft-store "Stack Overflow: unsigned MSIX and Microsoft Store"
|
|
146
|
+
[20]: https://security.stackexchange.com/questions/139347/smart-screen-filter-still-complains-despite-i-signed-the-executable-why "Security Stack Exchange: SmartScreen after signing"
|
|
147
|
+
[21]: https://www.usenix.org/conference/usenixsecurity18/presentation/kim "The Broken Shield: Measuring Revocation Effectiveness in the Windows Code-Signing PKI"
|
|
148
|
+
[22]: https://arxiv.org/abs/1803.02931 "Issued for Abuse: Measuring the Underground Trade in Code Signing Certificate"
|
|
149
|
+
[23]: https://vscodium.com/ "VSCodium open-source binary distribution"
|
|
150
|
+
[24]: https://docs.signpath.io/trusted-build-systems/github "SignPath GitHub trusted build system"
|
|
151
|
+
[25]: https://github.com/VSCodium/vscodium/tree/master/.github/workflows "VSCodium public workflows"
|
|
152
|
+
[26]: https://ossign.org/ "OSSign code signing for open source"
|
|
153
|
+
[27]: https://letsencrypt.org/docs/faq/ "Let's Encrypt FAQ"
|
|
154
|
+
[28]: https://github.com/lite-xl/lite-xl "Lite XL source repository and release notes"
|
|
155
|
+
[29]: https://keepassxc.org/blog/2017-03-04-authenticode-cert/ "KeePassXC funding an Authenticode certificate"
|
|
156
|
+
[30]: https://certum.store/open-source-code-signing-code.html "Certum Open Source Code Signing certificate"
|
|
157
|
+
[31]: https://www.codegic.com/code-signing-certificate/ "Codegic code signing certificate limits"
|
|
158
|
+
[32]: https://github.com/VSCodium/vscodium/releases "VSCodium releases and architecture-specific assets"
|
|
159
|
+
[33]: https://github.com/lite-xl/lite-xl/releases "Lite XL releases and package matrix"
|
|
160
|
+
[34]: https://github.com/keepassxreboot/keepassxc/releases "KeePassXC releases with detached signatures and digests"
|
|
161
|
+
[35]: https://github.com/qvacua/vimr/releases "VimR releases"
|
|
162
|
+
[36]: https://github.com/keepassxreboot/keepassxc/wiki/Release-Checklist/ea3d900eedd4f765cf51763fc157ccee6b0118ab "KeePassXC release checklist"
|
|
163
|
+
[37]: https://github.com/qvacua/vimr "VimR signed, notarized and ad-hoc build modes"
|
|
164
|
+
[38]: https://www.signserver.org/ "SignServer Community open-source signing software"
|
|
165
|
+
[39]: https://github.com/Keyfactor/signserver-ce "SignServer Community repository and production limits"
|
|
166
|
+
[40]: https://eclipse.dev/cbi/best-practices/software-supply-chain/osssc-best-practices/ "Eclipse Open Source Software Supply Chain best practices"
|
|
167
|
+
[41]: https://www.jetbrains.com/opensource/intellij-platform/ "IntelliJ Platform open-source foundation"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Signing Saddle without owning platform certificates
|
|
2
|
+
|
|
3
|
+
Saddle cannot generate a certificate that Windows, Apple or an app store already trusts. A local self-signed certificate proves only that a test key signed the file; it does not establish publisher identity for public users. The reliable choices are a platform store, a managed signing provider, an open-source signing program or a certificate purchased and held by the project owner.
|
|
4
|
+
|
|
5
|
+
## Decision matrix
|
|
6
|
+
|
|
7
|
+
| Surface | Route without an owned production certificate | What the project still needs | Result in the workflow |
|
|
8
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
9
|
+
| Windows | Submit an MSIX package to Microsoft Store, where Microsoft re-signs the package; apply to SignPath Foundation; or use Azure Artifact Signing | Store/SignPath/Azure acceptance and a release identity | Trusted only when the external provider or store has signed the artifact |
|
|
10
|
+
| Windows direct EXE/MSI | SignPath Foundation or Azure Artifact Signing; traditional OV certificate is the paid fallback | Provider account, repository binding and timestamp configuration | `caller-owned` signing status; unsigned output remains a test artifact |
|
|
11
|
+
| macOS | Mac App Store distribution or Apple Developer ID plus notarization | Apple Developer Program membership, Account Holder access, certificate, hardened runtime and notarization credentials | `notarized` only after Apple accepts and staples the ticket |
|
|
12
|
+
| Android Play | Google Play App Signing | Play Console account and a secret upload key; Google protects the final app-signing key | Google signs store APKs; direct APKs still require Saddle signing |
|
|
13
|
+
| Android direct APK | Generate and protect a project keystore with `keytool` | Secret keystore, alias and separate passwords | `caller-key` only after `apksigner verify` passes |
|
|
14
|
+
| iOS App Store | Apple signing and provisioning through the Apple Developer Program and App Store Connect | Apple team, distribution certificate, provisioning profile and export credentials | IPA/app is distributable only after Apple signing succeeds |
|
|
15
|
+
| Browser extension | No platform certificate is required for a local ZIP; store publishing uses the store account | Store publisher account and review | Package is identified by its manifest and release checksums |
|
|
16
|
+
|
|
17
|
+
Microsoft explicitly distinguishes free Microsoft Store MSIX re-signing from MSI/EXE submission, which still requires an Authenticode chain trusted by Microsoft. The same guidance lists self-signed and unsigned artifacts as development or testing options, not public-trust solutions [1]. SignPath Foundation is a legitimate open-source program that can provide a certificate for eligible projects and keeps the private key in an HSM; it is an application and approval process, not a package that manufactures trust locally [2].
|
|
18
|
+
|
|
19
|
+
Apple requires a Developer ID certificate for Gatekeeper confidence outside the Mac App Store and recommends notarization after signing. The Developer ID certificate is created from an Apple Developer account by the Account Holder [3]. Android requires installable APKs to be signed; Play App Signing lets Google protect the final app-signing key while the project retains an upload key [4].
|
|
20
|
+
|
|
21
|
+
## Recommended path for Saddle
|
|
22
|
+
|
|
23
|
+
The first practical route is to apply to the [SignPath Foundation](https://signpath.org/apply) for Windows signing and simultaneously keep the current unsigned mode for artifacts produced before approval. If Microsoft Store distribution is acceptable, add an MSIX/AppX packaging target and submit that package instead of promising SmartScreen trust for the existing EXE/MSI files. OpenCode demonstrates the managed-provider route publicly: its release workflow uses Azure Artifact Signing with an endpoint, account name and certificate profile [5].
|
|
24
|
+
|
|
25
|
+
For macOS and iOS, the project needs an Apple Developer Program team. No open-source framework can produce a universally trusted Developer ID certificate or Apple provisioning profile from source code. Android can use Google Play App Signing for Play distribution, but direct APK files still require a project-controlled upload/release key.
|
|
26
|
+
|
|
27
|
+
## GitHub configuration steps
|
|
28
|
+
|
|
29
|
+
The repository owner should acquire or be accepted by the appropriate provider first. The private files and passwords must never be pasted into chat, committed to the repository or printed by a workflow. In GitHub, open **Saddle → Settings → Secrets and variables → Actions → New repository secret** and add the values as repository or protected-environment secrets [6].
|
|
30
|
+
|
|
31
|
+
The current workflow contracts are:
|
|
32
|
+
|
|
33
|
+
| Provider | Secrets | Variables |
|
|
34
|
+
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
|
|
35
|
+
| Windows Authenticode | `WINDOWS_CERTIFICATE_BASE64`, `WINDOWS_CERTIFICATE_PASSWORD` | `WINDOWS_TIMESTAMP_URL` |
|
|
36
|
+
| Azure/SignPath adapter | Provider-specific endpoint, account/profile and OIDC or token values after approval | Provider-specific non-secret identifiers |
|
|
37
|
+
| macOS desktop | `APPLE_CERTIFICATE`, `APPLE_CERTIFICATE_PASSWORD`, `APPLE_SIGNING_IDENTITY`, `KEYCHAIN_PASSWORD`, `APPLE_ID`, `APPLE_APP_PASSWORD`, `APPLE_TEAM_ID` | None required by the current desktop contract |
|
|
38
|
+
| Android | `ANDROID_KEY_BASE64`, `ANDROID_KEY_ALIAS`, `ANDROID_STORE_PASSWORD`, `ANDROID_KEY_PASSWORD` | None required |
|
|
39
|
+
| iOS | `IOS_CERTIFICATE_BASE64`, `IOS_CERTIFICATE_PASSWORD`, `IOS_PROVISIONING_PROFILE_BASE64`, `KEYCHAIN_PASSWORD` | `IOS_PROVISIONING_PROFILE_NAME` |
|
|
40
|
+
|
|
41
|
+
The workflow must run signing only for a trusted release event. Fork and Dependabot workflows do not receive normal repository secrets, so those jobs should build, scan and report unsigned/test status rather than attempting production signing [6]. The release manifest must state `unsigned`, `ci-test-key`, `caller-owned` or `notarized`; it must never equate a successful build with platform trust.
|
|
42
|
+
|
|
43
|
+
## What not to do
|
|
44
|
+
|
|
45
|
+
The project must not download a “universal certificate,” use a private key from another project, reuse a certificate from OpenCode or Zed, place a self-signed certificate in the public repository, or claim that SmartScreen, Gatekeeper or Play will trust an unsigned file. Those approaches either fail for users or create an impersonation and supply-chain risk.
|
|
46
|
+
|
|
47
|
+
## References
|
|
48
|
+
|
|
49
|
+
[1]: https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/code-signing-options "Microsoft code signing options for Windows app developers"
|
|
50
|
+
[2]: https://signpath.org/ "SignPath Foundation"
|
|
51
|
+
[3]: https://developer.apple.com/developer-id/ "Apple Developer ID signing and notarization"
|
|
52
|
+
[4]: https://developer.android.com/studio/publish/app-signing "Android app signing and Play App Signing"
|
|
53
|
+
[5]: https://raw.githubusercontent.com/anomalyco/opencode/dev/.github/workflows/publish.yml "OpenCode publish workflow"
|
|
54
|
+
[6]: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets "Using secrets in GitHub Actions"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# SignPath Foundation application
|
|
2
|
+
|
|
3
|
+
The public application page is `https://signpath.org/apply`.
|
|
4
|
+
|
|
5
|
+
The visible first section requests the project name, repository URL, homepage URL, download URL and privacy policy URL. SignPath states that the homepage should be a project website or repository page, while the download page must mention that the project uses SignPath Foundation for code signing. The application must be completed with public project information first; personal email and final submission remain caller-owned.
|
|
6
|
+
|
|
7
|
+
The recommended Saddle integration is GitHub Actions because the repository has public release workflows and a reproducible build path. A generic CI/CD label is broader, while GitHub Actions identifies the trusted build system that SignPath can verify.
|
|
8
|
+
|
|
9
|
+
The selected project license is GPL-3.0-only, an OSI-approved open-source license. The repository now keeps one canonical root `LICENSE` file with the official GPL v3.0 text and declares `GPL-3.0-only` in its package manifests. The public download page documents the requested SignPath Foundation code-signing policy while clearly marking approval as pending.
|
|
10
|
+
|
|
11
|
+
The form is rendered by an embedded HubSpot flow. The page visually shows the public fields, but the browser automation layer does not expose those inputs as indexable controls, so direct coordinate entry is not reliable. The safe continuation is a user browser takeover on the already-open page. The agent must not enter the user's email or submit the application without an explicit final confirmation.
|
package/docs/sitemap.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Sitemap traversal
|
|
2
|
+
|
|
3
|
+
The sitemap parser follows nested sitemap indexes with a caller-defined maximum depth and URL count. It tracks visited sitemap documents to prevent cycles and canonicalizes URL identities without fragments so repeated references do not consume the result budget. `fetchSitemap` also accepts an injected fetcher for deterministic tests and caller-owned transport policy.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
const urls = await parseSitemap("https://example.test/sitemap.xml", {
|
|
7
|
+
followIndexes: true,
|
|
8
|
+
maxDepth: 8,
|
|
9
|
+
maxUrls: 10000,
|
|
10
|
+
timeout: 10000,
|
|
11
|
+
});
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The parser does not select a proxy, browser, credential, host or port. Network failures continue to use the existing `WebScrapeError` contract, and the result remains a bounded array of normalized sitemap entries.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Tauri and glib advisory decision
|
|
2
|
+
|
|
3
|
+
The Tauri issue tracker confirms that Tauri's Linux surface can inherit the affected Rust GTK3/glib bindings transitively. The upstream discussion states that GTK3 bindings are archived and that the issue is blocked on upstream dependencies; a GTK4 migration remains an open feature request. Tauri maintainers also state that the affected iterator path is not used by Tauri itself, but this does not make the dependency advisory disappear from automated scanners.
|
|
4
|
+
|
|
5
|
+
Saddle must therefore treat `GHSA-wrw7-89jp-8q8g` as a documented transitive limitation until the resolved desktop graph proves otherwise. The security workflow should fail on a newly introduced reachable affected version, but its baseline policy may allow this specific existing Linux-only advisory only through a reviewed, time-bounded ignore entry with the exact rationale and upstream tracking links. The release manifest must expose the accepted-risk status instead of labeling the Linux bundle fully clean.
|
|
6
|
+
|
|
7
|
+
Sources:
|
|
8
|
+
|
|
9
|
+
1. [Tauri issue #12048: glib-rs advisory](https://github.com/tauri-apps/tauri/issues/12048)
|
|
10
|
+
2. [Tauri issue #7335: GTK4 migration](https://github.com/tauri-apps/tauri/issues/7335)
|
|
11
|
+
3. [GHSA-wrw7-89jp-8q8g](https://github.com/advisories/GHSA-wrw7-89jp-8q8g)
|