> ## Documentation Index
> Fetch the complete documentation index at: https://gleanfeed.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-service sign-in

> Let customers create or access a portal account with magic link or Google and return securely to the in-app portal.

Use self-service sign-in when customers can open Glean Feed without first signing into your app. The hosted portal displays its normal **Sign in** and **Create account** controls inside the SDK.

<Note>
  If your app already has customer accounts, [server-signed identity](/docs/ios-sdk/identity) gives the
  smoothest experience. Call `identify` and customers do not need a second sign-in.
</Note>

## 1. Register a callback scheme

Choose a unique lowercase reverse-domain value, for example:

```text theme={null}
com.example.your-app.gleanfeed
```

In Xcode, select your app target, open **Info → URL Types**, add a URL type, and enter that value under **URL Schemes**. Then pass the exact value to `setup`:

```swift theme={null}
GleanFeed.setup(
  workspaceId: "your-workspace-uuid",
  workspaceSlug: "your-workspace-slug",
  callbackURLScheme: "com.example.your-app.gleanfeed"
)
```

## 2. Forward magic-link callbacks

Google sign-in returns through Apple's authentication session automatically. Magic links open from the customer's email app, so your app must forward the incoming URL to Glean Feed.

### SwiftUI

```swift theme={null}
@main
struct ExampleApp: App {
  init() {
    GleanFeed.setup(
      workspaceId: "your-workspace-uuid",
      workspaceSlug: "your-workspace-slug",
      callbackURLScheme: "com.example.your-app.gleanfeed"
    )
  }

  var body: some Scene {
    WindowGroup {
      ContentView()
        .onOpenURL { url in
          GleanFeed.handleOpenURL(url)
        }
    }
  }
}
```

### UIKit scene delegate

```swift theme={null}
func scene(_ scene: UIScene, openURLContexts contexts: Set<UIOpenURLContext>) {
  for context in contexts where GleanFeed.handleOpenURL(context.url) {
    return
  }

  // Handle your app's other URL schemes here.
}
```

## What customers experience

* **Google:** iOS presents the standard secure web authentication sheet. After Google completes, the sheet closes and the authenticated portal continues in the existing Glean Feed view.
* **Magic link:** Glean Feed sends the normal branded email. Tapping the link verifies the address, returns to your app, and finishes in the existing Glean Feed view.

The SDK stores an unfinished transaction in the device Keychain, so the callback can resume after suspension or a cold launch.

## Security model

The flow uses OAuth-style authorization code exchange with PKCE:

* The app creates a fresh verifier and sends only its SHA-256 challenge.
* The browser callback contains a short-lived, single-use authorization code—not a portal session or long-lived user token.
* Completion requires the callback code, the app-held PKCE verifier, and a separate device secret.
* The server atomically consumes the transaction. Replays and callbacks for another transaction fail.
* The final portal handoff is accepted only on the exact portal origin already loaded by the SDK.

Do not parse or exchange the callback yourself. Forward the URL unchanged to `GleanFeed.handleOpenURL(_:)`.
