Compare commits

...
5 Commits
Author SHA1 Message Date
Ian 9f57dbf29a Prompt to update when a newer release is out 2026-11-13 15:22:11 -05:00
ian-at-strix 27a1ac2d74 Update README to remove old asset
Removed outdated asset links from README.
2026-10-26 14:19:01 -04:00
ian-at-strix 55e0f5f7b7 Claude demo 2026-10-26 14:15:26 -04:00
ian-at-strix 89b2bda2d8 Update README.md 2026-10-26 13:47:15 -04:00
ian-at-strix 7685049e68 Fix release notes (#101) 2026-10-26 13:00:37 -04:00
9 changed files with 63 additions and 10 deletions

No files matched your search

+1 -3
View File
@@ -27,9 +27,7 @@ jobs:
## Command line
\`\`\`sh
cargo install strix-firewall
\`\`\`
**Command-line installs do not include machine-wide screening.**
\`\`\`sh
curl --proto '=https' --tlsv1.2 -LsSf $url/strix-firewall-installer.sh | sh
+1 -2
View File
@@ -302,8 +302,7 @@ jobs:
secrets: inherit
# publish jobs get escalated permissions
permissions:
"id-token": "write"
"packages": "write"
"contents": "read"
announce:
needs:
+3 -1
View File
@@ -1,10 +1,12 @@
# Strix's Dependency Firewall
Stops malicious packages before they install. Built by [Strix](https://strix.ai/blog/firewall-announcement).
Stops malicious packages before they install. Built by [Strix](https://strix.ai): read [the blogpost](https://www.strix.ai/blog/firewall-announcement).
Screening runs on your device: downloads go straight to the registry, never through a Strix server.
Each package's name and version are looked up [Strix's malicious-package blocklist](https://github.com/usestrix/firewall-blocklist), so installs are blocked system-wide *before* reaching your machine.
https://github.com/user-attachments/assets/835411b1-5c89-409f-b98a-cb238310429c
## Install
**Machine-wide**, from the [latest release](https://github.com/usestrix/firewall/releases/latest):
+3
View File
@@ -14,3 +14,6 @@ post-announce-jobs = ["./release-notes"]
global-artifacts-jobs = ["./build-macos-pkg"]
github-build-setup = "../build-setup.yml"
targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"]
[dist.github-custom-job-permissions]
"publish-crates" = { contents = "read" }
+13
View File
@@ -55,6 +55,7 @@ final class FirewallModel: NSObject, ObservableObject {
@Published private(set) var removed = false
@Published private(set) var screening = false
@Published private(set) var blocked: [BlockedPackage] = []
@Published private(set) var update: String?
private let logger = Logger(subsystem: FirewallIDs.appBundleID, category: "installer")
private var pendingRequest: (request: OSSystemExtensionRequest, continuation: CheckedContinuation<Void, Error>)?
@@ -76,6 +77,7 @@ final class FirewallModel: NSObject, ObservableObject {
Task { await install() }
}
Task { await watchBlocks() }
Task { await watchUpdates() }
}
// MARK: - Flows
@@ -246,6 +248,17 @@ final class FirewallModel: NSObject, ObservableObject {
}
}
/// Asks again every day until the user updates.
private func watchUpdates() async {
while true {
if let version = await Updates.available() {
update = version
Updates.prompt(version)
}
try? await Task.sleep(nanoseconds: 86_400_000_000_000)
}
}
private func stage(_ step: ReferenceWritableKeyPath<FirewallModel, StepStatus>,
running: String,
work: @MainActor () async throws -> String) async -> Bool {
+6
View File
@@ -7,6 +7,12 @@ struct MenuBarView: View {
var body: some View {
Text(model.screening ? "Screening downloads" : "Not running")
if let version = model.update {
Button("Update to \(version)") {
Updates.download(version)
}
}
Divider()
Button("Setup") {
+32
View File
@@ -0,0 +1,32 @@
import AppKit
enum Updates {
static let current = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? ""
private struct Release: Decodable {
let tag_name: String
}
/// The latest release's version, when it is newer than this app.
static func available() async -> String? {
let latest = URL(string: "https://api.github.com/repos/usestrix/firewall/releases/latest")!
guard let (data, _) = try? await URLSession.shared.data(from: latest),
let release = try? JSONDecoder().decode(Release.self, from: data) else { return nil }
let version = release.tag_name.hasPrefix("v") ? String(release.tag_name.dropFirst()) : release.tag_name
return version.compare(current, options: .numeric) == .orderedDescending ? version : nil
}
static func download(_ version: String) {
NSWorkspace.shared.open(URL(string: "https://github.com/usestrix/firewall/releases/download/v\(version)/Firewall.pkg")!)
}
@MainActor static func prompt(_ version: String) {
let alert = NSAlert()
alert.messageText = "Firewall \(version) is available"
alert.informativeText = "You have \(current). Download the installer and open it to update."
alert.addButton(withTitle: "Download")
alert.addButton(withTitle: "Later")
NSApp.activate(ignoringOtherApps: true)
if alert.runModal() == .alertFirstButtonReturn { download(version) }
}
}
+2 -2
View File
@@ -28,7 +28,7 @@ export NE_PROVIDER
APP_ID=com.usestrix.firewall
EXT_ID=com.usestrix.firewall.extension
VERSION=0.1
VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' ../core/Cargo.toml)
INSTALLER_IDENTITY=${INSTALLER_IDENTITY:-Developer ID Installer}
PROFILES="$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
@@ -48,7 +48,7 @@ build() {
xcodegen generate >/dev/null
xcodebuild -project Firewall.xcodeproj -scheme StrixFirewall -configuration $CONFIGURATION \
-destination generic/platform=macOS \
-derivedDataPath build CURRENT_PROJECT_VERSION="$(date +%s)" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO \
-derivedDataPath build CURRENT_PROJECT_VERSION="$(date +%s)" MARKETING_VERSION="$VERSION" CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO \
CODE_SIGN_IDENTITY="" CODE_SIGN_ENTITLEMENTS="" build >/dev/null
}
+2 -2
View File
@@ -43,7 +43,7 @@ targets:
path: Extension/Info.plist
properties:
CFBundlePackageType: SYSX
CFBundleShortVersionString: "0.1"
CFBundleShortVersionString: $(MARKETING_VERSION)
CFBundleVersion: $(CURRENT_PROJECT_VERSION)
NSSystemExtensionUsageDescription: Firewall uses a network extension to screen package downloads before they install.
NetworkExtension:
@@ -104,7 +104,7 @@ targets:
info:
path: App/Info.plist
properties:
CFBundleShortVersionString: "0.1"
CFBundleShortVersionString: $(MARKETING_VERSION)
CFBundleVersion: $(CURRENT_PROJECT_VERSION)
LSMinimumSystemVersion: $(MACOSX_DEPLOYMENT_TARGET)
NSSystemExtensionUsageDescription: Firewall uses a network extension to screen package downloads before they install.