latest, trying to get sep to work without ADP membership

This commit is contained in:
Jeffrey Paul 2025-05-29 04:03:40 -07:00
parent 354681b298
commit 2443256338
6 changed files with 1532 additions and 8 deletions

105
Makefile
View File

@ -1,10 +1,113 @@
# Makefile for Secret Manager macOS App with Code Signing
# Configuration - Update these with your Apple Developer details
DEVELOPER_ID_DEV = "Apple Development: YOUR_NAME (TEAM_ID)"
DEVELOPER_ID_DIST = "Developer ID Application: YOUR_NAME (TEAM_ID)"
ENTITLEMENTS = entitlements.plist
BINARY_NAME = secret
# Build directories
BUILD_DIR = build
DIST_DIR = dist
default: test
# Development build with code signing
build-dev: clean
@echo "Building development version..."
go build -o $(BINARY_NAME) cmd/secret/main.go
@echo "Code signing for development..."
codesign --sign $(DEVELOPER_ID_DEV) \
--entitlements $(ENTITLEMENTS) \
--options runtime \
--force \
--verbose \
./$(BINARY_NAME)
@echo "Development build complete: ./$(BINARY_NAME)"
# Production build with code signing
build-prod: clean
@echo "Building production version..."
go build -ldflags="-s -w" -o $(BINARY_NAME) cmd/secret/main.go
@echo "Code signing for distribution..."
codesign --sign $(DEVELOPER_ID_DIST) \
--entitlements $(ENTITLEMENTS) \
--options runtime \
--force \
--verbose \
./$(BINARY_NAME)
@echo "Production build complete: ./$(BINARY_NAME)"
# Build without code signing (for testing compilation)
build-unsigned: clean
@echo "Building unsigned version..."
go build -o $(BINARY_NAME) cmd/secret/main.go
@echo "Unsigned build complete: ./$(BINARY_NAME)"
# Verify code signing
verify:
@echo "Verifying code signature..."
codesign -dv --verbose=4 ./$(BINARY_NAME)
@echo "\nVerifying entitlements..."
codesign -d --entitlements :- ./$(BINARY_NAME)
# Check certificates and provisioning profiles
check-signing:
@echo "Available code signing identities:"
security find-identity -v -p codesigning
@echo "\nInstalled provisioning profiles:"
ls -la ~/Library/MobileDevice/Provisioning\ Profiles/ 2>/dev/null || echo "No provisioning profiles found"
# Test with linting
test: lint
go test -v ./...
# Lint the code
lint:
golangci-lint run --timeout 5m
# Clean build artifacts
clean:
rm -f ./secret
rm -f ./$(BINARY_NAME)
rm -rf $(BUILD_DIR) $(DIST_DIR)
# Create app bundle structure (for future app store distribution)
bundle: build-prod
@echo "Creating app bundle..."
mkdir -p $(DIST_DIR)/Secret.app/Contents/MacOS
mkdir -p $(DIST_DIR)/Secret.app/Contents/Resources
cp $(BINARY_NAME) $(DIST_DIR)/Secret.app/Contents/MacOS/
@echo "App bundle created in $(DIST_DIR)/Secret.app"
# Install to /usr/local/bin (development)
install-dev: build-dev
@echo "Installing to /usr/local/bin..."
sudo cp $(BINARY_NAME) /usr/local/bin/
@echo "Installed to /usr/local/bin/$(BINARY_NAME)"
# Uninstall from /usr/local/bin
uninstall:
@echo "Removing from /usr/local/bin..."
sudo rm -f /usr/local/bin/$(BINARY_NAME)
@echo "Uninstalled $(BINARY_NAME)"
# Help target
help:
@echo "Available targets:"
@echo " build-dev - Build and sign for development"
@echo " build-prod - Build and sign for production/distribution"
@echo " build-unsigned - Build without code signing (testing only)"
@echo " verify - Verify code signature and entitlements"
@echo " check-signing - Show available certificates and profiles"
@echo " test - Run tests with linting"
@echo " lint - Run linter only"
@echo " clean - Remove build artifacts"
@echo " bundle - Create macOS app bundle"
@echo " install-dev - Install development build to /usr/local/bin"
@echo " uninstall - Remove from /usr/local/bin"
@echo " help - Show this help"
@echo ""
@echo "Before using build-dev or build-prod, update the DEVELOPER_ID variables"
@echo "in this Makefile with your Apple Developer certificate names."
.PHONY: default build-dev build-prod build-unsigned verify check-signing test lint clean bundle install-dev uninstall help

