From cbef7c6181b8cf90fbe6e6029b0560d1d6e2366b Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Wed, 3 Sep 2025 01:25:00 -0700 Subject: [PATCH 1/5] Add manual trigger to nightly (#662) --- .github/workflows/nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 53735cf..c15b877 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -3,6 +3,8 @@ name: Nightly on: schedule: - cron: "0 8 * * *" + workflow_dispatch: + jobs: build: # runs-on: macOS-latest From 61eed5987caaa5258fb169c544bef3cb5e2c0c6f Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Wed, 3 Sep 2025 01:39:59 -0700 Subject: [PATCH 2/5] Add permissions to nightly (#663) * Add permissions to nightly * Add archives --- .github/workflows/nightly.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c15b877..12bbc25 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -9,6 +9,10 @@ jobs: build: # runs-on: macOS-latest runs-on: macos-15 + permissions: + id-token: write + contents: write + attestations: write timeout-minutes: 10 steps: - uses: actions/checkout@v5 @@ -45,9 +49,14 @@ jobs: id: attest uses: actions/attest-build-provenance@v2 with: - subject-path: 'Secretive.zip' + subject-path: 'Secretive.zip, Xcode_Archive.zip' - name: Upload App to Artifacts uses: actions/upload-artifact@v4 with: name: Secretive.zip path: Secretive.zip + - name: Upload Archive to Artifacts + uses: actions/upload-artifact@v4 + with: + name: Xcode_Archive.zip + path: Xcode_Archive.zip From c4605fb60ed2214c41a86e5f11d3227c0d692280 Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Wed, 3 Sep 2025 01:49:20 -0700 Subject: [PATCH 3/5] Update nightly.yml (#665) --- .github/workflows/nightly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 12bbc25..c4e7ad3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -39,7 +39,7 @@ jobs: - name: Create ZIPs run: | ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive/Products/Applications/Secretive.app ./Secretive.zip - ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive ./Archive.zip + ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive ./Xcode_Archive.zip - name: Notarize env: APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} From 416a7d5f40849f01c3603c0aa039646bc477061f Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Wed, 3 Sep 2025 21:38:22 -0700 Subject: [PATCH 4/5] Fix attestation issue from double-zip file process in upload action (#666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove archives since we don’t strip symbols anyway. * Attest upload result. --- .github/workflows/nightly.yml | 18 +++++++----------- .github/workflows/release.yml | 23 +++++++++-------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c4e7ad3..0d156bb 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -36,27 +36,23 @@ jobs: sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Secretive/Credits.rtf - name: Build run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive - - name: Create ZIPs + - name: Create ZIP run: | ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive/Products/Applications/Secretive.app ./Secretive.zip - ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive ./Xcode_Archive.zip - name: Notarize env: APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} run: xcrun notarytool submit --key ~/.private_keys/AuthKey_$APPLE_API_KEY_ID.p8 --key-id $APPLE_API_KEY_ID --issuer $APPLE_API_ISSUER Secretive.zip - - name: Attest - id: attest - uses: actions/attest-build-provenance@v2 - with: - subject-path: 'Secretive.zip, Xcode_Archive.zip' - name: Upload App to Artifacts + id: upload uses: actions/upload-artifact@v4 with: name: Secretive.zip path: Secretive.zip - - name: Upload Archive to Artifacts - uses: actions/upload-artifact@v4 + - name: Attest + id: attest + uses: actions/attest-build-provenance@v2 with: - name: Xcode_Archive.zip - path: Xcode_Archive.zip + subject-name: "Secretive.zip" + subject-digest: ${{ steps.upload.outputs.artifact-digest }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ebd0b01..da81788 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,39 +56,34 @@ jobs: sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Secretive/Credits.rtf - name: Build run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive - - name: Create ZIPs + - name: Create ZIP run: | ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive/Products/Applications/Secretive.app ./Secretive.zip - ditto -c -k --sequesterRsrc --keepParent Archive.xcarchive ./Xcode_Archive.zip - name: Notarize env: APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} run: xcrun notarytool submit --key ~/.private_keys/AuthKey_$APPLE_API_KEY_ID.p8 --key-id $APPLE_API_KEY_ID --issuer $APPLE_API_ISSUER Secretive.zip + - name: Upload App to Artifacts + id: upload + uses: actions/upload-artifact@v4 + with: + name: Secretive.zip + path: Secretive.zip - name: Attest id: attest uses: actions/attest-build-provenance@v2 with: - subject-path: 'Secretive.zip, Xcode_Archive.zip' + subject-name: "Secretive.zip" + subject-digest: ${{ steps.upload.outputs.artifact-digest }} - name: Create Release run: | sed -i.tmp "s/RUN_ID/$RUN_ID/g" .github/templates/release.md sed -i.tmp "s/ATTESTATION_ID/$ATTESTATION_ID/g" .github/templates/release.md gh release create $TAG_NAME -d -F .github/templates/release.md gh release upload Secretive.zip - gh release upload Xcode_Archive.zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ github.ref }} RUN_ID: ${{ github.run_id }} ATTESTATION_ID: ${{ steps.attest.outputs.attestation-id }} - - name: Upload App to Artifacts - uses: actions/upload-artifact@v4 - with: - name: Secretive.zip - path: Secretive.zip - - name: Upload Archive to Artifacts - uses: actions/upload-artifact@v4 - with: - name: Xcode_Archive.zip - path: Xcode_Archive.zip From 412687467bba97208f75b82ecc8a14d9e20ae6fc Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Wed, 3 Sep 2025 22:01:44 -0700 Subject: [PATCH 5/5] Digest wants 'sha256:' prefix that the upload step doesn't add for some reason (#667) --- .github/workflows/nightly.yml | 2 +- .../CryptoKitMigrator.swift | 28 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 0d156bb..dc61369 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -55,4 +55,4 @@ jobs: uses: actions/attest-build-provenance@v2 with: subject-name: "Secretive.zip" - subject-digest: ${{ steps.upload.outputs.artifact-digest }} + subject-digest: sha256:${{ steps.upload.outputs.artifact-digest }} diff --git a/Sources/Packages/Sources/SecureEnclaveSecretKit/CryptoKitMigrator.swift b/Sources/Packages/Sources/SecureEnclaveSecretKit/CryptoKitMigrator.swift index ddcc042..a4c69d2 100644 --- a/Sources/Packages/Sources/SecureEnclaveSecretKit/CryptoKitMigrator.swift +++ b/Sources/Packages/Sources/SecureEnclaveSecretKit/CryptoKitMigrator.swift @@ -30,7 +30,7 @@ extension SecureEnclave { SecItemCopyMatching(privateAttributes, &privateUntyped) guard let privateTyped = privateUntyped as? [[CFString: Any]] else { return } let migratedPublicKeys = Set(store.secrets.map(\.publicKey)) - var migrated = false + var migratedAny = false for key in privateTyped { let name = key[kSecAttrLabel] as? String ?? String(localized: .unnamedSecret) let id = key[kSecAttrApplicationLabel] as! Data @@ -45,20 +45,24 @@ extension SecureEnclave { // Best guess. let auth: AuthenticationRequirement = String(describing: accessControl) .contains("DeviceOwnerAuthentication") ? .presenceRequired : .unknown - let parsed = try CryptoKit.SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: tokenObjectID) - let secret = Secret(id: UUID().uuidString, name: name, publicKey: parsed.publicKey.x963Representation, attributes: Attributes(keyType: .init(algorithm: .ecdsa, size: 256), authentication: auth)) - guard !migratedPublicKeys.contains(parsed.publicKey.x963Representation) else { - logger.log("Skipping \(name), public key already present. Marking as migrated.") + do { + let parsed = try CryptoKit.SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: tokenObjectID) + let secret = Secret(id: UUID().uuidString, name: name, publicKey: parsed.publicKey.x963Representation, attributes: Attributes(keyType: .init(algorithm: .ecdsa, size: 256), authentication: auth)) + guard !migratedPublicKeys.contains(parsed.publicKey.x963Representation) else { + logger.log("Skipping \(name), public key already present. Marking as migrated.") + try markMigrated(secret: secret, oldID: id) + continue + } + logger.log("Migrating \(name).") + try store.saveKey(tokenObjectID, name: name, attributes: secret.attributes) + logger.log("Migrated \(name).") try markMigrated(secret: secret, oldID: id) - continue + migratedAny = true + } catch { + logger.error("Failed to migrate \(name): \(error).") } - logger.log("Migrating \(name).") - try store.saveKey(tokenObjectID, name: name, attributes: secret.attributes) - logger.log("Migrated \(name).") - try markMigrated(secret: secret, oldID: id) - migrated = true } - if migrated { + if migratedAny { store.reloadSecrets() } }