generated from MrSphay/codex-agent-repository-kit
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5cea35069 | ||
|
|
f3c353b821 | ||
|
|
d3234e03b8 | ||
| 631a66dab1 |
@@ -10,6 +10,8 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MRTRUST_VERSION: 0.1.3
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -24,7 +26,6 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="0.1.2"
|
||||
dotnet publish src/MrTrustLauncher.csproj \
|
||||
--configuration Release \
|
||||
--runtime win-x64 \
|
||||
@@ -38,7 +39,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="0.1.2"
|
||||
version="${MRTRUST_VERSION}"
|
||||
package_root="dist/MrTrust-${version}"
|
||||
rm -rf "$package_root" "dist/MrTrust-${version}.zip"
|
||||
mkdir -p "$package_root"
|
||||
@@ -54,8 +55,8 @@ jobs:
|
||||
- name: Upload release artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: MrTrust-0.1.2
|
||||
path: dist/MrTrust-0.1.2.zip
|
||||
name: MrTrust-${{ env.MRTRUST_VERSION }}
|
||||
path: dist/MrTrust-${{ env.MRTRUST_VERSION }}.zip
|
||||
|
||||
- name: Attach ZIP to Gitea release
|
||||
if: github.ref == 'refs/heads/main'
|
||||
@@ -64,16 +65,38 @@ jobs:
|
||||
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="0.1.2"
|
||||
version="${MRTRUST_VERSION}"
|
||||
asset_name="MrTrust-${version}.zip"
|
||||
api="https://git.wilkensxl.de/api/v1/repos/MrSphay/MrTrust"
|
||||
release_json="$(curl -fsS -H "Authorization: token ${GITEA_TOKEN}" "${api}/releases/tags/v${version}")"
|
||||
release_response="$(mktemp)"
|
||||
status="$(curl -sS -o "$release_response" -w "%{http_code}" -H "Authorization: token ${GITEA_TOKEN}" "${api}/releases/tags/v${version}")"
|
||||
if [ "$status" = "404" ]; then
|
||||
release_json="$(VERSION="$version" python3 -c 'import json, os; version = os.environ["VERSION"]; print(json.dumps({"tag_name": f"v{version}", "target_commitish": "main", "name": f"MrTrust v{version}", "body": f"MrTrust v{version} release built by the Gitea runner.", "draft": False, "prerelease": False}))')"
|
||||
curl -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$release_json" \
|
||||
"${api}/releases" > "$release_response"
|
||||
elif [ "$status" != "200" ]; then
|
||||
cat "$release_response" >&2
|
||||
exit 1
|
||||
fi
|
||||
release_json="$(cat "$release_response")"
|
||||
release_id="$(printf '%s' "$release_json" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')"
|
||||
if [ -z "$release_id" ]; then
|
||||
echo "Could not resolve release id for v${version}" >&2
|
||||
exit 1
|
||||
fi
|
||||
existing_asset_id="$(RELEASE_JSON="$release_json" ASSET_NAME="$asset_name" python3 -c 'import json, os; release = json.loads(os.environ["RELEASE_JSON"]); asset_name = os.environ["ASSET_NAME"]; print(next((str(asset.get("id", "")) for asset in release.get("assets", []) if asset.get("name") == asset_name), ""))')"
|
||||
if [ -n "$existing_asset_id" ]; then
|
||||
curl -fsS \
|
||||
-X DELETE \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${api}/releases/${release_id}/assets/${existing_asset_id}"
|
||||
fi
|
||||
curl -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-F "attachment=@dist/MrTrust-${version}.zip" \
|
||||
"${api}/releases/${release_id}/assets?name=MrTrust-${version}.zip"
|
||||
-F "attachment=@dist/${asset_name}" \
|
||||
"${api}/releases/${release_id}/assets?name=${asset_name}"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 0.1.3
|
||||
|
||||
- Added Ubuntu-runner signing support through `osslsigncode` and PFX secrets.
|
||||
|
||||
## 0.1.2
|
||||
|
||||
- Made `MrTrust.exe` a standalone user-facing release artifact.
|
||||
|
||||
@@ -19,6 +19,7 @@ MrTrust does not bypass Microsoft Defender or SmartScreen. Windows can still sca
|
||||
- `scripts/Install-MrTrust.ps1` installs the public trust certificate for the current user or the local machine.
|
||||
- `scripts/Uninstall-MrTrust.ps1` removes the MrTrust certificate again.
|
||||
- `scripts/Sign-MrTrustProject.ps1` signs `.exe`, `.msi`, `.ps1`, and other Authenticode-compatible files.
|
||||
- `scripts/Sign-MrTrustProjectLinux.sh` signs Windows PE/MSI/CAT artifacts on Ubuntu Gitea runners with `osslsigncode`.
|
||||
- `scripts/New-MrTrustRelease.ps1` builds a distributable ZIP package.
|
||||
- `docs/integration-prompt.md` is a prompt you can paste into other Windows projects.
|
||||
- `docs/agent-target-integration.md` is the autonomous target-project integration runbook for agents.
|
||||
@@ -69,7 +70,7 @@ Remove the trust certificate:
|
||||
Build a user-facing ZIP release:
|
||||
|
||||
```powershell
|
||||
.\scripts\New-MrTrustRelease.ps1 -Version 0.1.2
|
||||
.\scripts\New-MrTrustRelease.ps1 -Version 0.1.3
|
||||
```
|
||||
|
||||
The Gitea workflow `.gitea/workflows/build.yml` builds the Windows launcher EXE on an `ubuntu-latest` runner with .NET Windows cross-targeting, then uploads the ZIP as an artifact.
|
||||
|
||||
@@ -43,6 +43,8 @@ Apply every item that fits the target project:
|
||||
- Use the public thumbprint from `mrtrust.integration.json`.
|
||||
- Only run signing where private signing material is securely available.
|
||||
- Do not commit `.pfx`, private keys, passwords, tokens, or signing secrets.
|
||||
- On the available `ubuntu-latest` Gitea runners, use `osslsigncode` with PFX secrets for `.exe`, `.dll`, `.msi`, and `.cat`.
|
||||
- PowerShell script signing (`.ps1`, `.psm1`, `.psd1`) still requires a Windows signing environment. If no Windows runner exists, document that limitation instead of blocking PE/MSI signing.
|
||||
|
||||
4. Add verification.
|
||||
- Verify the target project still builds.
|
||||
@@ -76,6 +78,12 @@ Check a signature:
|
||||
Get-AuthenticodeSignature .\dist\App.exe | Format-List Status,SignerCertificate,StatusMessage
|
||||
```
|
||||
|
||||
Sign a release directory on an Ubuntu Gitea runner:
|
||||
|
||||
```bash
|
||||
bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh ./dist
|
||||
```
|
||||
|
||||
## Installer Patterns
|
||||
|
||||
### Inno Setup
|
||||
@@ -118,6 +126,45 @@ Document that users should run it once before launching signed MrSphay apps if W
|
||||
|
||||
## CI Signing Patterns
|
||||
|
||||
### Gitea Actions On Ubuntu Runner
|
||||
|
||||
Use this when only `ubuntu-latest`, `ubuntu-24.04`, or `ubuntu-22.04` runners are available.
|
||||
|
||||
Required Gitea secrets:
|
||||
|
||||
```text
|
||||
MRTRUST_CODESIGN_PFX_BASE64
|
||||
MRTRUST_CODESIGN_PFX_PASSWORD
|
||||
```
|
||||
|
||||
Create `MRTRUST_CODESIGN_PFX_BASE64` locally from the private `.pfx`:
|
||||
|
||||
```powershell
|
||||
[Convert]::ToBase64String([IO.File]::ReadAllBytes(".\private\MrSphay-CodeSigning.pfx")) | Set-Clipboard
|
||||
```
|
||||
|
||||
Then paste the clipboard value into the Gitea secret. Do not commit the `.pfx` or the base64 value.
|
||||
|
||||
Ubuntu workflow step:
|
||||
|
||||
```yaml
|
||||
- name: Install signing tool
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y osslsigncode
|
||||
|
||||
- name: Sign Windows artifacts
|
||||
shell: bash
|
||||
env:
|
||||
MRTRUST_CODESIGN_PFX_BASE64: ${{ secrets.MRTRUST_CODESIGN_PFX_BASE64 }}
|
||||
MRTRUST_CODESIGN_PFX_PASSWORD: ${{ secrets.MRTRUST_CODESIGN_PFX_PASSWORD }}
|
||||
run: |
|
||||
bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh ./dist
|
||||
```
|
||||
|
||||
This signs `.exe`, `.dll`, `.msi`, and `.cat` artifacts. It does not sign PowerShell script files.
|
||||
|
||||
### Gitea Actions On Windows Runner
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -32,10 +32,12 @@ Implementation requirements:
|
||||
- Only offer LocalMachine installation when the user explicitly chooses an all-users install and the process is elevated.
|
||||
- Add an uninstall path or documentation that opens MrTrust again and tells the user to choose "Remove trust".
|
||||
- Keep the UI wording clear: the user is trusting MrSphay signed software, not bypassing Windows security.
|
||||
- If this project produces an .exe, .msi, .dll, .ps1, .psm1, .psd1, or .cat release artifact, sign it with:
|
||||
.\MrTrust\MrTrust.exe sign -Path <artifact-path> -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B
|
||||
- If this project produces an .exe, .msi, .dll, or .cat release artifact on an Ubuntu Gitea runner, sign it with:
|
||||
bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh <artifact-path>
|
||||
- Treat the certificate thumbprint as public metadata, but never commit private signing material.
|
||||
- If the target project needs automated signing, call MrTrust's signing script from CI or a secure local release machine where the private certificate is already installed or supplied through secrets. Do not put private signing material into the target repository or user-facing release ZIP.
|
||||
- Configure Gitea secrets `MRTRUST_CODESIGN_PFX_BASE64` and `MRTRUST_CODESIGN_PFX_PASSWORD` for Ubuntu runner signing.
|
||||
- If the target project needs .ps1, .psm1, or .psd1 signing, use a Windows signing environment or document that script signing is not available on the current Ubuntu-only runners.
|
||||
- Do not put private signing material into the target repository or user-facing release ZIP.
|
||||
|
||||
Verification:
|
||||
- Confirm the target project's user-facing release contains either a link to the MrTrust release ZIP or a bundled copy of `MrTrust.exe`.
|
||||
|
||||
@@ -29,8 +29,35 @@
|
||||
".psd1",
|
||||
".cat"
|
||||
],
|
||||
"preferredCommand": ".\\MrTrust\\MrTrust.exe sign -Path <artifact-path> -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B",
|
||||
"ciGuidance": "Run signing only on a trusted Windows release runner or secure local release machine where the private certificate is already installed or supplied through secrets.",
|
||||
"ubuntuRunner": {
|
||||
"supportedExtensions": [
|
||||
".exe",
|
||||
".msi",
|
||||
".dll",
|
||||
".cat"
|
||||
],
|
||||
"requiredTool": "osslsigncode",
|
||||
"helperScript": "scripts/Sign-MrTrustProjectLinux.sh",
|
||||
"requiredSecrets": [
|
||||
"MRTRUST_CODESIGN_PFX_BASE64",
|
||||
"MRTRUST_CODESIGN_PFX_PASSWORD"
|
||||
],
|
||||
"preferredCommand": "bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh <artifact-path>"
|
||||
},
|
||||
"windowsRunner": {
|
||||
"supportedExtensions": [
|
||||
".exe",
|
||||
".msi",
|
||||
".dll",
|
||||
".ps1",
|
||||
".psm1",
|
||||
".psd1",
|
||||
".cat"
|
||||
],
|
||||
"preferredCommand": ".\\MrTrust\\MrTrust.exe sign -Path <artifact-path> -CertificateThumbprint A024A89200469F099EC4A172B4F96F6428AFD41B"
|
||||
},
|
||||
"preferredCommand": "bash ./MrTrust/scripts/Sign-MrTrustProjectLinux.sh <artifact-path>",
|
||||
"ciGuidance": "On ubuntu-latest runners, sign PE/MSI/CAT artifacts with osslsigncode using a PFX stored in Gitea secrets. Use Windows runners only when signing PowerShell scripts or when Windows certificate store signing is required.",
|
||||
"unsignedBehavior": "Unsigned builds should remain unsigned. MrTrust only makes correctly signed MrSphay artifacts validate after the user has installed trust."
|
||||
},
|
||||
"targetProjectAgentContract": {
|
||||
|
||||
@@ -24,6 +24,7 @@ $payloadFiles = @(
|
||||
@{ Path = "scripts\New-MrTrustIcon.ps1"; ResourceName = "MrTrust.Payload.scripts.New-MrTrustIcon.ps1" },
|
||||
@{ Path = "scripts\New-MrTrustRelease.ps1"; ResourceName = "MrTrust.Payload.scripts.New-MrTrustRelease.ps1" },
|
||||
@{ Path = "scripts\Sign-MrTrustProject.ps1"; ResourceName = "MrTrust.Payload.scripts.Sign-MrTrustProject.ps1" },
|
||||
@{ Path = "scripts\Sign-MrTrustProjectLinux.sh"; ResourceName = "MrTrust.Payload.scripts.Sign-MrTrustProjectLinux.sh" },
|
||||
@{ Path = "scripts\Start-MrTrustGui.ps1"; ResourceName = "MrTrust.Payload.scripts.Start-MrTrustGui.ps1" },
|
||||
@{ Path = "scripts\Uninstall-MrTrust.ps1"; ResourceName = "MrTrust.Payload.scripts.Uninstall-MrTrust.ps1" },
|
||||
@{ Path = "assets\MrTrust.ico"; ResourceName = "MrTrust.Payload.assets.MrTrust.ico" },
|
||||
|
||||
71
scripts/Sign-MrTrustProjectLinux.sh
Normal file
71
scripts/Sign-MrTrustProjectLinux.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Usage: Sign-MrTrustProjectLinux.sh <artifact> [artifact...]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ -z "${MRTRUST_CODESIGN_PFX_BASE64:-}" ]; then
|
||||
echo "MRTRUST_CODESIGN_PFX_BASE64 is required." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ -z "${MRTRUST_CODESIGN_PFX_PASSWORD:-}" ]; then
|
||||
echo "MRTRUST_CODESIGN_PFX_PASSWORD is required." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! command -v osslsigncode >/dev/null 2>&1; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y osslsigncode
|
||||
else
|
||||
echo "osslsigncode is not installed and apt-get is unavailable." >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
work_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$work_dir"' EXIT
|
||||
|
||||
pfx_path="$work_dir/mrtrust-codesign.pfx"
|
||||
printf '%s' "$MRTRUST_CODESIGN_PFX_BASE64" | base64 -d > "$pfx_path"
|
||||
|
||||
timestamp_url="${MRTRUST_TIMESTAMP_URL:-http://timestamp.digicert.com}"
|
||||
|
||||
for artifact in "$@"; do
|
||||
if [ ! -f "$artifact" ]; then
|
||||
echo "Artifact not found: $artifact" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "${artifact##*.}" in
|
||||
exe|EXE|msi|MSI|dll|DLL|cat|CAT)
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported artifact for osslsigncode: $artifact" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
signed_path="$work_dir/$(basename "$artifact").signed"
|
||||
args=(
|
||||
sign
|
||||
-pkcs12 "$pfx_path"
|
||||
-pass "$MRTRUST_CODESIGN_PFX_PASSWORD"
|
||||
-n "MrSphay"
|
||||
-i "https://git.wilkensxl.de/MrSphay"
|
||||
-in "$artifact"
|
||||
-out "$signed_path"
|
||||
)
|
||||
|
||||
if [ -n "$timestamp_url" ]; then
|
||||
args+=( -t "$timestamp_url" )
|
||||
fi
|
||||
|
||||
osslsigncode "${args[@]}"
|
||||
mv "$signed_path" "$artifact"
|
||||
echo "Signed $artifact"
|
||||
done
|
||||
@@ -6,8 +6,6 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
#pragma warning disable CS8600, CS8602
|
||||
|
||||
namespace MrTrust
|
||||
{
|
||||
internal static class MrTrustLauncher
|
||||
@@ -23,6 +21,7 @@ namespace MrTrust
|
||||
new PayloadFile("scripts.New-MrTrustIcon.ps1", Path.Combine("scripts", "New-MrTrustIcon.ps1")),
|
||||
new PayloadFile("scripts.New-MrTrustRelease.ps1", Path.Combine("scripts", "New-MrTrustRelease.ps1")),
|
||||
new PayloadFile("scripts.Sign-MrTrustProject.ps1", Path.Combine("scripts", "Sign-MrTrustProject.ps1")),
|
||||
new PayloadFile("scripts.Sign-MrTrustProjectLinux.sh", Path.Combine("scripts", "Sign-MrTrustProjectLinux.sh")),
|
||||
new PayloadFile("scripts.Start-MrTrustGui.ps1", Path.Combine("scripts", "Start-MrTrustGui.ps1")),
|
||||
new PayloadFile("scripts.Uninstall-MrTrust.ps1", Path.Combine("scripts", "Uninstall-MrTrust.ps1")),
|
||||
new PayloadFile("assets.MrTrust.ico", Path.Combine("assets", "MrTrust.ico")),
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<EmbeddedResource Include="..\scripts\New-MrTrustIcon.ps1" LogicalName="MrTrust.Payload.scripts.New-MrTrustIcon.ps1" />
|
||||
<EmbeddedResource Include="..\scripts\New-MrTrustRelease.ps1" LogicalName="MrTrust.Payload.scripts.New-MrTrustRelease.ps1" />
|
||||
<EmbeddedResource Include="..\scripts\Sign-MrTrustProject.ps1" LogicalName="MrTrust.Payload.scripts.Sign-MrTrustProject.ps1" />
|
||||
<EmbeddedResource Include="..\scripts\Sign-MrTrustProjectLinux.sh" LogicalName="MrTrust.Payload.scripts.Sign-MrTrustProjectLinux.sh" />
|
||||
<EmbeddedResource Include="..\scripts\Start-MrTrustGui.ps1" LogicalName="MrTrust.Payload.scripts.Start-MrTrustGui.ps1" />
|
||||
<EmbeddedResource Include="..\scripts\Uninstall-MrTrust.ps1" LogicalName="MrTrust.Payload.scripts.Uninstall-MrTrust.ps1" />
|
||||
<EmbeddedResource Include="..\assets\MrTrust.ico" LogicalName="MrTrust.Payload.assets.MrTrust.ico" />
|
||||
|
||||
Reference in New Issue
Block a user