buildanything 1.7.1 → 2.0.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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +9 -3
- package/CHANGELOG.md +112 -0
- package/README.md +2 -2
- package/agents/a11y-architect.md +166 -0
- package/agents/business-model.md +80 -29
- package/agents/code-architect.md +75 -0
- package/agents/code-reviewer.md +255 -0
- package/agents/code-simplifier.md +64 -0
- package/agents/design-brand-guardian.md +293 -53
- package/agents/design-critic.md +139 -0
- package/agents/design-inclusive-visuals-specialist.md +6 -19
- package/agents/design-ui-designer.md +335 -56
- package/agents/design-ux-architect.md +403 -55
- package/agents/design-ux-researcher.md +264 -49
- package/agents/engineering-ai-engineer.md +26 -36
- package/agents/engineering-backend-architect.md +185 -36
- package/agents/engineering-data-engineer.md +225 -43
- package/agents/engineering-devops-automator.md +227 -74
- package/agents/engineering-frontend-developer.md +210 -34
- package/agents/engineering-mobile-app-builder.md +6 -1
- package/agents/engineering-rapid-prototyper.md +30 -9
- package/agents/engineering-security-engineer.md +263 -61
- package/agents/engineering-senior-developer.md +128 -19
- package/agents/engineering-sre.md +84 -0
- package/agents/engineering-technical-writer.md +285 -41
- package/agents/feature-intel.md +110 -0
- package/agents/ios-app-review-guardian.md +66 -0
- package/agents/ios-foundation-models-specialist.md +64 -0
- package/agents/ios-storekit-specialist.md +59 -0
- package/agents/ios-swift-architect.md +129 -0
- package/agents/ios-swift-search.md +137 -0
- package/agents/ios-swift-ui-design.md +136 -0
- package/agents/marketing-app-store-optimizer.md +246 -64
- package/agents/planner.md +216 -0
- package/agents/pr-test-analyzer.md +63 -0
- package/agents/product-feedback-synthesizer.md +8 -2
- package/agents/refactor-cleaner.md +102 -0
- package/agents/security-reviewer.md +128 -0
- package/agents/silent-failure-hunter.md +54 -0
- package/agents/swift-build-resolver.md +119 -0
- package/agents/swift-reviewer.md +112 -0
- package/agents/tech-feasibility.md +21 -1
- package/agents/testing-api-tester.md +236 -59
- package/agents/testing-evidence-collector.md +26 -1
- package/agents/testing-performance-benchmarker.md +21 -1
- package/agents/testing-reality-checker.md +6 -1
- package/agents/visual-research.md +116 -0
- package/bin/adapters/cycle-counter-tool.ts +155 -0
- package/bin/adapters/scribe-tool.ts +71 -0
- package/bin/adapters/state-save-tool.ts +130 -0
- package/bin/adapters/write-lease-tool.ts +127 -0
- package/bin/buildanything-runtime.js +15 -0
- package/bin/buildanything-runtime.ts +328 -0
- package/bin/setup.js +83 -8
- package/commands/add-feature.md +2 -0
- package/commands/build.md +752 -332
- package/commands/fix.md +65 -0
- package/commands/self-check.md +121 -0
- package/commands/setup.md +114 -0
- package/commands/ux-review.md +63 -0
- package/commands/verify.md +69 -0
- package/docs/migration/agents.yaml +729 -0
- package/docs/migration/phase-graph.yaml +1088 -0
- package/docs/migration/sdk-host-compat.md +18 -0
- package/hooks/compile-writer-owner-cache.ts +171 -0
- package/hooks/hooks.json +36 -0
- package/hooks/pre-tool-use +19 -0
- package/hooks/pre-tool-use.ts +776 -0
- package/hooks/record-mode-transitions.ts +178 -0
- package/hooks/session-start +89 -2
- package/hooks/subagent-start +17 -0
- package/hooks/subagent-start.ts +471 -0
- package/hooks/subagent-stop +17 -0
- package/hooks/subagent-stop.ts +153 -0
- package/package.json +28 -5
- package/protocols/architecture-schema.md +171 -0
- package/protocols/build-fix.md +52 -0
- package/protocols/cleanup.md +54 -0
- package/protocols/decision-log.md +131 -0
- package/protocols/eval-harness.md +61 -0
- package/protocols/fake-data-detector.md +64 -0
- package/protocols/ios-context.md +234 -0
- package/protocols/ios-frameworks-map.md +323 -0
- package/protocols/ios-phase-branches.md +337 -0
- package/protocols/ios-preflight.md +27 -0
- package/protocols/launch-readiness.md +258 -0
- package/protocols/metric-loop.md +153 -0
- package/protocols/smoke-test.md +118 -0
- package/protocols/state-schema.json +388 -0
- package/protocols/state-schema.md +172 -0
- package/protocols/verify.md +127 -0
- package/protocols/visual-dna.md +185 -0
- package/protocols/web-phase-branches.md +351 -0
- package/skills/ios/_VENDORED.md +62 -0
- package/skills/ios/activitykit/LICENSE +131 -0
- package/skills/ios/activitykit/SKILL.md +505 -0
- package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
- package/skills/ios/app-intents/LICENSE +131 -0
- package/skills/ios/app-intents/SKILL.md +494 -0
- package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
- package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
- package/skills/ios/apple-on-device-ai/LICENSE +131 -0
- package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
- package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
- package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
- package/skills/ios/hig-components-content/SKILL.md +86 -0
- package/skills/ios/hig-components-content/references/activity-views.md +79 -0
- package/skills/ios/hig-components-content/references/charts.md +180 -0
- package/skills/ios/hig-components-content/references/collections.md +48 -0
- package/skills/ios/hig-components-content/references/color-wells.md +42 -0
- package/skills/ios/hig-components-content/references/image-views.md +82 -0
- package/skills/ios/hig-components-content/references/image-wells.md +34 -0
- package/skills/ios/hig-components-content/references/lockups.md +78 -0
- package/skills/ios/hig-components-content/references/web-views.md +36 -0
- package/skills/ios/hig-components-controls/SKILL.md +88 -0
- package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
- package/skills/ios/hig-components-controls/references/controls.md +112 -0
- package/skills/ios/hig-components-controls/references/gauges.md +74 -0
- package/skills/ios/hig-components-controls/references/labels.md +92 -0
- package/skills/ios/hig-components-controls/references/pickers.md +128 -0
- package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
- package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
- package/skills/ios/hig-components-controls/references/sliders.md +92 -0
- package/skills/ios/hig-components-controls/references/steppers.md +40 -0
- package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
- package/skills/ios/hig-components-controls/references/text-views.md +56 -0
- package/skills/ios/hig-components-controls/references/toggles.md +127 -0
- package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
- package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
- package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
- package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
- package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
- package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
- package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
- package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
- package/skills/ios/hig-components-layout/SKILL.md +99 -0
- package/skills/ios/hig-components-layout/references/boxes.md +48 -0
- package/skills/ios/hig-components-layout/references/column-views.md +44 -0
- package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
- package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
- package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
- package/skills/ios/hig-components-layout/references/panels.md +75 -0
- package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
- package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
- package/skills/ios/hig-components-layout/references/split-views.md +110 -0
- package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
- package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
- package/skills/ios/hig-components-layout/references/windows.md +188 -0
- package/skills/ios/hig-components-menus/SKILL.md +81 -0
- package/skills/ios/hig-components-menus/references/action-button.md +61 -0
- package/skills/ios/hig-components-menus/references/buttons.md +261 -0
- package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
- package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
- package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
- package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
- package/skills/ios/hig-components-menus/references/menus.md +171 -0
- package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
- package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
- package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
- package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
- package/skills/ios/hig-components-search/SKILL.md +68 -0
- package/skills/ios/hig-components-search/references/page-controls.md +120 -0
- package/skills/ios/hig-components-search/references/path-controls.md +40 -0
- package/skills/ios/hig-components-search/references/search-fields.md +189 -0
- package/skills/ios/hig-components-status/SKILL.md +80 -0
- package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
- package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
- package/skills/ios/hig-components-status/references/status-bars.md +38 -0
- package/skills/ios/hig-components-system/SKILL.md +88 -0
- package/skills/ios/hig-components-system/references/app-clips.md +387 -0
- package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
- package/skills/ios/hig-components-system/references/complications.md +425 -0
- package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
- package/skills/ios/hig-components-system/references/live-activities.md +442 -0
- package/skills/ios/hig-components-system/references/notifications.md +153 -0
- package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
- package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
- package/skills/ios/hig-components-system/references/widgets.md +517 -0
- package/skills/ios/hig-foundations/SKILL.md +98 -0
- package/skills/ios/hig-foundations/references/accessibility.md +291 -0
- package/skills/ios/hig-foundations/references/app-icons.md +210 -0
- package/skills/ios/hig-foundations/references/branding.md +44 -0
- package/skills/ios/hig-foundations/references/color.md +274 -0
- package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
- package/skills/ios/hig-foundations/references/icons.md +263 -0
- package/skills/ios/hig-foundations/references/images.md +176 -0
- package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
- package/skills/ios/hig-foundations/references/inclusion.md +189 -0
- package/skills/ios/hig-foundations/references/layout.md +425 -0
- package/skills/ios/hig-foundations/references/materials.md +238 -0
- package/skills/ios/hig-foundations/references/motion.md +103 -0
- package/skills/ios/hig-foundations/references/privacy.md +231 -0
- package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
- package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
- package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
- package/skills/ios/hig-foundations/references/typography.md +1146 -0
- package/skills/ios/hig-foundations/references/writing.md +91 -0
- package/skills/ios/hig-inputs/SKILL.md +94 -0
- package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
- package/skills/ios/hig-inputs/references/camera-control.md +107 -0
- package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
- package/skills/ios/hig-inputs/references/eyes.md +120 -0
- package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
- package/skills/ios/hig-inputs/references/game-controls.md +156 -0
- package/skills/ios/hig-inputs/references/gestures.md +208 -0
- package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
- package/skills/ios/hig-inputs/references/keyboards.md +234 -0
- package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
- package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
- package/skills/ios/hig-inputs/references/remotes.md +67 -0
- package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
- package/skills/ios/hig-patterns/SKILL.md +104 -0
- package/skills/ios/hig-patterns/references/charting-data.md +81 -0
- package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
- package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
- package/skills/ios/hig-patterns/references/entering-data.md +69 -0
- package/skills/ios/hig-patterns/references/feedback.md +67 -0
- package/skills/ios/hig-patterns/references/file-management.md +135 -0
- package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
- package/skills/ios/hig-patterns/references/launching.md +81 -0
- package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
- package/skills/ios/hig-patterns/references/loading.md +59 -0
- package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
- package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
- package/skills/ios/hig-patterns/references/modality.md +82 -0
- package/skills/ios/hig-patterns/references/multitasking.md +131 -0
- package/skills/ios/hig-patterns/references/offering-help.md +117 -0
- package/skills/ios/hig-patterns/references/onboarding.md +69 -0
- package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
- package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
- package/skills/ios/hig-patterns/references/playing-video.md +180 -0
- package/skills/ios/hig-patterns/references/printing.md +50 -0
- package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
- package/skills/ios/hig-patterns/references/searching.md +70 -0
- package/skills/ios/hig-patterns/references/settings.md +84 -0
- package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
- package/skills/ios/hig-patterns/references/workouts.md +76 -0
- package/skills/ios/hig-platforms/SKILL.md +84 -0
- package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
- package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
- package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
- package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
- package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
- package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
- package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
- package/skills/ios/hig-project-context/SKILL.md +133 -0
- package/skills/ios/hig-technologies/SKILL.md +107 -0
- package/skills/ios/hig-technologies/references/airplay.md +125 -0
- package/skills/ios/hig-technologies/references/always-on.md +62 -0
- package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
- package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
- package/skills/ios/hig-technologies/references/carekit.md +224 -0
- package/skills/ios/hig-technologies/references/carplay.md +119 -0
- package/skills/ios/hig-technologies/references/game-center.md +343 -0
- package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
- package/skills/ios/hig-technologies/references/healthkit.md +120 -0
- package/skills/ios/hig-technologies/references/homekit.md +343 -0
- package/skills/ios/hig-technologies/references/icloud.md +52 -0
- package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
- package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
- package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
- package/skills/ios/hig-technologies/references/live-photos.md +54 -0
- package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
- package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
- package/skills/ios/hig-technologies/references/maps.md +221 -0
- package/skills/ios/hig-technologies/references/nfc.md +51 -0
- package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
- package/skills/ios/hig-technologies/references/researchkit.md +134 -0
- package/skills/ios/hig-technologies/references/shareplay.md +142 -0
- package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
- package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
- package/skills/ios/hig-technologies/references/siri.md +523 -0
- package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
- package/skills/ios/hig-technologies/references/voiceover.md +90 -0
- package/skills/ios/hig-technologies/references/wallet.md +420 -0
- package/skills/ios/ios-26-platform/SKILL.md +53 -0
- package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
- package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
- package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
- package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
- package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
- package/skills/ios/ios-bootstrap/SKILL.md +107 -0
- package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
- package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
- package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
- package/skills/ios/ios-debugger-agent/LICENSE +21 -0
- package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
- package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
- package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
- package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
- package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
- package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
- package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
- package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
- package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
- package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
- package/skills/ios/swift-accessibility/LICENSE +21 -0
- package/skills/ios/swift-accessibility/SKILL.md +371 -0
- package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
- package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
- package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
- package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
- package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
- package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
- package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
- package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
- package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
- package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
- package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
- package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
- package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
- package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
- package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
- package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
- package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
- package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
- package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
- package/skills/ios/swift-concurrency/LICENSE +21 -0
- package/skills/ios/swift-concurrency/SKILL.md +171 -0
- package/skills/ios/swift-concurrency/references/_index.md +50 -0
- package/skills/ios/swift-concurrency/references/actors.md +660 -0
- package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
- package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
- package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
- package/skills/ios/swift-concurrency/references/core-data.md +560 -0
- package/skills/ios/swift-concurrency/references/glossary.md +135 -0
- package/skills/ios/swift-concurrency/references/linting.md +155 -0
- package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
- package/skills/ios/swift-concurrency/references/migration.md +1104 -0
- package/skills/ios/swift-concurrency/references/performance.md +593 -0
- package/skills/ios/swift-concurrency/references/sendable.md +598 -0
- package/skills/ios/swift-concurrency/references/tasks.md +636 -0
- package/skills/ios/swift-concurrency/references/testing.md +592 -0
- package/skills/ios/swift-concurrency/references/threading.md +495 -0
- package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
- package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
- package/skills/ios/swift-security-expert/LICENSE +21 -0
- package/skills/ios/swift-security-expert/SKILL.md +470 -0
- package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
- package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
- package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
- package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
- package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
- package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
- package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
- package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
- package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
- package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
- package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
- package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
- package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
- package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
- package/skills/ios/swift-testing-expert/LICENSE +21 -0
- package/skills/ios/swift-testing-expert/SKILL.md +79 -0
- package/skills/ios/swift-testing-expert/references/_index.md +12 -0
- package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
- package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
- package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
- package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
- package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
- package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
- package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
- package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
- package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
- package/skills/ios/swiftdata-pro/LICENSE +21 -0
- package/skills/ios/swiftdata-pro/SKILL.md +102 -0
- package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
- package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
- package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
- package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
- package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
- package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
- package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
- package/skills/ios/swiftui-design-principles/LICENSE +21 -0
- package/skills/ios/swiftui-design-principles/README.md +41 -0
- package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
- package/skills/ios/swiftui-design-principles/metadata.json +10 -0
- package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
- package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
- package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
- package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
- package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
- package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
- package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
- package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
- package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
- package/skills/ios/swiftui-pro/LICENSE +21 -0
- package/skills/ios/swiftui-pro/SKILL.md +108 -0
- package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
- package/skills/ios/swiftui-pro/references/api.md +39 -0
- package/skills/ios/swiftui-pro/references/data.md +43 -0
- package/skills/ios/swiftui-pro/references/design.md +31 -0
- package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
- package/skills/ios/swiftui-pro/references/navigation.md +14 -0
- package/skills/ios/swiftui-pro/references/performance.md +46 -0
- package/skills/ios/swiftui-pro/references/swift.md +56 -0
- package/skills/ios/swiftui-pro/references/views.md +35 -0
- package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
- package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
- package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
- package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
- package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
- package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
- package/skills/ios/widgetkit/LICENSE +131 -0
- package/skills/ios/widgetkit/SKILL.md +502 -0
- package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
- package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
- package/skills/web/accessibility/SKILL.md +146 -0
- package/skills/web/aceternity-ui/SKILL.md +719 -0
- package/skills/web/aceternity-ui/metadata.json +10 -0
- package/skills/web/api-design/SKILL.md +523 -0
- package/skills/web/chart-accessibility/SKILL.md +332 -0
- package/skills/web/composition-patterns/AGENTS.md +946 -0
- package/skills/web/composition-patterns/README.md +60 -0
- package/skills/web/composition-patterns/SKILL.md +89 -0
- package/skills/web/composition-patterns/metadata.json +11 -0
- package/skills/web/composition-patterns/rules/_sections.md +29 -0
- package/skills/web/composition-patterns/rules/_template.md +24 -0
- package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/skills/web/database-migrations/SKILL.md +429 -0
- package/skills/web/deployment-patterns/SKILL.md +427 -0
- package/skills/web/docker-patterns/SKILL.md +364 -0
- package/skills/web/e2e-testing/SKILL.md +326 -0
- package/skills/web/lighthouse-ci/SKILL.md +361 -0
- package/skills/web/mcp-server-patterns/SKILL.md +69 -0
- package/skills/web/next-best-practices/SKILL.md +153 -0
- package/skills/web/next-best-practices/async-patterns.md +87 -0
- package/skills/web/next-best-practices/bundling.md +180 -0
- package/skills/web/next-best-practices/data-patterns.md +297 -0
- package/skills/web/next-best-practices/debug-tricks.md +105 -0
- package/skills/web/next-best-practices/directives.md +73 -0
- package/skills/web/next-best-practices/error-handling.md +227 -0
- package/skills/web/next-best-practices/file-conventions.md +140 -0
- package/skills/web/next-best-practices/font.md +245 -0
- package/skills/web/next-best-practices/functions.md +108 -0
- package/skills/web/next-best-practices/hydration-error.md +91 -0
- package/skills/web/next-best-practices/image.md +173 -0
- package/skills/web/next-best-practices/metadata.md +301 -0
- package/skills/web/next-best-practices/parallel-routes.md +287 -0
- package/skills/web/next-best-practices/route-handlers.md +146 -0
- package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
- package/skills/web/next-best-practices/runtime-selection.md +39 -0
- package/skills/web/next-best-practices/scripts.md +141 -0
- package/skills/web/next-best-practices/self-hosting.md +371 -0
- package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
- package/skills/web/next-cache-components/SKILL.md +411 -0
- package/skills/web/postgres-best-practices/SKILL.md +14 -0
- package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
- package/skills/web/react-best-practices/AGENTS.md +3810 -0
- package/skills/web/react-best-practices/README.md +123 -0
- package/skills/web/react-best-practices/SKILL.md +149 -0
- package/skills/web/react-best-practices/metadata.json +15 -0
- package/skills/web/react-best-practices/rules/_sections.md +46 -0
- package/skills/web/react-best-practices/rules/_template.md +28 -0
- package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
- package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/web/seo/SKILL.md +154 -0
- package/skills/web/web-design-guidelines/SKILL.md +39 -0
- package/skills/web/zap-scan-config/SKILL.md +444 -0
- package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
- package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
- package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
- package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
- package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
- package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
- package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
- package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
- package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
- package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
- package/src/lrr/aggregator.ts +80 -0
- package/src/orchestrator/hooks/context-header.ts +95 -0
- package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
- package/src/orchestrator/hooks/token-accounting.ts +101 -0
- package/src/orchestrator/mcp/cycle-counter.ts +129 -0
- package/src/orchestrator/mcp/scribe.ts +283 -0
- package/src/orchestrator/mcp/state-save.ts +149 -0
- package/src/orchestrator/mcp/write-lease.ts +167 -0
- package/src/orchestrator/phase4-shared-context.ts +41 -0
- package/src/orchestrator/schemas/backward-edge.ts +46 -0
- package/agents/agentic-identity-trust.md +0 -121
- package/agents/data-consolidation-agent.md +0 -39
- package/agents/design-image-prompt-engineer.md +0 -105
- package/agents/design-visual-storyteller.md +0 -147
- package/agents/design-whimsy-injector.md +0 -89
- package/agents/engineering-autonomous-optimization-architect.md +0 -105
- package/agents/market-intel.md +0 -35
- package/agents/marketing-instagram-curator.md +0 -111
- package/agents/marketing-reddit-community-builder.md +0 -121
- package/agents/marketing-social-media-strategist.md +0 -74
- package/agents/marketing-tiktok-strategist.md +0 -123
- package/agents/marketing-twitter-engager.md +0 -124
- package/agents/marketing-wechat-official-account.md +0 -143
- package/agents/marketing-xiaohongshu-specialist.md +0 -136
- package/agents/marketing-zhihu-strategist.md +0 -160
- package/agents/product-behavioral-nudge-engine.md +0 -78
- package/agents/project-management-experiment-tracker.md +0 -102
- package/agents/report-distribution-agent.md +0 -43
- package/agents/risk-analysis.md +0 -45
- package/agents/sales-data-extraction-agent.md +0 -46
- package/agents/specialized-cultural-intelligence-strategist.md +0 -65
- package/agents/specialized-developer-advocate.md +0 -146
- package/agents/support-analytics-reporter.md +0 -133
- package/agents/support-executive-summary-generator.md +0 -64
- package/agents/support-finance-tracker.md +0 -145
- package/agents/support-legal-compliance-checker.md +0 -129
- package/agents/support-support-responder.md +0 -91
- package/agents/testing-accessibility-auditor.md +0 -110
- package/agents/testing-test-results-analyzer.md +0 -97
- package/agents/testing-tool-evaluator.md +0 -76
- package/agents/testing-workflow-optimizer.md +0 -99
- package/agents/user-research.md +0 -40
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
# Secure Enclave: Hardware-Backed Key Operations for iOS & macOS
|
|
2
|
+
|
|
3
|
+
> Scope: Secure Enclave capabilities, constraints, and integration patterns for key generation, persistence, biometric gating, and testability on Apple platforms.
|
|
4
|
+
|
|
5
|
+
**The Secure Enclave (SE) is Apple's dedicated security coprocessor — a physically isolated chip that generates, stores, and operates on cryptographic keys in silicon that never exposes private key material to the application processor.** Every modern Apple device since iPhone 5s (2013) contains this hardware, but developers routinely misuse it because of subtle API behaviors, simulator traps, and fundamental architectural constraints that AI code generators consistently get wrong. This reference covers CryptoKit's `SecureEnclave` module (iOS 13+), the legacy Security framework path, iOS 26 post-quantum additions, correct and incorrect code patterns, persistence, testing strategies, and the hardware limitations you must design around.
|
|
6
|
+
|
|
7
|
+
Primary sources: Apple Platform Security Guide (Secure Enclave chapter), Apple Developer Documentation for CryptoKit `SecureEnclave` types, WWDC 2019 Session 709 "Cryptography and Your Apps," WWDC 2025 "Get ahead with quantum-secure cryptography," Apple DTS documentation "Protecting keys with the Secure Enclave," and "Storing CryptoKit Keys in the Keychain."
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What the Secure Enclave actually is
|
|
12
|
+
|
|
13
|
+
The SE is a dedicated security subsystem embedded in Apple's SoC, running its own microkernel (sepOS — a customized L4 microkernel on a proprietary AKF ARMv7a core at 300–400 MHz). It has its own boot ROM (immutable, cryptographically verified at startup), hardware true random number generator (TRNG), AES engine, public key accelerator (PKA), and encrypted memory region. Communication with the application processor happens exclusively through an interrupt-driven mailbox — a hardware filter blocks all other access paths.
|
|
14
|
+
|
|
15
|
+
The SE's core guarantee: **private key material generated inside the Secure Enclave never leaves its hardware boundary.** When your code "uses" an SE key, it sends a request through the mailbox, the SE performs the cryptographic operation internally, and only the result (a signature, a shared secret) comes back. There is no API, debug interface, or JTAG path to extract the raw key.
|
|
16
|
+
|
|
17
|
+
Each SoC has a Unique ID (UID) permanently fused into silicon at manufacturing. This UID is inaccessible to any software (including Apple's) and serves as the root cryptographic key from which all SE keys derive. This is what makes keys irrevocably device-bound.
|
|
18
|
+
|
|
19
|
+
**Devices with Secure Enclave:** All iPhones from iPhone 5s onward (A7+ chips), all iPads from iPad Air onward, Apple Watch Series 1+, Apple TV HD (4th gen) onward, HomePod, all Macs with T1/T2/M-series chips, and Apple Vision Pro. Intel Macs without T1 or T2 chips (pre-2016 MacBook Pro, pre-2018 MacBook Air, pre-2020 iMac except iMac Pro) do **not** have a Secure Enclave.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Hardware limitations you must design around
|
|
24
|
+
|
|
25
|
+
These constraints are architectural, not bugs — they are fundamental to the SE's security model:
|
|
26
|
+
|
|
27
|
+
- **P-256 only for classical EC** — No P-384, P-521, Curve25519, or secp256k1. CryptoKit has no `SecureEnclave.P384` or `SecureEnclave.Curve25519` types. iOS 26 adds lattice-based post-quantum algorithms (ML-KEM, ML-DSA), not additional curves.
|
|
28
|
+
- **No symmetric key operations** — The internal AES engine handles Data Protection and FileVault but is **not exposed as a developer API**. There is no `SecureEnclave.AES`.
|
|
29
|
+
- **No key export** — `SecKeyCopyExternalRepresentation()` on an SE private key fails. The `dataRepresentation` property returns an encrypted opaque blob, not raw key material.
|
|
30
|
+
- **No key import** — Keys must be generated inside the SE. `init(dataRepresentation:)` accepts only the opaque blob from a previously created SE key — not arbitrary key material. There is no `init(rawRepresentation:)` on SE key types.
|
|
31
|
+
- **Device-bound** — Keys are tied to the device's UID fused at manufacturing. They do not survive factory resets, cannot be backed up to iCloud, cannot sync via iCloud Keychain, and cannot be transferred to a replacement device.
|
|
32
|
+
- **Limited storage** — The SE has approximately 4 MB of flash storage for keys. Not a concern for typical apps (a few dozen keys), but relevant if generating keys at high volume.
|
|
33
|
+
- **Performance overhead** — Each operation requires an interrupt-driven round-trip to the isolated coprocessor. The SE is not suitable for high-frequency operations (thousands of signatures per second). Batch signing or bulk encryption should use SE-derived symmetric keys instead.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## CryptoKit SecureEnclave API (iOS 13+)
|
|
38
|
+
|
|
39
|
+
CryptoKit's `SecureEnclave` module is the primary API for new code. It wraps the lower-level Security framework with Swift-native types that provide compile-time type safety, automatic memory zeroing on deallocation, and a curated surface that makes misuse difficult.
|
|
40
|
+
|
|
41
|
+
Two operation families are supported: **signing** (`SecureEnclave.P256.Signing`) and **key agreement** (`SecureEnclave.P256.KeyAgreement`).
|
|
42
|
+
|
|
43
|
+
### Creating signing keys
|
|
44
|
+
|
|
45
|
+
```swift
|
|
46
|
+
// ✅ CORRECT: Robust availability check + key creation
|
|
47
|
+
import CryptoKit
|
|
48
|
+
|
|
49
|
+
func createSigningKey() throws -> SecureEnclave.P256.Signing.PrivateKey {
|
|
50
|
+
#if targetEnvironment(simulator)
|
|
51
|
+
throw SecureEnclaveError.notAvailable
|
|
52
|
+
#else
|
|
53
|
+
guard SecureEnclave.isAvailable else {
|
|
54
|
+
throw SecureEnclaveError.notAvailable
|
|
55
|
+
}
|
|
56
|
+
return try SecureEnclave.P256.Signing.PrivateKey()
|
|
57
|
+
#endif
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
enum SecureEnclaveError: Error {
|
|
61
|
+
case notAvailable
|
|
62
|
+
case keyCreationFailed(underlying: Error)
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The `#if targetEnvironment(simulator)` compile-time guard is essential. **`SecureEnclave.isAvailable` can return `true` on the Simulator** when the host Mac has SE hardware (T2/M-series), but actual key generation fails at runtime. This behavior varies across Xcode versions — some return `false` consistently, others reflect the host's hardware. The compile-time check eliminates the ambiguity entirely.
|
|
67
|
+
|
|
68
|
+
> **Cross-validation note:** The Claude research source documents the simulator `isAvailable` returning `true` as a confirmed trap; the Parallel research source states `isAvailable` is always `false` on simulator. Real-world behavior depends on Xcode version and host hardware. The defensive pattern above (compile-time guard + runtime check) is correct regardless of which behavior your environment exhibits.
|
|
69
|
+
|
|
70
|
+
```swift
|
|
71
|
+
// ❌ INCORRECT: No availability check — crashes on simulator and old devices
|
|
72
|
+
let key = try SecureEnclave.P256.Signing.PrivateKey()
|
|
73
|
+
// Simulator: error -25293 or EXC_BAD_ACCESS depending on Xcode version
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Signing and verification
|
|
77
|
+
|
|
78
|
+
Once you have an SE key, signing is straightforward. The SE performs ECDSA internally and returns a standard `P256.Signing.ECDSASignature`. Verification uses the public key — a regular `P256.Signing.PublicKey` that can be freely exported and used anywhere:
|
|
79
|
+
|
|
80
|
+
```swift
|
|
81
|
+
// ✅ Sign with SE key, verify with public key
|
|
82
|
+
let privateKey = try SecureEnclave.P256.Signing.PrivateKey()
|
|
83
|
+
let message = "Transfer $500 to Alice".data(using: .utf8)!
|
|
84
|
+
|
|
85
|
+
// Signing happens inside the Secure Enclave hardware
|
|
86
|
+
let signature = try privateKey.signature(for: message)
|
|
87
|
+
|
|
88
|
+
// Public key is standard P256 — works anywhere, export as DER for servers
|
|
89
|
+
let publicKey = privateKey.publicKey
|
|
90
|
+
let isValid = publicKey.isValidSignature(signature, for: message) // true
|
|
91
|
+
|
|
92
|
+
let derSignature = signature.derRepresentation // For wire format
|
|
93
|
+
let rawSignature = signature.rawRepresentation // For compact storage
|
|
94
|
+
let publicDER = publicKey.derRepresentation // Register with backend
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Key agreement (ECDH) with HKDF derivation
|
|
98
|
+
|
|
99
|
+
`SecureEnclave.P256.KeyAgreement.PrivateKey` performs Elliptic Curve Diffie-Hellman inside the SE. The resulting `SharedSecret` is then derived into a usable symmetric key via HKDF — this is the **only correct path to symmetric encryption** when starting from an SE key:
|
|
100
|
+
|
|
101
|
+
```swift
|
|
102
|
+
// ✅ CORRECT: ECDH key agreement → HKDF → AES-GCM
|
|
103
|
+
let localKey = try SecureEnclave.P256.KeyAgreement.PrivateKey()
|
|
104
|
+
let localPublicKey = localKey.publicKey // Send to peer
|
|
105
|
+
|
|
106
|
+
// Received from peer (decoded from DER or raw bytes)
|
|
107
|
+
let peerPublicKey: P256.KeyAgreement.PublicKey = // ...
|
|
108
|
+
|
|
109
|
+
// ECDH happens inside the Secure Enclave
|
|
110
|
+
let sharedSecret = try localKey.sharedSecretFromKeyAgreement(with: peerPublicKey)
|
|
111
|
+
|
|
112
|
+
// Derive a 256-bit AES key using HKDF-SHA256
|
|
113
|
+
let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
|
|
114
|
+
using: SHA256.self,
|
|
115
|
+
salt: "com.myapp.v1.salt".data(using: .utf8)!,
|
|
116
|
+
sharedInfo: "encryption-key".data(using: .utf8)!,
|
|
117
|
+
outputByteCount: 32
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
// Now use the derived software key for AES-GCM encryption
|
|
121
|
+
let sealedBox = try AES.GCM.seal(plaintext, using: symmetricKey)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```swift
|
|
125
|
+
// ❌ WRONG: There is no SE symmetric API
|
|
126
|
+
// SecureEnclave.AES.GCM.seal(data, using: seKey) — DOES NOT EXIST
|
|
127
|
+
// AES.GCM.seal(data, using: seSigningKey) — TYPE MISMATCH (needs SymmetricKey)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> The ECDH + HKDF pattern is covered in full — including curve selection, `info` parameter guidance, and output key length — in `cryptokit-public-key.md` § Key Agreement with HKDF Derivation.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Persisting SE keys via dataRepresentation
|
|
135
|
+
|
|
136
|
+
CryptoKit SE keys are **ephemeral by default** — if you don't persist the `dataRepresentation`, the key reference is lost when the app terminates. The `dataRepresentation` property returns an opaque encrypted blob that only the same Secure Enclave on the same device can use to reconstruct the key. It is emphatically **not** the raw private key.
|
|
137
|
+
|
|
138
|
+
```swift
|
|
139
|
+
// ✅ Persist SE key to keychain and retrieve later
|
|
140
|
+
import CryptoKit
|
|
141
|
+
import Security
|
|
142
|
+
|
|
143
|
+
// --- Store ---
|
|
144
|
+
let privateKey = try SecureEnclave.P256.Signing.PrivateKey()
|
|
145
|
+
let keyBlob: Data = privateKey.dataRepresentation // Encrypted, device-bound
|
|
146
|
+
|
|
147
|
+
let storeQuery: [String: Any] = [
|
|
148
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
149
|
+
kSecAttrAccount as String: "com.myapp.signing-key",
|
|
150
|
+
kSecValueData as String: keyBlob,
|
|
151
|
+
kSecAttrAccessible as String:
|
|
152
|
+
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
|
153
|
+
]
|
|
154
|
+
// Delete-then-add pattern to handle existing items
|
|
155
|
+
SecItemDelete(storeQuery as CFDictionary)
|
|
156
|
+
let status = SecItemAdd(storeQuery as CFDictionary, nil)
|
|
157
|
+
guard status == errSecSuccess else {
|
|
158
|
+
throw NSError(domain: NSOSStatusErrorDomain, code: Int(status))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// --- Retrieve ---
|
|
162
|
+
let fetchQuery: [String: Any] = [
|
|
163
|
+
kSecClass as String: kSecClassGenericPassword,
|
|
164
|
+
kSecAttrAccount as String: "com.myapp.signing-key",
|
|
165
|
+
kSecReturnData as String: true,
|
|
166
|
+
kSecMatchLimit as String: kSecMatchLimitOne
|
|
167
|
+
]
|
|
168
|
+
var item: CFTypeRef?
|
|
169
|
+
let fetchStatus = SecItemCopyMatching(fetchQuery as CFDictionary, &item)
|
|
170
|
+
guard fetchStatus == errSecSuccess, let storedBlob = item as? Data else {
|
|
171
|
+
throw NSError(domain: NSOSStatusErrorDomain, code: Int(fetchStatus))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let restoredKey = try SecureEnclave.P256.Signing.PrivateKey(
|
|
175
|
+
dataRepresentation: storedBlob
|
|
176
|
+
)
|
|
177
|
+
// restoredKey is fully functional — operations route to the same SE key
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
On macOS, add `kSecUseDataProtectionKeychain: true` to target the modern data protection keychain rather than the legacy file-based keychain. On iOS/tvOS/watchOS this flag is redundant but harmless.
|
|
181
|
+
|
|
182
|
+
**Always use `kSecAttrAccessibleWhenUnlockedThisDeviceOnly`** for SE key blobs — the key is device-bound anyway, and syncable accessibility levels would store the blob on iCloud servers where it is useless (the SE that can decrypt it isn't there).
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Biometric-gated SE keys with SecAccessControl
|
|
187
|
+
|
|
188
|
+
The most security-critical SE pattern combines hardware key isolation with biometric authentication. The SE evaluates access control policies internally, making them tamper-proof even against OS-level compromises.
|
|
189
|
+
|
|
190
|
+
```swift
|
|
191
|
+
// ✅ Complete biometric-gated SE key creation (iOS 13+)
|
|
192
|
+
import CryptoKit
|
|
193
|
+
import LocalAuthentication
|
|
194
|
+
import Security
|
|
195
|
+
|
|
196
|
+
func createBiometricKey() throws -> SecureEnclave.P256.Signing.PrivateKey {
|
|
197
|
+
guard SecureEnclave.isAvailable else {
|
|
198
|
+
throw SecureEnclaveError.notAvailable
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
var error: Unmanaged<CFError>?
|
|
202
|
+
guard let accessControl = SecAccessControlCreateWithFlags(
|
|
203
|
+
nil,
|
|
204
|
+
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
|
205
|
+
[.privateKeyUsage, .biometryCurrentSet],
|
|
206
|
+
&error
|
|
207
|
+
) else {
|
|
208
|
+
throw error!.takeRetainedValue() as Error
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let context = LAContext()
|
|
212
|
+
context.localizedReason = "Authenticate to create signing key"
|
|
213
|
+
context.touchIDAuthenticationAllowableReuseDuration = 10
|
|
214
|
+
|
|
215
|
+
return try SecureEnclave.P256.Signing.PrivateKey(
|
|
216
|
+
compactRepresentable: true,
|
|
217
|
+
accessControl: accessControl,
|
|
218
|
+
authenticationContext: context
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Later: reconstruct and use (biometric prompt appears)
|
|
223
|
+
func signWithBiometricKey(storedBlob: Data, data: Data) throws -> Data {
|
|
224
|
+
let context = LAContext()
|
|
225
|
+
context.localizedReason = "Authenticate to sign transaction"
|
|
226
|
+
|
|
227
|
+
let key = try SecureEnclave.P256.Signing.PrivateKey(
|
|
228
|
+
dataRepresentation: storedBlob,
|
|
229
|
+
authenticationContext: context
|
|
230
|
+
)
|
|
231
|
+
return try key.signature(for: data).derRepresentation
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```swift
|
|
236
|
+
// ❌ Omitting .privateKeyUsage causes signing to fail
|
|
237
|
+
let badControl = SecAccessControlCreateWithFlags(
|
|
238
|
+
nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
|
239
|
+
.biometryCurrentSet, // Missing .privateKeyUsage!
|
|
240
|
+
nil
|
|
241
|
+
)!
|
|
242
|
+
// Key creation succeeds, but signing operations will fail
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Access control flag selection:**
|
|
246
|
+
|
|
247
|
+
- **`.biometryCurrentSet`** — Strongest. Key is permanently invalidated when the user re-enrolls biometrics (adds a new fingerprint, re-registers Face ID). Best for banking/healthcare. Requires re-keying logic when invalidation occurs.
|
|
248
|
+
- **`.biometryAny`** — Key survives biometric re-enrollment. Good balance of security and convenience for most apps.
|
|
249
|
+
- **`.userPresence`** — Accepts biometric or device passcode. Most flexible; use when you just need proof that a human is present.
|
|
250
|
+
|
|
251
|
+
**Critical operational note:** If you use `.biometryCurrentSet` and the user changes their enrolled biometrics, the key becomes **permanently unusable**. Your app must detect `errSecItemNotFound` or authentication errors, explain to the user why re-authentication is needed, and generate a fresh key with server-side re-enrollment. (See `biometric-authentication.md` for full LAContext integration patterns.)
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Legacy Security framework approach (iOS 10+)
|
|
256
|
+
|
|
257
|
+
Before CryptoKit, SE keys were created via `SecKeyCreateRandomKey` with `kSecAttrTokenIDSecureEnclave`. This still works and is necessary when targeting pre-iOS 13 or working with certificate-based identity operations:
|
|
258
|
+
|
|
259
|
+
```swift
|
|
260
|
+
// Legacy approach — functional but verbose; prefer CryptoKit for new code
|
|
261
|
+
import Security
|
|
262
|
+
|
|
263
|
+
func legacyCreateSEKey(tag: String) throws -> SecKey {
|
|
264
|
+
let access = SecAccessControlCreateWithFlags(
|
|
265
|
+
kCFAllocatorDefault,
|
|
266
|
+
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
|
|
267
|
+
[.privateKeyUsage, .biometryCurrentSet],
|
|
268
|
+
nil
|
|
269
|
+
)!
|
|
270
|
+
|
|
271
|
+
let attributes: NSDictionary = [
|
|
272
|
+
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
|
|
273
|
+
kSecAttrKeySizeInBits: 256,
|
|
274
|
+
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
|
|
275
|
+
kSecPrivateKeyAttrs: [
|
|
276
|
+
kSecAttrIsPermanent: true,
|
|
277
|
+
kSecAttrApplicationTag: tag.data(using: .utf8)!,
|
|
278
|
+
kSecAttrAccessControl: access
|
|
279
|
+
]
|
|
280
|
+
]
|
|
281
|
+
|
|
282
|
+
var error: Unmanaged<CFError>?
|
|
283
|
+
guard let privateKey = SecKeyCreateRandomKey(attributes, &error) else {
|
|
284
|
+
throw error!.takeRetainedValue() as Error
|
|
285
|
+
}
|
|
286
|
+
return privateKey
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
CryptoKit is preferred for new code because it provides compile-time type safety (distinct types per algorithm/operation), automatic memory zeroing, Swift-native error handling, and a curated API surface. The Security framework remains necessary for certificate management (`SecTrust`), RSA keys, or existing keychain items stored via the older API. (See `certificate-trust.md` for SecTrust patterns.)
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## iOS 26: Post-quantum cryptography in the Secure Enclave
|
|
295
|
+
|
|
296
|
+
WWDC 2025 session "Get ahead with quantum-secure cryptography" announced the most significant expansion of the SE's developer-facing capabilities since its 2013 introduction. Starting with **iOS 26, macOS 26, and all 2025 platform releases**, four new algorithm families are available:
|
|
297
|
+
|
|
298
|
+
- **`SecureEnclave.MLKEM768`** and **`SecureEnclave.MLKEM1024`** — Post-quantum key encapsulation (FIPS 203). Hardware-isolated ML-KEM operations for quantum-resistant key exchange.
|
|
299
|
+
- **`SecureEnclave.MLDSA65`** and **`SecureEnclave.MLDSA87`** — Post-quantum digital signatures (FIPS 204). Hardware-isolated ML-DSA signing resistant to quantum attacks.
|
|
300
|
+
|
|
301
|
+
These are **hardware-backed**, not software-only. Apple confirmed SE support explicitly. The implementations are formally verified as functionally equivalent to their FIPS specifications.
|
|
302
|
+
|
|
303
|
+
**Quantum-secure TLS by default:** `URLSession` and `Network.framework` automatically upgrade to quantum-secure TLS 1.3 using X-Wing (ML-KEM768 + X25519) in iOS 26. System services including CloudKit, Push Notifications, and Private Relay already use it. For most developers, no code changes are needed.
|
|
304
|
+
|
|
305
|
+
**Custom end-to-end encryption:** Apple recommends hybrid constructions that combine post-quantum and classical algorithms. The `XWingMLKEM768X25519` type provides a hybrid KEM ciphersuite. For application-level encryption, use `SecureEnclave.MLKEM768.PrivateKey` to encapsulate/decapsulate shared secrets within the hardware boundary.
|
|
306
|
+
|
|
307
|
+
**API evolution timeline:**
|
|
308
|
+
|
|
309
|
+
| Release | SE Developer Additions |
|
|
310
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------- |
|
|
311
|
+
| **iOS 13** (2019) | CryptoKit introduced: `SecureEnclave.P256.Signing`, `.P256.KeyAgreement`, `.isAvailable` |
|
|
312
|
+
| **iOS 14** (2020) | No SE changes. Added HKDF, PEM/DER format support |
|
|
313
|
+
| **iOS 15–16** (2021–22) | No SE changes |
|
|
314
|
+
| **iOS 17** (2023) | No SE changes. HPKE added (software-only). iMessage PQ3 shipped in 17.4 |
|
|
315
|
+
| **iOS 18** (2024) | No SE changes |
|
|
316
|
+
| **iOS 26** (2025) | **Major expansion**: `.MLKEM768`, `.MLKEM1024`, `.MLDSA65`, `.MLDSA87`. Quantum-secure TLS default |
|
|
317
|
+
|
|
318
|
+
The SE's classical elliptic curve support remains **P-256 only** — the expansion is entirely into lattice-based post-quantum algorithms.
|
|
319
|
+
|
|
320
|
+
> For the full post-quantum algorithm catalog — including software-only types, X-Wing hybrid KEM construction, key/signature size trade-offs, HPKE integration patterns, and hybrid classical+PQ signing — see `cryptokit-public-key.md` § Post-Quantum Cryptography (iOS 26+). This section covers the hardware-backed SE variants specifically.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## When to use SE versus software keys
|
|
325
|
+
|
|
326
|
+
**Use the Secure Enclave for:** root signing keys, device attestation, transaction authorization, biometric-gated authentication, and any scenario where proving key possession on a specific physical device matters. The non-exportability guarantee is the core value — an attacker who compromises the application processor still cannot extract the private key.
|
|
327
|
+
|
|
328
|
+
**Use standard keychain (software keys) for:** session tokens, API keys, symmetric encryption keys, keys requiring algorithms beyond P-256 (RSA, P-384, Ed25519), keys that must sync via iCloud Keychain, keys that need to survive device replacement, and high-throughput operations requiring thousands of operations per second.
|
|
329
|
+
|
|
330
|
+
**Common effective pattern:** Store a master asymmetric key in the SE and use ECDH to derive or wrap symmetric keys for bulk encryption. The SE protects the root of trust; derived keys handle the high-throughput work.
|
|
331
|
+
|
|
332
|
+
The anti-pattern is reaching for the SE for every secret. The P-256 constraint, performance overhead, and device-binding mean SE keys should protect the most critical operations, not replace the standard keychain. (See `credential-storage-patterns.md` for token lifecycle patterns.)
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Six correctness traps AI generators get wrong
|
|
337
|
+
|
|
338
|
+
These patterns appear routinely in LLM-generated code. Each reflects a misunderstanding of the SE's hardware architecture.
|
|
339
|
+
|
|
340
|
+
### 1. Not checking isAvailable (and the simulator double-trap)
|
|
341
|
+
|
|
342
|
+
The minimal check is `SecureEnclave.isAvailable`, but this alone is insufficient on the simulator. The robust pattern combines compile-time and runtime checks:
|
|
343
|
+
|
|
344
|
+
```swift
|
|
345
|
+
// ✅ Robust availability check — safe everywhere
|
|
346
|
+
var canUseSecureEnclave: Bool {
|
|
347
|
+
#if targetEnvironment(simulator)
|
|
348
|
+
return false
|
|
349
|
+
#else
|
|
350
|
+
return SecureEnclave.isAvailable
|
|
351
|
+
#endif
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### 2. Attempting to import external keys
|
|
356
|
+
|
|
357
|
+
There is no `init(rawRepresentation:)` on SE key types. `init(dataRepresentation:)` accepts only the opaque blob from a previously created SE key:
|
|
358
|
+
|
|
359
|
+
```swift
|
|
360
|
+
// ❌ IMPOSSIBLE: Cannot import an existing key into the Secure Enclave
|
|
361
|
+
let externalKey = P256.Signing.PrivateKey()
|
|
362
|
+
let rawBytes = externalKey.rawRepresentation
|
|
363
|
+
// SecureEnclave.P256.Signing.PrivateKey(rawRepresentation:) DOES NOT EXIST
|
|
364
|
+
// SecureEnclave.P256.Signing.PrivateKey(dataRepresentation: rawBytes) WILL THROW
|
|
365
|
+
|
|
366
|
+
// ✅ Keys MUST be generated inside the SE
|
|
367
|
+
let seKey = try SecureEnclave.P256.Signing.PrivateKey()
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### 3. Attempting AES/symmetric encryption directly
|
|
371
|
+
|
|
372
|
+
The SE's internal AES engine is not exposed to developers. Use ECDH → HKDF → AES-GCM instead (see Key agreement section above).
|
|
373
|
+
|
|
374
|
+
### 4. Assuming SE keys can be backed up or transferred
|
|
375
|
+
|
|
376
|
+
SE keys are device-bound. Server-side architectures **must** register the device's public key and support re-keying when a user changes devices. Design re-enrollment flows from day one.
|
|
377
|
+
|
|
378
|
+
### 5. Using legacy Security framework when CryptoKit is available
|
|
379
|
+
|
|
380
|
+
`SecKeyCreateRandomKey` + `kSecAttrTokenIDSecureEnclave` still works, but CryptoKit eliminates ~20 lines of dictionary-based C-style code and provides compile-time type safety. Use the legacy API only for pre-iOS 13 targets or certificate operations.
|
|
381
|
+
|
|
382
|
+
### 6. Omitting .privateKeyUsage in access control
|
|
383
|
+
|
|
384
|
+
SE keys created with `SecAccessControl` for biometric gating **must** include `.privateKeyUsage`. Without it, key creation succeeds but signing operations fail silently on some configurations. Always combine: `[.privateKeyUsage, .biometryCurrentSet]`.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Testing and CI/CD strategies
|
|
389
|
+
|
|
390
|
+
### Protocol-based abstraction for testable SE code
|
|
391
|
+
|
|
392
|
+
Since SE operations fail on simulators and most CI environments, abstract cryptographic operations behind a protocol with SE, software, and mock implementations:
|
|
393
|
+
|
|
394
|
+
```swift
|
|
395
|
+
// ✅ Protocol abstraction for testable SE-dependent code
|
|
396
|
+
import CryptoKit
|
|
397
|
+
import Foundation
|
|
398
|
+
|
|
399
|
+
protocol SigningKeyProvider {
|
|
400
|
+
var publicKeyData: Data { get throws }
|
|
401
|
+
func sign(_ data: Data) throws -> Data
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Production: Secure Enclave implementation
|
|
405
|
+
final class SESigningKey: SigningKeyProvider {
|
|
406
|
+
private let key: SecureEnclave.P256.Signing.PrivateKey
|
|
407
|
+
|
|
408
|
+
init() throws { self.key = try SecureEnclave.P256.Signing.PrivateKey() }
|
|
409
|
+
init(dataRepresentation: Data) throws {
|
|
410
|
+
self.key = try SecureEnclave.P256.Signing.PrivateKey(
|
|
411
|
+
dataRepresentation: dataRepresentation)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
var publicKeyData: Data { get throws { key.publicKey.derRepresentation } }
|
|
415
|
+
func sign(_ data: Data) throws -> Data {
|
|
416
|
+
try key.signature(for: data).derRepresentation
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Fallback: Software P256 (same curve, same signature format)
|
|
421
|
+
final class SoftwareSigningKey: SigningKeyProvider {
|
|
422
|
+
private let key: P256.Signing.PrivateKey
|
|
423
|
+
|
|
424
|
+
init() { self.key = P256.Signing.PrivateKey() }
|
|
425
|
+
var publicKeyData: Data { get throws { key.publicKey.derRepresentation } }
|
|
426
|
+
func sign(_ data: Data) throws -> Data {
|
|
427
|
+
try key.signature(for: data).derRepresentation
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Test: Mock implementation
|
|
432
|
+
final class MockSigningKey: SigningKeyProvider {
|
|
433
|
+
var publicKeyDataToReturn = Data()
|
|
434
|
+
var signatureToReturn = Data()
|
|
435
|
+
var shouldThrow = false
|
|
436
|
+
var signCallCount = 0
|
|
437
|
+
|
|
438
|
+
var publicKeyData: Data { get throws { publicKeyDataToReturn } }
|
|
439
|
+
func sign(_ data: Data) throws -> Data {
|
|
440
|
+
signCallCount += 1
|
|
441
|
+
if shouldThrow { throw NSError(domain: "Mock", code: -1) }
|
|
442
|
+
return signatureToReturn
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Factory with SE → software fallback
|
|
448
|
+
|
|
449
|
+
```swift
|
|
450
|
+
// ✅ Runtime factory — SE when available, software otherwise
|
|
451
|
+
struct SigningKeyFactory {
|
|
452
|
+
static func create() throws -> SigningKeyProvider {
|
|
453
|
+
#if targetEnvironment(simulator)
|
|
454
|
+
return SoftwareSigningKey()
|
|
455
|
+
#else
|
|
456
|
+
if SecureEnclave.isAvailable {
|
|
457
|
+
return try SESigningKey()
|
|
458
|
+
}
|
|
459
|
+
return SoftwareSigningKey()
|
|
460
|
+
#endif
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Both SE and software implementations produce **identical P256 ECDSA signatures** — verification code works the same regardless of which implementation created the key.
|
|
466
|
+
|
|
467
|
+
### XCTest patterns
|
|
468
|
+
|
|
469
|
+
```swift
|
|
470
|
+
import XCTest
|
|
471
|
+
@testable import MyApp
|
|
472
|
+
|
|
473
|
+
final class AuthServiceTests: XCTestCase {
|
|
474
|
+
func testSignChallenge() throws {
|
|
475
|
+
let mock = MockSigningKey()
|
|
476
|
+
mock.signatureToReturn = Data([0xDE, 0xAD])
|
|
477
|
+
let service = AuthService(signingKey: mock)
|
|
478
|
+
|
|
479
|
+
let result = try service.signChallenge(Data("test".utf8))
|
|
480
|
+
|
|
481
|
+
XCTAssertEqual(mock.signCallCount, 1)
|
|
482
|
+
XCTAssertEqual(result, Data([0xDE, 0xAD]))
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
func testRealSEKey() throws {
|
|
486
|
+
#if targetEnvironment(simulator)
|
|
487
|
+
throw XCTSkip("Secure Enclave not available on Simulator")
|
|
488
|
+
#else
|
|
489
|
+
guard SecureEnclave.isAvailable else {
|
|
490
|
+
throw XCTSkip("Secure Enclave not available on this hardware")
|
|
491
|
+
}
|
|
492
|
+
let key = try SESigningKey()
|
|
493
|
+
let signature = try key.sign(Data("test".utf8))
|
|
494
|
+
XCTAssertFalse(signature.isEmpty)
|
|
495
|
+
#endif
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### CI/CD reality
|
|
501
|
+
|
|
502
|
+
GitHub Actions macOS runners (both arm64 and Intel) run in VMs where the **Secure Enclave is not accessible** — the Apple Virtualization Framework does not pass through SE access to guest VMs. Self-hosted runners on physical Mac hardware (Mac mini M-series, MacBook Pro with T2) do have SE access. Xcode Cloud runs on Apple silicon but SE availability depends on the specific cloud configuration.
|
|
503
|
+
|
|
504
|
+
**Practical CI approach:** Run unit tests with mocks on CI; run SE integration tests only on physical device test farms or self-hosted runners; tag SE-specific tests with `XCTSkip` guards for conditional execution. (See `testing-security-code.md` for comprehensive CI/CD patterns.)
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Operational guidance: rotation, migration, and incident response
|
|
509
|
+
|
|
510
|
+
Treat SE keys as **ephemeral, device-bound artifacts** rather than permanent user identities:
|
|
511
|
+
|
|
512
|
+
- **Device replacement:** When a user gets a new device, SE keys from the old device are gone. Your app must detect a missing key (keychain blob absent or `dataRepresentation` fails to reconstruct) and trigger a re-enrollment flow: generate a new SE key, register its public key with your backend, and invalidate the old public key.
|
|
513
|
+
- **Biometric re-enrollment:** If using `.biometryCurrentSet`, adding a new fingerprint or resetting Face ID permanently invalidates the key. Catch the error, explain to the user why they need to re-authenticate, and provision a fresh key.
|
|
514
|
+
- **Key rotation:** Periodic rotation of SE keys follows the same re-enrollment pattern. Generate a new key, register the new public key with the server, sign a transition token with the old key (if still valid), and delete the old key blob from the keychain.
|
|
515
|
+
- **Incident response:** If a device is compromised at the OS level, SE keys remain protected (the SE operates independently). However, if the physical device is in an attacker's possession and they know the passcode, they can authenticate to the SE. Remote wipe via MDM or Find My destroys the UID-derived key hierarchy, rendering all SE keys permanently unrecoverable.
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Conclusion
|
|
520
|
+
|
|
521
|
+
The Secure Enclave's developer surface was remarkably stable from iOS 13 to iOS 25 — `SecureEnclave.P256` was the entire API. iOS 26 broke open the boundary with post-quantum ML-KEM and ML-DSA, the first algorithm expansion in the SE's 12-year history. The practical insight is that **correct SE usage is more about what you don't do** (don't skip availability checks, don't try to import keys, don't assume portability, don't use the SE for symmetric encryption) than complex API choreography. The CryptoKit API is deliberately minimal and hard to misuse, which is its greatest strength.
|
|
522
|
+
|
|
523
|
+
For new projects, the recommended architecture is: protocol-based abstraction around signing and key agreement; SE implementation as primary with software P256 fallback; `dataRepresentation` persisted in the keychain as `kSecClassGenericPassword` with `kSecAttrAccessibleWhenUnlockedThisDeviceOnly`; biometric access control for high-value keys; server-side public key registration with re-keying support for device replacement; and `XCTSkip`-guarded integration tests on physical hardware.
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## Summary Checklist
|
|
528
|
+
|
|
529
|
+
1. **Availability guard** — Always combine `#if targetEnvironment(simulator)` (compile-time) with `SecureEnclave.isAvailable` (runtime) before any SE key creation. Never assume SE is present.
|
|
530
|
+
2. **No key import** — SE keys must be generated inside the hardware. `init(dataRepresentation:)` reconstructs existing SE keys only — it cannot import external key material.
|
|
531
|
+
3. **No symmetric encryption** — The SE does not expose AES to developers. Use ECDH → HKDF → `AES.GCM` for encryption workflows starting from an SE key.
|
|
532
|
+
4. **Device-bound design** — SE keys cannot be backed up, synced, or transferred. Build server-side re-enrollment flows for device replacement from day one.
|
|
533
|
+
5. **Persist dataRepresentation** — Store the opaque encrypted blob in the keychain as `kSecClassGenericPassword` with `kSecAttrAccessibleWhenUnlockedThisDeviceOnly`. Without persistence, keys are lost on app termination.
|
|
534
|
+
6. **Include .privateKeyUsage** — When creating `SecAccessControl` for biometric-gated SE keys, always include `.privateKeyUsage` alongside the biometric flag. Omitting it causes signing to fail silently.
|
|
535
|
+
7. **Handle biometric invalidation** — `.biometryCurrentSet` keys are permanently invalidated on biometric re-enrollment. Detect the error and trigger re-keying with server notification.
|
|
536
|
+
8. **Protocol abstraction** — Abstract SE operations behind a protocol with SE, software, and mock implementations for testability. Both SE and software P256 produce identical signature formats.
|
|
537
|
+
9. **CryptoKit over Security framework** — Use `SecureEnclave.P256.Signing.PrivateKey` (CryptoKit) instead of `SecKeyCreateRandomKey` + `kSecAttrTokenIDSecureEnclave` for new code. Reserve the Security framework for certificates and pre-iOS 13 targets.
|
|
538
|
+
10. **iOS 26 post-quantum** — `SecureEnclave.MLKEM768/1024` and `.MLDSA65/87` are hardware-backed. For custom E2E encryption, adopt hybrid constructions (classical + PQC). `URLSession` TLS upgrades automatically.
|
|
539
|
+
11. **CI/CD skip guards** — Use `XCTSkip` for SE-specific tests in CI. GitHub Actions VMs do not have SE access. Run SE integration tests only on physical hardware or device farms.
|