182
PROVISIONING_GUIDE.md Normal file
View File

@ -0,0 +1,182 @@
# Provisioning Profile Setup for macOS Biometric Authentication
## Prerequisites
1. Apple Developer Account (paid membership required)
2. macOS development machine
3. Xcode installed (for code signing tools)
## Step 1: Log into Apple Developer Portal
1. Go to [developer.apple.com](https://developer.apple.com)
2. Sign in with your Apple Developer account
3. Navigate to "Certificates, Identifiers & Profiles"
## Step 2: Create App ID
1. Click "Identifiers" in the sidebar
2. Click the "+" button to create a new identifier
3. Select "App IDs" and click "Continue"
4. Choose "App" (not App Clip) and click "Continue"
5. Fill in the details:
- **Description**: `Secret Manager macOS App`
- **Bundle ID**: Select "Explicit" and enter `berlin.sneak.pkg.secret`
6. In the "Capabilities" section, enable:
- **Keychain Sharing** (this is essential for keychain access)
- Leave other capabilities unchecked unless specifically needed
7. Click "Continue" and then "Register"
## Step 3: Create/Verify Development Certificate
1. Click "Certificates" in the sidebar
2. Click the "+" button if you need a new certificate
3. Under "Development", select "Mac Development"
4. Follow the instructions to generate a Certificate Signing Request (CSR):
- Open Keychain Access on your Mac
- Go to Keychain Access → Certificate Assistant → Request a Certificate from a Certificate Authority
- Enter your email address and name
- Select "Saved to disk" and "Let me specify key pair information"
- Click "Continue" and save the CSR file
5. Upload the CSR file and download the certificate
6. Double-click the downloaded certificate to install it in Keychain Access
## Step 4: Register Development Device
1. Click "Devices" in the sidebar
2. Click the "+" button to register a new device
3. Select "macOS" as the platform
4. Get your Mac's hardware UUID:
```bash
system_profiler SPHardwareDataType | grep "Hardware UUID"
```
5. Enter:
- **Device Name**: Your Mac's name (e.g., "John's MacBook Pro")
- **Device ID (UUID)**: The hardware UUID from step 4
6. Click "Continue" and then "Register"
## Step 5: Create Development Provisioning Profile
1. Click "Profiles" in the sidebar
2. Click the "+" button to create a new profile
3. Under "Development", select "Mac App Development"
4. Click "Continue"
5. Select your App ID: `berlin.sneak.pkg.secret`
6. Click "Continue"
7. Select your development certificate
8. Click "Continue"
9. Select your registered Mac device
10. Click "Continue"
11. Enter a profile name: `Secret Manager macOS Development`
12. Click "Generate"
13. Download the provisioning profile
## Step 6: Install Provisioning Profile
1. Double-click the downloaded `.provisionprofile` file to install it
2. Or manually copy it to: `~/Library/MobileDevice/Provisioning Profiles/`
## Step 7: Code Signing Setup
### Option A: Manual Code Signing
Add these flags when building your Go binary:
```bash
# Build the binary
go build -o secret cmd/secret/main.go
# Sign the binary
codesign --sign "Apple Development: YOUR_NAME (TEAM_ID)" \
--entitlements entitlements.plist \
--options runtime \
--force \
./secret
```
### Option B: Using Makefile
Update your Makefile to include code signing:
```makefile
DEVELOPER_ID = "Apple Development: YOUR_NAME (TEAM_ID)"
ENTITLEMENTS = entitlements.plist
secret:
go build -o secret cmd/secret/main.go
codesign --sign $(DEVELOPER_ID) \
--entitlements $(ENTITLEMENTS) \
--options runtime \
--force \
./secret
.PHONY: secret
```
## Step 8: Verify Code Signing
Check that your binary is properly signed:
```bash
# Check code signature
codesign -dv --verbose=4 ./secret
# Check entitlements
codesign -d --entitlements :- ./secret
```
## Step 9: Test Biometric Authentication
Run your app and verify that:
1. Touch ID/Face ID prompts appear when accessing keychain
2. No entitlement errors occur
3. Keychain operations work correctly
## Troubleshooting
### Common Issues:
1. **errSecMissingEntitlement (-34018)**
- Ensure your provisioning profile includes keychain access
- Verify code signing is applied correctly
- Check that bundle ID matches exactly
2. **No biometric prompt appears**
- Verify access control flags in your Security Framework calls
- Ensure device has biometric authentication enabled
- Check system preferences for app permissions
3. **Code signing failures**
- Ensure certificate is installed in Keychain Access
- Verify team ID matches between certificate and provisioning profile
- Check that provisioning profile is installed
### Debug Commands:
```bash
# List installed certificates
security find-identity -v -p codesigning
# List provisioning profiles
ls ~/Library/MobileDevice/Provisioning\ Profiles/
# Check provisioning profile contents
security cms -D -i ~/Library/MobileDevice/Provisioning\ Profiles/YOUR_PROFILE.provisionprofile
```
## Production Distribution
For production distribution, you'll need to:
1. Create a "Developer ID Application" certificate
2. Create a "Developer ID" provisioning profile
3. Notarize your app with Apple
4. Staple the notarization ticket
This allows distribution outside the Mac App Store while maintaining system trust.
## Important Notes
- Keychain access groups are automatically included for explicit App IDs
- Biometric authentication requires proper access controls in your Security Framework calls
- The `com.apple.security.cs.disable-library-validation` entitlement may be needed for Go binaries
- Test thoroughly on a clean system to ensure all entitlements work correctly

24
entitlements.plist Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)berlin.sneak.pkg.secret</string>
</array>
<key>com.apple.application-identifier</key>
<string>$(AppIdentifierPrefix)berlin.sneak.pkg.secret</string>
<key>com.apple.developer.team-identifier</key>
<string>$(AppIdentifierPrefix)</string>
<key>get-task-allow</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<false/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<false/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<false/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

