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
|
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
|
test: lint
|
||||||
go test -v ./...
|
go test -v ./...
|
||||||
|
|
||||||
|
# Lint the code
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run --timeout 5m
|
golangci-lint run --timeout 5m
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
clean:
|
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 (
|
require (
|
||||||
|
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // 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/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/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
golang.org/x/term v0.32.0 // indirect
|
golang.org/x/term v0.32.0 // indirect
|
||||||
|
@ -332,8 +332,14 @@ func TestIdentityFromEntropyEdgeCases(t *testing.T) {
|
|||||||
expectError: false,
|
expectError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "random valid entropy",
|
name: "random valid entropy",
|
||||||
entropy: func() []byte { b := make([]byte, 32); rand.Read(b); return b }(),
|
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,
|
expectError: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -658,7 +664,9 @@ func BenchmarkDeriveEntropy(b *testing.B) {
|
|||||||
|
|
||||||
func BenchmarkIdentityFromEntropy(b *testing.B) {
|
func BenchmarkIdentityFromEntropy(b *testing.B) {
|
||||||
entropy := make([]byte, 32)
|
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()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -795,8 +803,7 @@ func TestLargeMessageEncryption(t *testing.T) {
|
|||||||
func TestRandomMnemonicDeterministicGeneration(t *testing.T) {
|
func TestRandomMnemonicDeterministicGeneration(t *testing.T) {
|
||||||
// Generate a random mnemonic using the BIP39 library
|
// Generate a random mnemonic using the BIP39 library
|
||||||
entropy := make([]byte, 32) // 256 bits for 24-word mnemonic
|
entropy := make([]byte, 32) // 256 bits for 24-word mnemonic
|
||||||
_, err := rand.Read(entropy)
|
if _, err := rand.Read(entropy); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to generate random entropy: %v", err)
|
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
|
// Generate 1 MB of random data for encryption test
|
||||||
testData := make([]byte, testDataSizeMegabyte)
|
testData := make([]byte, testDataSizeMegabyte)
|
||||||
_, err = rand.Read(testData)
|
if _, err := rand.Read(testData); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to generate random test data: %v", err)
|
t.Fatalf("failed to generate random test data: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user