main
md 170 lines 5.91 KB
Rendered Raw
1 <h1 align="center">smbCloud Auth for Swift</h1>
2
3 <p align="center">
4 <strong>Native Swift SDK for smbCloud Auth — server-side and Apple apps.</strong>
5 </p>
6
7 <p align="center">
8 <a href="https://smbcloud.xyz"><img src="https://img.shields.io/badge/smbcloud.xyz-0969DA?style=flat-square&labelColor=1A1A1A" alt="Website"></a>
9 <a href="https://github.com/smbcloudXYZ/smbcloud-auth-swift/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-0969DA?style=flat-square&labelColor=1A1A1A" alt="License"></a>
10 </p>
11
12 <p align="center">
13 <a href="https://github.com/smbcloudXYZ/smbcloud-cli">Rust core</a> ·
14 <a href="https://www.npmjs.com/package/@smbcloud/sdk-auth">npm</a> ·
15 <a href="https://pypi.org/project/smbcloud-sdk-auth/">PyPI</a> ·
16 <a href="https://rubygems.org/gems/smbcloud-auth">RubyGems</a>
17 </p>
18
19 ---
20
21 `smbcloud-auth-swift` is the Swift SDK for smbCloud Auth. It authenticates a
22 tenant auth app's end users (**`AuthUser`**) against the smbCloud tenant client
23 API (`/v1/client/*`).
24
25 It ships **two products**:
26
27 | Product | Platforms | What it's for |
28 |---------|-----------|---------------|
29 | **`AuthCore`** | Apple · Linux · Windows · Android | Headless, UI-free auth engine (use server-side too) |
30 | **`SmbCloudAuth`** | Apple only | Hosted login UI + Keychain on top of `AuthCore` |
31
32 `AuthCore` gives you:
33
34 - `AuthCoreClient` — the tenant credential client: `login`, `signup`, `me`,
35 `logout`, `remove`, plus the Apple provider helpers. Uses confidential
36 `ClientCredentials` (`appId` + `appSecret`).
37 - `OIDC` — the public-client OIDC Authorization Code + PKCE flow
38 (`buildAuthorizationRequest`, `parseCallbackURL`, `exchangeCode`, `getUserInfo`).
39 - `SmbCloudSession` and `SmbCloudCredentialsStore` (+ `SmbCloudInMemoryCredentialsStore`).
40 - `SmbCloudError` / `SmbCloudErrorCode`, `AccountStatus`, `User`, `SignupResult`.
41
42 `SmbCloudAuth` adds the Apple UI/platform layer and re-exports `AuthCore`:
43
44 - `SmbCloudWebAuth` — `ASWebAuthenticationSession` hosted login over the OIDC flow
45 - `SmbCloudCredentialsManager` — Keychain-backed `SmbCloudCredentialsStore`
46
47 ### Confidential vs public clients
48
49 - **Confidential** (`AuthCoreClient`): `appId` + `appSecret`. Use it where the
50 secret stays private — a backend / BFF, the CLI, server-side Swift. The
51 email/password `login`/`signup` calls require it.
52 - **Public** (`SmbCloudWebAuth` / `OIDC`): no secret. This is the path for
53 native and browser apps. **Never ship `appSecret` in a distributed app.**
54
55 ### Relationship to the Rust SDK
56
57 The contract authority is the Rust crate
58 [`smbcloud-cli/crates/smbcloud-auth-sdk`](https://github.com/smbcloudXYZ/smbcloud-cli),
59 which the `-py` and `-wasm` bindings wrap. `AuthCore` is a faithful **native**
60 Swift port of it (no Rust/UniFFI dependency, so it builds with plain
61 `swift build` everywhere, including Linux servers), pinned to the crate by a
62 shared conformance suite. Apple consumers use this package directly — there is
63 no UniFFI Apple binding. See
64 [`Docs/AuthCore-SDK-Surface.md`](Docs/AuthCore-SDK-Surface.md).
65
66 ## Installation
67
68 ### Swift Package Manager
69
70 ```swift
71 dependencies: [
72 .package(url: "https://github.com/smbcloudXYZ/smbcloud-auth-swift", from: "1.0.0")
73 ],
74 targets: [
75 // Apple app: the UI layer.
76 .target(name: "MyApp", dependencies: [
77 .product(name: "SmbCloudAuth", package: "smbcloud-auth-swift")
78 ]),
79 // Server / cross-platform: the headless engine.
80 .target(name: "MyServer", dependencies: [
81 .product(name: "AuthCore", package: "smbcloud-auth-swift")
82 ])
83 ]
84 ```
85
86 ## Quick example (Apple, public client)
87
88 ```swift
89 import SmbCloudAuth
90
91 let webAuth = SmbCloudWebAuth(
92 environment: .production,
93 oidcClientId: "your-oidc-client-id",
94 redirectURL: URL(string: "myapp://auth/callback")!
95 )
96
97 let credentials = SmbCloudCredentialsManager(
98 service: "com.example.myapp.smbcloud-auth"
99 )
100
101 let session = try await webAuth.login(
102 presentationAnchorProvider: { window },
103 credentialsManager: credentials
104 )
105
106 let user = try await webAuth.userInfo(session: session)
107 print(user.email ?? "Signed in")
108 ```
109
110 ## Quick example (server-side / headless, confidential client)
111
112 On a backend (e.g. a Vapor service) you hold the `appSecret` and can use the
113 tenant credential flow directly:
114
115 ```swift
116 import AuthCore
117
118 let client = AuthCoreClient(
119 environment: .production,
120 credentials: ClientCredentials(appId: appId, appSecret: appSecret)
121 )
122
123 switch try await client.login(username: email, password: password) {
124 case .ready(let accessToken):
125 let user = try await client.me(accessToken: accessToken) // GET /v1/client/me
126 print(user.email)
127 case .incomplete(let status):
128 print("Account not ready: \(status)") // e.g. .emailUnverified
129 case .notFound:
130 print("No such account")
131 }
132 ```
133
134 `AuthCoreClient.login` returns the access token inside `.ready(accessToken:)` as
135 the full `Authorization` header value (it already includes `Bearer `); pass it
136 back to `me`/`logout`/`remove` verbatim.
137
138 ## Platforms
139
140 `SmbCloudAuth` (hosted-login UI + Keychain):
141
142 | Platform | Minimum |
143 |----------|---------|
144 | iOS | 16.0 |
145 | macOS | 14.0 |
146 | tvOS | 16.0 |
147 | visionOS | 1.0 |
148
149 `SmbCloudWebAuth` runs on iOS, macOS, and visionOS. `AuthCore` additionally
150 builds on **Linux, Windows, and Android**, with no dependency on UIKit/AppKit,
151 `AuthenticationServices`, or the Keychain (it uses
152 [swift-crypto](https://github.com/apple/swift-crypto) for OIDC PKCE off Apple
153 platforms). Bring your own `SmbCloudCredentialsStore` (or use
154 `SmbCloudInMemoryCredentialsStore`) for persistence.
155
156 ## Security notes
157
158 - Native and browser apps are **public clients**: use `SmbCloudWebAuth` / `OIDC`,
159 not a shipped `appSecret`.
160 - Keep `appSecret` and email/password (`AuthCoreClient`) on a backend / BFF.
161 - Use system browser auth, not embedded webviews.
162 - `logout()` clears local credentials.
163
164 ## License
165
166 Apache 2.0. See [LICENSE](LICENSE).
167
168 ## Copyright
169
170 © 2026 [Splitfire AB](https://5mb.app) ([smbCloud](https://smbcloud.xyz)).