Skip to content

Commit 0f84320

Browse files
committed
ci: security-hardened CI + release with brew tap auto-update
CI workflow: - Read-only permissions (contents: read) - Skips fork PRs to prevent untrusted code execution - Build + test + version verify on macos-15 Release workflow: - Only runs on onllm-dev/onvault repo (not forks) - Requires 'release' environment (manual approval in GitHub Settings) - Verifies tag version matches VERSION file - Runs full test suite before building dist - Packages tarball with install script + SHA-256 checksums - Creates GitHub Release with release notes - Auto-updates onllm-dev/homebrew-tap formula via deploy key - Pre-release tags (rc/beta/alpha) skip brew tap update - Deploy key cleaned up after use Security setup required: 1. Settings → Environments → Create "release" with required reviewers 2. Settings → Secrets → HOMEBREW_TAP_DEPLOY_KEY (SSH key with write to homebrew-tap) 3. Settings → Rules → Tag protection → v* (only maintainers can push tags) Usage: git tag v0.1.0 && git push origin v0.1.0 Users: brew tap onllm-dev/tap && brew install onvault
1 parent c0ed088 commit 0f84320

2 files changed

Lines changed: 139 additions & 23 deletions

File tree

.github/workflows/ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,19 @@ on:
66
pull_request:
77
branches: [main]
88

9+
# Minimal permissions — CI only reads code and runs tests
10+
permissions:
11+
contents: read
12+
913
jobs:
1014
build-and-test:
1115
runs-on: macos-15
16+
17+
# Only run on trusted events — not from forks on PRs
18+
if: >
19+
github.event_name == 'push' ||
20+
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
21+
1222
steps:
1323
- uses: actions/checkout@v4
1424

@@ -22,3 +32,6 @@ jobs:
2232

2333
- name: Run tests
2434
run: make test
35+
36+
- name: Verify version
37+
run: ./onvault --version

.github/workflows/release.yml

Lines changed: 126 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,36 @@ on:
55
tags:
66
- 'v*'
77

8+
# Only maintainers can push tags — this is enforced by GitHub branch/tag protection rules.
9+
# Set up tag protection: Settings → Rules → Tag protection → Add rule → v*
10+
11+
# Minimal required permissions
812
permissions:
9-
contents: write
13+
contents: write # Create GitHub Release + upload assets
1014

1115
jobs:
1216
build-and-release:
1317
runs-on: macos-15
18+
19+
# SECURITY: Only run if the tag was pushed by a repo admin/maintainer
20+
# This prevents forked PRs or compromised tokens from triggering releases
21+
if: github.repository == 'onllm-dev/onvault'
22+
23+
environment: release # Requires manual approval in GitHub Settings → Environments
24+
1425
steps:
1526
- uses: actions/checkout@v4
1627