15
go.mod
View File

@ -15,10 +15,25 @@ require (
)
require (
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c // indirect
github.com/facebookincubator/sks v0.0.0-20250508161834-9be892919529 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/certificate-transparency-go v1.1.2 // indirect
github.com/google/certtostore v1.0.3-0.20230404221207-8d01647071cc // indirect
github.com/google/deck v0.0.0-20230104221208-105ad94aa8ae // indirect
github.com/google/go-attestation v0.5.1 // indirect
github.com/google/go-tpm v0.9.0 // indirect
github.com/google/go-tspi v0.3.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jgoguen/go-utils v0.0.0-20200211015258-b42ad41486fd // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/spf13/pflag v1.0.6 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect

1194
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -332,8 +332,14 @@ func TestIdentityFromEntropyEdgeCases(t *testing.T) {
expectError: false,
},
{
name: "random valid entropy",
entropy: func() []byte { b := make([]byte, 32); rand.Read(b); return b }(),
name: "random valid entropy",
entropy: func() []byte {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
panic(err) // In test context, panic is acceptable for setup failures
}
return b
}(),
expectError: false,
},
}
@ -658,7 +664,9 @@ func BenchmarkDeriveEntropy(b *testing.B) {
func BenchmarkIdentityFromEntropy(b *testing.B) {
entropy := make([]byte, 32)
rand.Read(entropy)
if _, err := rand.Read(entropy); err != nil {
b.Fatalf("failed to generate random entropy: %v", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
@ -795,8 +803,7 @@ func TestLargeMessageEncryption(t *testing.T) {
func TestRandomMnemonicDeterministicGeneration(t *testing.T) {
// Generate a random mnemonic using the BIP39 library
entropy := make([]byte, 32) // 256 bits for 24-word mnemonic
_, err := rand.Read(entropy)
if err != nil {
if _, err := rand.Read(entropy); err != nil {
t.Fatalf("failed to generate random entropy: %v", err)
}
@ -842,8 +849,7 @@ func TestRandomMnemonicDeterministicGeneration(t *testing.T) {
// Generate 1 MB of random data for encryption test
testData := make([]byte, testDataSizeMegabyte)
_, err = rand.Read(testData)
if err != nil {
if _, err := rand.Read(testData); err != nil {
t.Fatalf("failed to generate random test data: %v", err)
}