Releases: tixster/swift-app-attest
Releases · tixster/swift-app-attest
Release list
1.1.0
What's new
Challenge-echo enrollment DTOs
Two new shared payloads in AppAttestCore for services without accounts or
sessions — the server remembers issued challenges by value, and the client
echoes the challenge back alongside the attestation:
ChallengePayload— the server → client challenge response.EnrollmentPayload— challenge + key ID + attestation in one body.
Like the existing DTOs they're optional, Codable, and re-exported by both
the client and server products.
Documentation
- New DocC landing page for
AppAttestClient: enrollment and signing flow,
key-loss recovery. - Transport variants for assertions, in the README and the Verifying
assertions article — including carrying the key ID and assertion in HTTP
headers with the raw request body as the signed client data, and the rules
that keep it safe (the challenge stays inside the signed bytes; enrollment
stays in the request body). - Expanded guides: challenge storage patterns (session-bound vs. echo), a
complete client + server (Hummingbird) example, wire-format pitfalls
(JSON isn't canonical — verify the shipped bytes).
Full Changelog: 1.0.0...1.1.0
swift-app-attest 1.0.0
Initial release: full coverage of Apple's App Attest API, on both sides of the wire.
AppAttestClient — iOS 14+ / macOS 11+ / tvOS 15+ / watchOS 9+ / visionOS 1+
AppAttestService: a thin async wrapper overDCAppAttestService—isSupported,
generateKey(),attestKey,generateAssertion.- Typed errors: every method is
async throws(AppAttestClientError), mapping all
DCErrorcodes with recovery guidance in the docs (e.g. re-attest on.invalidKey). - Convenience overloads
attestKey(_:challenge:)andgenerateAssertion(_:clientData:)
hash with SHA-256 for you; rawclientDataHash:pass-throughs remain.
AppAttestServer — macOS 11+ / Linux
AttestationVerifierimplements every step of Apple's Validating apps that
connect to your server: certificate chain to the pinned Apple App Attest Root CA,
nonce extension (OID1.2.840.113635.100.8.2), key identifier, App ID (RP ID) hash,
counter, environment AAGUID, credential ID — plus the macOS access-control policy
check (aclBlob, OID1.2.840.113635.100.8.6).AssertionVerifier: ECDSA signature overSHA256(authData || SHA256(clientData)),
RP ID, strictly increasing counter, and challenge validation with a pluggable
extractor for app-specific client-data formats.- Both verifiers surface the
apple_validation_category_01(distribution category) and
apple_bundle_version_01(app version) authenticator-data extensions. ReceiptVerifier: PKCS #7 receipts verified up to Apple Root CA - G3, decoded
into typed fields (App ID, attested certificate, receipt type, creation/not-before/
expiration times, risk metric).FraudAssessmentClient: the receipt exchange with
data{-development}.appattest.apple.com, authenticated with an ES256 JWT from an
App Store Connect key; all documented response codes are mapped to typed errors.
Transport sits behind theAppAttestHTTPClientprotocol —URLSessionby default,
AsyncHTTPClient pluggable.AppAttestChallenge.generate()for issuing server challenges.- Typed throws throughout:
AppAttestVerificationErrorandAppAttestReceiptError
name the exact check that failed.
Shared core
AppAttestKeyID,AppAttestEnvironment, and optional Codable transport DTOs
(AttestationPayload,AssertionPayload) are shared by both products, so the
client and server always agree on the wire format.
Under the hood
- Dependencies: only Apple's swift-crypto, swift-certificates, and swift-asn1;
CBOR is decoded by a small internal reader. - 78 tests run fully offline against synthetic attestation chains, CMS-signed
receipts, and cryptographically verified JWTs; every verifier failure branch
is covered. - CI on macOS and Linux (Swift 6.1 and latest); API documentation is published
at https://tixster.github.io/swift-app-attest/documentation/
Installation
.package(url: "https://github.com/tixster/swift-app-attest.git", from: "1.0.0"),