28+
- name: Verify tag matches VERSION file
29+
run: |
30+
TAG_VERSION="${GITHUB_REF_NAME#v}"
31+
FILE_VERSION=$(cat VERSION)
32+
if [ "$TAG_VERSION" != "$FILE_VERSION" ]; then
33+
echo "ERROR: Tag version ($TAG_VERSION) does not match VERSION file ($FILE_VERSION)"
34+
exit 1
35+
fi
36+
echo "Version verified: $TAG_VERSION"
37+
1738
- name: Extract version from tag
1839
id: version
1940
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
@@ -30,7 +51,6 @@ jobs:
3051
3152
- name: Build distribution
3253
run: |
33-
echo "${{ steps.version.outputs.VERSION }}" > VERSION
3454
make clean
3555
make dist
3656
@@ -49,7 +69,6 @@ jobs:
4969
cp install/com.onvault.daemon.plist dist/onvault-${VERSION}-macos-arm64/
5070
cp -r defaults dist/onvault-${VERSION}-macos-arm64/
5171
52-
# Create install script
5372
cat > dist/onvault-${VERSION}-macos-arm64/install.sh << 'INSTALL_EOF'
5473
#!/bin/bash
5574
set -e
@@ -68,48 +87,41 @@ jobs:
6887
INSTALL_EOF
6988
chmod +x dist/onvault-${VERSION}-macos-arm64/install.sh
7089
71-
# Create tarball
7290
cd dist
7391
tar czf onvault-${VERSION}-macos-arm64.tar.gz onvault-${VERSION}-macos-arm64/
74-
75-
# Generate SHA-256 checksum
7692
shasum -a 256 onvault-${VERSION}-macos-arm64.tar.gz > onvault-${VERSION}-macos-arm64.tar.gz.sha256
7793
7894
- name: Generate release notes
79-
id: notes
8095
run: |
8196
VERSION=${{ steps.version.outputs.VERSION }}
8297
cat > release_notes.md << EOF
8398
## onvault v${VERSION}
8499
85100
Seamless file encryption & per-process access control for macOS.
86101
87-
### Installation
102+
### Install via Homebrew
88103
89104
\`\`\`bash
90-
# Prerequisites
91-
brew install --cask macfuse
105+
brew tap onllm-dev/tap
106+
brew install onvault
107+
\`\`\`
92108
93-
# Download and install
109+
### Install manually
110+
111+
\`\`\`bash
112+
brew install --cask macfuse # prerequisite
94113
tar xzf onvault-${VERSION}-macos-arm64.tar.gz
95114
cd onvault-${VERSION}-macos-arm64
96115
./install.sh
97-
98-
# Get started
99-
onvault init
100-
onvault start
101-
onvault unlock
102-
onvault vault add ~/.ssh --smart
103116
\`\`\`
104117
105-
### Build from Source
118+
### Get started
106119
107120
\`\`\`bash
108-
brew install openssl@3 argon2
109-
brew install --cask macfuse
110-
git clone https://github.com/onllm-dev/onvault.git
111-
cd onvault
112-
make && make test && make dist
121+
onvault init # First-time setup
122+
onvault start # Start daemon
123+
onvault unlock # Authenticate
124+
onvault vault add ~/.ssh --smart # Protect SSH keys
113125
\`\`\`
114126
115127
### Requirements
@@ -133,3 +145,94 @@ jobs:
133145
files: |
134146
dist/onvault-${{ steps.version.outputs.VERSION }}-macos-arm64.tar.gz
135147
dist/onvault-${{ steps.version.outputs.VERSION }}-macos-arm64.tar.gz.sha256
148+
149+
# Update Homebrew tap — uses a deploy key with write access to homebrew-tap repo
150+
# Set up: Settings → Secrets → HOMEBREW_TAP_DEPLOY_KEY (SSH private key)
151+
- name: Update Homebrew tap
152+
if: "!contains(github.ref_name, '-rc') && !contains(github.ref_name, '-beta') && !contains(github.ref_name, '-alpha')"
153+
env:
154+
DEPLOY_KEY: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }}
155+
run: |
156+
if [ -z "$DEPLOY_KEY" ]; then
157+
echo "HOMEBREW_TAP_DEPLOY_KEY not set — skipping brew tap update"
158+
exit 0
159+
fi
160+
161+
VERSION=${{ steps.version.outputs.VERSION }}
162+
SHA256=$(cat dist/onvault-${VERSION}-macos-arm64.tar.gz.sha256 | awk '{print $1}')
163+
164+
# Set up SSH for homebrew-tap repo
165+
mkdir -p ~/.ssh
166+
echo "$DEPLOY_KEY" > ~/.ssh/tap_deploy_key
167+
chmod 600 ~/.ssh/tap_deploy_key
168+
export GIT_SSH_COMMAND="ssh -i ~/.ssh/tap_deploy_key -o StrictHostKeyChecking=no"
169+
170+
git clone git@github.com:onllm-dev/homebrew-tap.git /tmp/homebrew-tap-update
171+
cd /tmp/homebrew-tap-update
172+
173+
# Update the formula with new version and SHA
174+
cat > Formula/onvault.rb << FORMULA_EOF
175+
class Onvault < Formula
176+
desc "Seamless file encryption & per-process access control for macOS"
177+
homepage "https://github.com/onllm-dev/onvault"
178+
version "${VERSION}"
179+
license "GPL-3.0-only"
180+
181+
on_macos do
182+
if Hardware::CPU.arm?
183+
url "https://github.com/onllm-dev/onvault/releases/download/v${VERSION}/onvault-${VERSION}-macos-arm64.tar.gz"
184+
sha256 "${SHA256}"
185+
end
186+
end
187+
188+
depends_on :macos
189+
depends_on "macfuse" => :cask
190+
191+
def install
192+
bin.install "onvault"
193+
bin.install "onvaultd"
194+
(share/"onvault/defaults").install Dir["defaults/*"]
195+
(prefix/"com.onvault.daemon.plist").install "com.onvault.daemon.plist"
196+
end
197+
198+
def post_install
199+
launch_agents = Pathname.new("#{Dir.home}/Library/LaunchAgents")
200+
launch_agents.mkpath
201+
plist_dst = launch_agents/"com.onvault.daemon.plist"
202+
unless plist_dst.exist?
203+
plist_dst.make_symlink(prefix/"com.onvault.daemon.plist")
204+
end
205+
end
206+
207+
def caveats
208+
<<~EOS
209+
onvault requires macFUSE to be installed and approved:
210+
211+
brew install --cask macfuse
212+
# System Settings → Privacy & Security → Approve
213+
# Reboot required after first install
214+
215+
Get started:
216+
217+
onvault init
218+
onvault start
219+
onvault unlock
220+
onvault vault add ~/.ssh --smart
221+
222+
Documentation: https://github.com/onllm-dev/onvault
223+
EOS
224+
end
225+
226+
test do
227+
assert_match version.to_s, shell_output("#{bin}/onvault --version")
228+
end
229+
end
230+
FORMULA_EOF
231+
232+
git add Formula/onvault.rb
233+
git -c user.name="onvault-release" -c user.email="release@onllm.dev" \
234+
commit -m "onvault ${VERSION}"
235+
git push origin main
236+
237+
# Clean up deploy key
238+
rm -f ~/.ssh/tap_deploy_key

0 commit comments

Comments
 (0)