@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +266 -267
- package/package.json +2 -2
- package/pipeline/scripts/_notices.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +68 -68
- package/pipeline/skills/shared/README.md +70 -70
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -4,41 +4,45 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 0,
|
|
6
6
|
"name": "app-attest-attestation-verifier",
|
|
7
|
-
"prompt": "
|
|
8
|
-
"expected_output": "
|
|
7
|
+
"prompt": "Our backend team is writing the endpoint that receives App Attest attestation objects from the iOS client. List what the verifier has to check and what it should persist afterwards.",
|
|
8
|
+
"expected_output": "Walks through CBOR decoding, certificate chain validation against the App Attest root CA, nonce = SHA256(authData || SHA256(challenge)) matched against the certificate value under OID 1.2.840.113635.100.8.2, public key hash equal to keyId, RP ID hash equal to SHA256(teamID.bundleID), counter 0, aaguid for the expected environment, credentialId equal to keyId, then storing the public key and receipt and consuming the challenge only after success.",
|
|
9
9
|
"files": [],
|
|
10
10
|
"expectations": [
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
11
|
+
"Composes the nonce from authData and the hashed challenge, SHA256(authData || SHA256(challenge)), rather than hashing the challenge alone",
|
|
12
|
+
"Compares the nonce with the certificate extension at 1.2.840.113635.100.8.2",
|
|
13
|
+
"Checks the RP ID or App ID hash against team ID plus bundle ID",
|
|
14
|
+
"Checks aaguid for the expected environment and an initial counter of 0",
|
|
15
|
+
"Requires credentialId and the public key hash to match keyId",
|
|
16
|
+
"Keeps the public key and receipt after verification, not the raw attestation object"
|
|
15
17
|
]
|
|
16
18
|
},
|
|
17
19
|
{
|
|
18
20
|
"id": 1,
|
|
19
|
-
"name": "
|
|
20
|
-
"prompt": "
|
|
21
|
-
"expected_output": "
|
|
21
|
+
"name": "gift-card-assertion-flow",
|
|
22
|
+
"prompt": "We want to protect our 'redeem gift card' POST endpoint with App Attest assertions. Show the client side and explain what the server verifies.",
|
|
23
|
+
"expected_output": "Fetches a fresh one-time challenge per request, builds client data with the challenge plus method, path and a body digest, hashes it, calls generateAssertion, sends assertion and client data in headers; server checks that the stored key signed SHA256(authenticatorData || SHA256(clientData)), RP ID, a strictly increasing counter, and that the challenge and request context match.",
|
|
22
24
|
"files": [],
|
|
23
25
|
"expectations": [
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"Uses a fresh server-issued one-time challenge inside the client data",
|
|
27
|
+
"Binds request context or a body hash into the signed client data",
|
|
28
|
+
"Describes the signature as covering SHA256(authenticatorData || SHA256(clientData))",
|
|
29
|
+
"Server checks the RP ID hash and that the counter increases",
|
|
30
|
+
"Server confirms the challenge was issued and not yet consumed"
|
|
28
31
|
]
|
|
29
32
|
},
|
|
30
33
|
{
|
|
31
34
|
"id": 2,
|
|
32
|
-
"name": "
|
|
33
|
-
"prompt": "Review
|
|
34
|
-
"expected_output": "
|
|
35
|
+
"name": "integrity-plan-review",
|
|
36
|
+
"prompt": "Review our plan: cache the DeviceCheck token for a day, generate a new App Attest key each launch, retry every DCError with a new key, and use App Attest instead of OAuth sessions and certificate pinning. What would you change?",
|
|
37
|
+
"expected_output": "Makes DCDevice tokens single-use, keeps one key per account per device and warns that extra keys affect risk metrics, retries serverUnavailable reusing its keyId and clientDataHash while discarding the key for other attestation errors, explains invalidKey causes (already attested, not attested, rejected) without inventing causes such as system updates or enclave resets, and routes OAuth, sessions and pinning to the authentication and swift-security skills.",
|
|
35
38
|
"files": [],
|
|
36
39
|
"expectations": [
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
40
|
+
"Says DCDevice tokens are single-use and must not be cached",
|
|
41
|
+
"Keeps one key per account per device and mentions the key-count risk metric",
|
|
42
|
+
"On serverUnavailable, retries later reusing the identical keyId and clientDataHash",
|
|
43
|
+
"Discards the key and generates a new one for other attestation errors",
|
|
44
|
+
"Gives the three real invalidKey causes and does not invent others such as system updates or enclave resets",
|
|
45
|
+
"Routes OAuth, sessions and pinning to sibling skills instead of App Attest"
|
|
42
46
|
]
|
|
43
47
|
}
|
|
44
48
|
]
|
package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md
CHANGED
|
@@ -1,223 +1,187 @@
|
|
|
1
|
-
# Device Integrity
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
8. Store the verified public key and receipt for future assertion verification.
|
|
31
|
-
9. Mark the challenge consumed only after every verification step succeeds,
|
|
32
|
-
ideally in the same transaction that stores the key state.
|
|
33
|
-
|
|
34
|
-
See [Validating apps that connect to your server](https://sosumi.ai/documentation/devicecheck/validating-apps-that-connect-to-your-server) for the full server verification algorithm.
|
|
35
|
-
|
|
36
|
-
## Server-Side Assertion Verification
|
|
37
|
-
|
|
38
|
-
Your server must:
|
|
39
|
-
1. Decode the assertion (CBOR).
|
|
40
|
-
2. Recompute `clientDataHash = SHA256(clientData)`, where `clientData`
|
|
41
|
-
includes a one-time server challenge and request context.
|
|
42
|
-
3. Verify the signature using the stored public key over
|
|
1
|
+
# Device Integrity Patterns
|
|
2
|
+
|
|
3
|
+
Server verification, backend layout, error recovery and rollout for DeviceCheck
|
|
4
|
+
and App Attest. The client basics are in the [skill overview](../SKILL.md).
|
|
5
|
+
|
|
6
|
+
## Verifying an attestation on the server
|
|
7
|
+
|
|
8
|
+
Run every step; reject on the first failure.
|
|
9
|
+
|
|
10
|
+
1. Decode the attestation object and confirm the CBOR structure is well formed.
|
|
11
|
+
2. Extract the certificates and confirm they chain up to Apple's App Attest root.
|
|
12
|
+
3. Hash the challenge you issued (`clientDataHash = SHA256(challenge)`), concatenate
|
|
13
|
+
`authData` and that hash, then hash again: `nonce = SHA256(authData || clientDataHash)`.
|
|
14
|
+
4. The leaf certificate carries an extension, OID `1.2.840.113635.100.8.2`,
|
|
15
|
+
whose octet string has to be byte-for-byte equal to `nonce`.
|
|
16
|
+
5. Hash the credential certificate's public key. It must match the `keyId` the app sent.
|
|
17
|
+
6. The RP ID hash in `authData` must equal `SHA256(teamID + "." + bundleID)`.
|
|
18
|
+
7. The counter must be `0`, `aaguid` must name the environment you expect
|
|
19
|
+
(development or production), and `credentialId` must equal `keyId`.
|
|
20
|
+
8. Persist the public key you just verified plus the receipt. Keep those, not the raw attestation object.
|
|
21
|
+
9. Burn the challenge only once steps 1 to 8 all pass, ideally in the same
|
|
22
|
+
database transaction that writes the key record.
|
|
23
|
+
|
|
24
|
+
## Verifying an assertion on the server
|
|
25
|
+
|
|
26
|
+
1. Decode the CBOR assertion into `authenticatorData` and `signature`.
|
|
27
|
+
2. Compute `clientDataHash = SHA256(clientData)`. The client data carries the
|
|
28
|
+
one-time challenge and the request context.
|
|
29
|
+
3. Verify `signature` with the stored public key over
|
|
43
30
|
`SHA256(authenticatorData || clientDataHash)`.
|
|
44
|
-
4.
|
|
45
|
-
|
|
46
|
-
5. Confirm the embedded challenge
|
|
47
|
-
context
|
|
48
|
-
6.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
## Server
|
|
52
|
-
|
|
53
|
-
### Attestation
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
31
|
+
4. Check the RP ID hash, and require the counter to be greater than the stored
|
|
32
|
+
counter; on a key's first assertion anything above zero passes.
|
|
33
|
+
5. Confirm the embedded challenge is the one you issued and that the request
|
|
34
|
+
context (method, path, body digest) matches the request that arrived.
|
|
35
|
+
6. Consume the challenge and store the new counter only after everything passes,
|
|
36
|
+
preferably atomically.
|
|
37
|
+
|
|
38
|
+
## Server architecture
|
|
39
|
+
|
|
40
|
+
### Attestation versus assertion
|
|
41
|
+
|
|
42
|
+
| | Attestation | Assertion |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| When | Right after key generation | On every sensitive request |
|
|
45
|
+
| Proves | Real hardware, real app, holds this key | This request came from that attested instance |
|
|
46
|
+
| Frequency | Once per key | Once per request |
|
|
47
|
+
|
|
48
|
+
### Suggested services
|
|
49
|
+
|
|
50
|
+
- **Challenge endpoint** - hands out random nonces (16 or more bytes of
|
|
51
|
+
entropy). Store it with a short time to live (about five minutes), its purpose,
|
|
52
|
+
and the key or request it is meant for.
|
|
53
|
+
- **Attestation endpoint** - runs the attestation steps and stores the public
|
|
54
|
+
key and receipt indexed by `keyId`.
|
|
55
|
+
- **Assertion middleware** - sits in front of purchases, account changes and
|
|
56
|
+
other sensitive routes and runs the assertion steps.
|
|
57
|
+
|
|
58
|
+
Reject a challenge that is missing, expired, already used, or issued for a
|
|
59
|
+
different context. Consume it only after full verification; burning it the
|
|
60
|
+
moment it arrives turns a transient failure into a lost challenge and blocks a
|
|
61
|
+
safe retry.
|
|
62
|
+
|
|
63
|
+
### Risk assessment
|
|
64
|
+
|
|
65
|
+
Pair App Attest with Apple's fraud risk assessment for defense in depth. App
|
|
66
|
+
Attest confirms the binary is genuine; it cannot tell you whether the person
|
|
67
|
+
using it is abusing your service. It is also not user authentication, session
|
|
68
|
+
management, entitlement or subscription validation, TLS or pinning. Protected
|
|
69
|
+
endpoints still require all of those. Route sign-in work to `authentication`,
|
|
70
|
+
transport security to `ios-networking`, and Keychain or pinning policy to
|
|
71
|
+
`swift-security`.
|
|
72
|
+
|
|
73
|
+
## Handling `DCError`
|
|
82
74
|
|
|
83
75
|
```swift
|
|
84
76
|
import DeviceCheck
|
|
85
77
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Retry attestation later with the same keyId and clientDataHash
|
|
105
|
-
break
|
|
106
|
-
@unknown default:
|
|
107
|
-
break
|
|
108
|
-
}
|
|
78
|
+
enum AttestRecovery {
|
|
79
|
+
case retryLater, useDeviceCheck, inspectKeyState, fixInput, giveUp
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
func recovery(for error: DCError) -> AttestRecovery {
|
|
83
|
+
switch error.code {
|
|
84
|
+
case .unknownSystemFailure:
|
|
85
|
+
return .retryLater // transient system problem, back off
|
|
86
|
+
case .featureUnsupported:
|
|
87
|
+
return .useDeviceCheck // no App Attest on this device or OS
|
|
88
|
+
case .invalidKey:
|
|
89
|
+
return .inspectKeyState // regenerate only if the key is confirmed bad
|
|
90
|
+
case .invalidInput:
|
|
91
|
+
return .fixInput // malformed clientDataHash or keyId
|
|
92
|
+
case .serverUnavailable:
|
|
93
|
+
return .retryLater // same keyId and same hash on retry
|
|
94
|
+
@unknown default:
|
|
95
|
+
return .giveUp
|
|
109
96
|
}
|
|
110
97
|
}
|
|
111
98
|
```
|
|
112
99
|
|
|
113
|
-
## Retry
|
|
100
|
+
## Retry strategy
|
|
114
101
|
|
|
115
102
|
```swift
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return try await service.attestKey(keyId, clientDataHash: clientDataHash)
|
|
130
|
-
} catch let error as DCError where error.code == .serverUnavailable {
|
|
131
|
-
lastError = error
|
|
132
|
-
if attempt < maxAttempts - 1 {
|
|
133
|
-
try await Task.sleep(for: .seconds(pow(2.0, Double(attempt + 1))))
|
|
134
|
-
}
|
|
135
|
-
} catch {
|
|
136
|
-
throw error // Non-retryable errors propagate immediately
|
|
137
|
-
}
|
|
103
|
+
func withAttestRetry<T>(
|
|
104
|
+
maxAttempts: Int = 3,
|
|
105
|
+
_ operation: () async throws -> T
|
|
106
|
+
) async throws -> T {
|
|
107
|
+
var lastError: Error?
|
|
108
|
+
for attempt in 0..<maxAttempts {
|
|
109
|
+
do {
|
|
110
|
+
return try await operation()
|
|
111
|
+
} catch let failure as DCError {
|
|
112
|
+
guard failure.code == .serverUnavailable else { throw failure }
|
|
113
|
+
lastError = failure
|
|
114
|
+
let backoff = Duration.seconds(1 << (attempt + 1))
|
|
115
|
+
try await Task.sleep(for: backoff)
|
|
138
116
|
}
|
|
139
|
-
|
|
140
|
-
throw lastError ?? DeviceIntegrityError.attestationFailed
|
|
141
117
|
}
|
|
118
|
+
throw lastError ?? IntegrityError.attestationFailed
|
|
142
119
|
}
|
|
143
120
|
```
|
|
144
121
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
122
|
+
Only `.serverUnavailable` loops; every other error leaves immediately. Across
|
|
123
|
+
those retries nothing changes: one challenge, one `keyId`, one `clientDataHash`. Ask for a
|
|
124
|
+
new challenge only when you begin a brand-new attestation attempt.
|
|
148
125
|
|
|
149
|
-
##
|
|
126
|
+
## Rejected keys
|
|
150
127
|
|
|
151
|
-
`
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
the
|
|
128
|
+
`invalidKey` has three causes: `attestKey` on a key that is already attested,
|
|
129
|
+
`generateAssertion` with a key that was never attested, or the service
|
|
130
|
+
rejecting the key. Check local and server state first. When it confirms the key
|
|
131
|
+
is unusable, remove it from the Keychain with the **same account-scoped query
|
|
132
|
+
used to save it**, clear the cached value, and enroll again:
|
|
155
133
|
|
|
156
134
|
```swift
|
|
157
|
-
extension
|
|
158
|
-
func
|
|
159
|
-
|
|
160
|
-
|
|
135
|
+
extension AttestKeyStore {
|
|
136
|
+
func discardKeyAndReenroll() async throws -> String {
|
|
137
|
+
let status = SecItemDelete(baseQuery as CFDictionary)
|
|
138
|
+
if status != errSecSuccess && status != errSecItemNotFound {
|
|
139
|
+
throw IntegrityError.keyNotGenerated
|
|
140
|
+
}
|
|
141
|
+
keyID = nil
|
|
161
142
|
return try await generateKeyIfNeeded()
|
|
162
143
|
}
|
|
163
|
-
|
|
164
|
-
private func deleteKeyIdFromKeychain() {
|
|
165
|
-
let query: [String: Any] = [
|
|
166
|
-
kSecClass as String: kSecClassGenericPassword,
|
|
167
|
-
kSecAttrAccount as String: "app-attest-key-id",
|
|
168
|
-
kSecAttrService as String: Bundle.main.bundleIdentifier ?? ""
|
|
169
|
-
]
|
|
170
|
-
SecItemDelete(query as CFDictionary)
|
|
171
|
-
}
|
|
172
144
|
}
|
|
173
145
|
```
|
|
174
146
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
2. Call `generateKeyIfNeeded()` for each user account on each device, reuse the
|
|
180
|
-
account/device-scoped `keyId`, and limit new key generation to new
|
|
181
|
-
account/device/install enrollment or confirmed bad-key recovery.
|
|
182
|
-
3. Attest once per key; if `.serverUnavailable` occurs, retry with the same
|
|
183
|
-
challenge, key, and `clientDataHash`.
|
|
184
|
-
4. For each sensitive request, obtain a one-time assertion challenge and sign
|
|
185
|
-
client data that includes the challenge plus request context.
|
|
186
|
-
5. Handle `DCError.invalidKey` by checking whether the key was already attested,
|
|
187
|
-
not yet attested, or rejected before regenerating.
|
|
147
|
+
`baseQuery` is the actor property from the skill overview and already
|
|
148
|
+
includes `"attest-key.\(accountID)"` as `kSecAttrAccount`. Building a separate
|
|
149
|
+
delete query with a bare account string would miss the stored item, leave the
|
|
150
|
+
stale `keyId` behind, and the next launch would load it again.
|
|
188
151
|
|
|
189
|
-
##
|
|
152
|
+
## Integration outline
|
|
190
153
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
154
|
+
1. Check `DCAppAttestService.shared.isSupported`; when false, fall back to `DCDevice`.
|
|
155
|
+
2. Call `generateKeyIfNeeded()` for the signed-in account. A new key is justified
|
|
156
|
+
only for a new account, device or install enrollment, or for confirmed
|
|
157
|
+
bad-key recovery.
|
|
158
|
+
3. Attest once per key. On `.serverUnavailable`, retry with the same challenge,
|
|
159
|
+
key and hash.
|
|
160
|
+
4. For each sensitive request, fetch a one-time challenge and sign it together
|
|
161
|
+
with the request context.
|
|
162
|
+
5. On `invalidKey`, establish whether the key is already attested, not attested,
|
|
163
|
+
or rejected before replacing it.
|
|
195
164
|
|
|
196
|
-
##
|
|
165
|
+
## Gradual rollout
|
|
197
166
|
|
|
198
|
-
|
|
199
|
-
|
|
167
|
+
Apple recommends enabling App Attest gradually. Put it behind a remote feature
|
|
168
|
+
flag, keep the `DCDevice` fallback for unsupported devices, and ramp large
|
|
169
|
+
audiences in steps. Be ready to switch attestation traffic off if
|
|
170
|
+
`.serverUnavailable` errors or rate limiting climb.
|
|
200
171
|
|
|
201
|
-
|
|
202
|
-
<key>com.apple.developer.devicecheck.appattest-environment</key>
|
|
203
|
-
<string>production</string>
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
When the entitlement is omitted during development, the app uses the App Attest
|
|
207
|
-
sandbox by default. After distribution through TestFlight, the App Store, or the
|
|
208
|
-
Apple Developer Enterprise Program, the app ignores the entitlement value and
|
|
209
|
-
uses production. Sandbox keys and receipts do not work in production, and
|
|
210
|
-
production keys and receipts do not work in sandbox.
|
|
172
|
+
## Environment entitlement
|
|
211
173
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
174
|
+
The environment entitlement (`...devicecheck.appattest-environment`) is
|
|
175
|
+
`development` or `production`. Development builds without it use the sandbox; TestFlight, App
|
|
176
|
+
Store and Enterprise builds always use production. Keys and receipts from one
|
|
177
|
+
environment fail in the other, so route server verification to match. App
|
|
178
|
+
Clips and extensions that call App Attest need the capability on their own
|
|
179
|
+
target as well.
|
|
216
180
|
|
|
217
|
-
### Error
|
|
181
|
+
### Error type used in the examples
|
|
218
182
|
|
|
219
183
|
```swift
|
|
220
|
-
enum
|
|
184
|
+
enum IntegrityError: Error {
|
|
221
185
|
case deviceCheckUnsupported
|
|
222
186
|
case keyNotGenerated
|
|
223
187
|
case attestationFailed
|
|
@@ -227,14 +191,12 @@ enum DeviceIntegrityError: Error {
|
|
|
227
191
|
}
|
|
228
192
|
```
|
|
229
193
|
|
|
230
|
-
## Apple
|
|
231
|
-
|
|
232
|
-
- [DeviceCheck framework](https://
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- [
|
|
236
|
-
- [
|
|
237
|
-
- [
|
|
238
|
-
-
|
|
239
|
-
- [Attestation Object Validation Guide](https://sosumi.ai/documentation/devicecheck/attestation-object-validation-guide)
|
|
240
|
-
- [App Attest Environment](https://sosumi.ai/documentation/bundleresources/entitlements/com.apple.developer.devicecheck.appattest-environment)
|
|
194
|
+
## Apple documentation
|
|
195
|
+
|
|
196
|
+
- [DeviceCheck framework](https://developer.apple.com/documentation/devicecheck), whose article list includes
|
|
197
|
+
the app integrity overview, validating apps that talk to your server, the
|
|
198
|
+
attestation object guide, and preparation steps for the App Attest service
|
|
199
|
+
- [Fraud risk assessment](https://developer.apple.com/documentation/devicecheck/assessing-fraud-risk)
|
|
200
|
+
- [DCAppAttestService](https://developer.apple.com/documentation/devicecheck/dcappattestservice)
|
|
201
|
+
- [DCDevice](https://developer.apple.com/documentation/devicecheck/dcdevice)
|
|
202
|
+
- The App Attest environment page under Bundle Resources > Entitlements
|