latest, trying to get sep to work without ADP membership
This commit is contained in:
parent
354681b298
commit
2443256338
105
Makefile
105
Makefile
@ -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
182
PROVISIONING_GUIDE.md
Normal 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
24
entitlements.plist
Normal 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
15
go.mod
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user