AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Auth0 Swift Major Migration

skill-auth0-agent-skills-auth0-swift-major-migration · by auth0

>

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-auth0-agent-skills-auth0-swift-major-migration

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-auth0-agent-skills-auth0-swift-major-migration)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Auth0 Swift Major Migration? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Auth0.swift v3 Migration

Migrates an existing Auth0.swift v2 integration to v3. Every code change is gated on a search that confirms the project actually calls the affected API — if the project never uses CredentialsManager, no CredentialsManager code is touched. Changes follow the project's existing architecture and Apple platform conventions.

When NOT to Use

  • New Auth0 integration (no existing Auth0.swift): Use [auth0-swift](/auth0-swift)
  • Minor/patch update (e.g., 2.17 → 2.18): Run pod update Auth0 or update SPM — no migration needed
  • Android apps: Use [auth0-android](/auth0-android)
  • React Native / Expo: Use [auth0-react-native](/auth0-react-native) or [auth0-expo](/auth0-expo)

Prerequisites

  • Existing Auth0.swift v2 integration
  • Xcode installed; project builds cleanly on the current version
  • Project under git version control with a clean working tree

Migration Workflow

> Agent instruction: Execute every step in order. The goal is a green build with the smallest correct changeset. Each code-change step is gated by the Step 4 file-reading audit — if the API was not found in the project's source files, skip the entire step for that area. Never add code the project doesn't already call.


Step 1 — Pre-flight & Safety Backup

# 1a. Verify clean working tree — stop if there are uncommitted changes
git status --porcelain

If the output is non-empty, ask the user: > "You have uncommitted changes. Should I stash them before proceeding (git stash), or would you like to commit first?"

# 1b. Create a safety branch the user can reset to at any time
git checkout -b auth0-v3-migration-backup
git checkout -
# 1c. Pick an available simulator, then confirm the project builds before touching anything
SIM=$(xcrun simctl list devices available -j \
  | python3 -c "import sys,json; d=json.load(sys.stdin); \
    phones=[dev for devs in d['devices'].values() for dev in devs \
            if 'iPhone' in dev.get('name','') and dev.get('isAvailable')]; \
    print(phones[0]['name'] if phones else 'iPhone 16')")
xcodebuild build \
  -scheme  \
  -destination "platform=iOS Simulator,name=${SIM}" \
  2>&1 | tail -5

If the build fails, stop. Ask the user to fix the existing issues first.


Step 2 — Detect Current & Target Versions

Detect the current Auth0.swift version from the project's dependency files:

# Check Package.resolved first (most reliable)
find . -name "Package.resolved" | xargs grep -A3 '"auth0/Auth0.swift"\|Auth0.swift"' 2>/dev/null | grep '"version"'

# Fallback: Podfile.lock
grep "^  - Auth0 " Podfile.lock 2>/dev/null

# Fallback: Cartfile.resolved
grep "auth0/Auth0.swift" Cartfile.resolved 2>/dev/null

# Fallback: Package.swift
grep -A2 'auth0/Auth0.swift' Package.swift 2>/dev/null

Resolve the target version. There are two paths:

Path A — the user passed a target version argument ($ARGUMENTS):

Validate it against the published releases before using it. It must pass all three checks:

# List all published Auth0.swift v3 release tags
curl -s https://api.github.com/repos/auth0/Auth0.swift/releases | python3 -c "
import sys, json
releases = json.load(sys.stdin)
v3 = [r for r in releases if r['tag_name'].startswith('3') and not r['draft']]
for r in v3:
    print(r['tag_name'])
"
  1. Exists — the requested tag appears in the published release list above.
  2. Correct major — the tag is within the v3 major line (starts with 3). A 2.x or any other major is not valid; reject it.
  3. Not a downgrade — the tag is newer than the version detected in the project.

> On any check failing, STOP and ask the user. Do not silently fall back. For example: > - "3.9.9 isn't a published Auth0.swift release. Published v3 releases are: 3.0.0-beta.2, … . Please pass a valid v3 tag, or omit the argument to auto-resolve the latest v3 release." > - "2.10.0 is a v2 release, not v3. This skill migrates to v3. Pass a v3 tag (e.g. 3.0.0-beta.2) or omit the argument." > - "3.0.0-beta.1 is older than the 3.0.0-beta.2 already in your project — that's a downgrade. Pass a newer v3 tag or omit the argument."

Path B — no argument: auto-resolve the latest v3 release (including pre-releases):

# Newest v3.x release tag (stable or pre-release), most recent first
curl -s https://api.github.com/repos/auth0/Auth0.swift/releases | python3 -c "
import sys, json
releases = json.load(sys.stdin)
v3 = [r for r in releases if r['tag_name'].startswith('3') and not r['draft']]
if v3:
    print(v3[0]['tag_name'])
else:
    print('')
"

Record the result as `` and use it in every subsequent step.

> **If ` is a pre-release** (contains -beta, -rc, etc.), inform the user before continuing: > *"The latest v3 release is (a pre-release). I'll migrate to that. You can pin a different tag by passing it as an argument: auth0-swift-major-migration `."* > > If no v3 release exists (the resolver returns empty), stop and tell the user there is no published v3 release to migrate to.


Step 3 — Fetch & Read the v3 SDK Source

Fetch the actual Swift source for the target tag. The signatures here are the authoritative reference for every change made in Step 6.

TAG=   # the version the developer chose in Step 2, e.g. 3.0.0-beta.2

# List all public Swift files in the SDK
curl -s "https://api.github.com/repos/auth0/Auth0.swift/git/trees/${TAG}?recursive=1" \
  | python3 -c "
import sys, json
for item in json.load(sys.stdin).get('tree', []):
    if item['path'].startswith('Auth0/') and item['path'].endswith('.swift'):
        print(item['path'])
"

# Fetch core public API files
for FILE in WebAuth.swift CredentialsManager.swift Authentication.swift \
            Credentials.swift UserProfile.swift Requestable.swift \
            CredentialsStorage.swift CredentialsManagerError.swift WebAuthError.swift; do
    URL="https://raw.githubusercontent.com/auth0/Auth0.swift/${TAG}/Auth0/${FILE}"
    CONTENT=$(curl -sf "$URL")
    [ -n "$CONTENT" ] && echo "=== $FILE ===" && echo "$CONTENT"
done

# MFA files live in a subdirectory
for FILE in MFA/MFAClient.swift MFA/MFAErrors.swift; do
    URL="https://raw.githubusercontent.com/auth0/Auth0.swift/${TAG}/Auth0/${FILE}"
    CONTENT=$(curl -sf "$URL")
    [ -n "$CONTENT" ] && echo "=== $FILE ===" && echo "$CONTENT"
done

Read the fetched source and note:

  • Every public method signature that changed (return type, parameters, throws added)
  • Types that were renamed or removed
  • Protocol requirements that changed
  • Default parameter values that changed

This is the ground truth. Every change in Step 6 must match a real signature in these files.


Step 4 — Audit Which Auth0 APIs the Project Uses

Find all Swift files that import Auth0 — these are the scope of the migration:

grep -rl "import Auth0" --include="*.swift" .

Read every file from that list. Do not grep for specific API patterns — read the full source so you can see exactly how Auth0, webAuth, authentication, credentialsManager, and any Auth0 types are used, including calls with domain/clientId parameters, chained builder calls, and any custom conformances.

For each file, identify:

| What to look for | Why it matters | |---|---| | Any call to webAuth(), webAuth(domain:), webAuth(domain:clientId:) | §6.1 – clearSession rename; §6.14 – default scope | | Any call to .clearSession( | §6.1 — rename to logout | | Switch/catch on WebAuthError with explicit case names | §6.2 — removed and new cases | | DispatchQueue.main.async or MainActor.run wrapping an Auth0 callback | §6.3 — removable in v3 | | Any stored Request type annotation (not just chained .start(…)) | §6.4 — type changed to Requestable | | Test mocks conforming to Authentication, MFAClient, or Requestable | §6.4 — return type + @MainActor update | | Any call to credentialsManager.store( | §6.5 — Bool → throws | | Any call to credentialsManager.clear() or credentialsManager.clear(forAudience: | §6.6 — Bool → throws (both overloads) | | Any access to credentialsManager.user (property, not method) | §6.7 — replaced by userProfile() method | | Any call to credentialsManager.revoke( | §6.8 — new error paths | | Any type annotation or declaration using UserInfo | §6.9 — renamed to UserProfile | | Any access to .expiresIn on a Credentials-like object | §6.10 — renamed to expiresAt | | Any type conforming to CredentialsStorage | §6.11 — method signatures changed | | Any call to Auth0.users( or Auth0.users(token: | §6.12 — Management client removed | | login(withOTP:, login(withOOBCode:, login(withRecoveryCode:, multifactorChallenge( | §6.13 — MFA methods removed | | Any call to webAuth() that does not chain .scope( | §6.14 — default scope changed | | Any call to credentialsManager.credentials( without explicit minTTL: parameter | §6.15 — default minTTL changed from 0 to 60 seconds |

Build a checklist: "This project uses: [list]" and "This project does NOT use: [list]". Only work through the §6.x sections that appear in the "uses" list. Skip the rest entirely.


Step 5 — Update the SDK Dependency

Apply only the matching package manager.

Use the ` chosen in Step 2. For stable releases (3.x.y with no suffix), use a range specifier. For pre-releases (3.x.y-beta.z), pin the exact tag — package managers treat pre-release versions as out-of-range for ~> / from:` rules.

Swift Package Manager (Package.swift):

// Stable v3 — range specifier picks up all 3.x.y patches
.package(url: "https://github.com/auth0/Auth0.swift", from: "3.0.0")

// Pre-release / specific beta — exact tag required
.package(url: "https://github.com/auth0/Auth0.swift", exact: "3.0.0-beta.2")

Then resolve:

swift package resolve

CocoaPods (Podfile):

# Stable v3
pod 'Auth0', '~> 3.0'

# Pre-release / specific beta — pin the exact version
pod 'Auth0', '3.0.0-beta.2'

Then:

pod update Auth0

Carthage (Cartfile):

# Stable v3
github "auth0/Auth0.swift" ~> 3.0

# Pre-release / specific beta — pin the exact tag
github "auth0/Auth0.swift" "3.0.0-beta.2"

Then:

carthage update Auth0.swift --use-xcframeworks

Xcode-managed SPM (no Package.swift at root):

  • Stable: File → Packages → Update to Latest Package Versions, then verify the version rule is Up to Next Major from 3.0.0.
  • Pre-release / specific beta: File → Packages → Update to Latest Package Versions won't resolve a beta unless the dependency already pins an exact version. Tell the user to change the version rule to Exact Version and enter 3.0.0-beta.2 (or the chosen tag).

Do not build yet — apply all known code changes first.


Step 6 — Apply Breaking Changes

> Agent instruction: Work through only the §6.x sections that matched during the Step 4 file-reading audit. Skip every section whose API the project does not use — do not touch those files. > > Apply each change exactly as shown. Do not alter surrounding code, rename variables, reformat, or modernise code that isn't being migrated. Match the project's existing style: completion handler → completion handler, async/await → async/await, Combine → Combine.


6.1 — WebAuth.clearSession()WebAuth.logout()

Applies if: Step 4 found any call to .clearSession( in the project's source files.

The clearSession(federated:) method was renamed to logout(federated:). The parameter and its default value are unchanged.

Completion handler:

// v2
Auth0.webAuth().clearSession { result in
    switch result {
    case .success: handleLogoutSuccess()
    case .failure(let error): handleError(error)
    }
}

// v3
Auth0.webAuth().logout { result in
    switch result {
    case .success: handleLogoutSuccess()
    case .failure(let error): handleError(error)
    }
}

async/await:

// v2
try await Auth0.webAuth().clearSession()

// v3
try await Auth0.webAuth().logout()

Combine:

// v2
Auth0.webAuth().clearSession()
    .sink(receiveCompletion: { ... }, receiveValue: { ... })
    .store(in: &cancellables)

// v3
Auth0.webAuth().logout()
    .sink(receiveCompletion: { ... }, receiveValue: { ... })
    .store(in: &cancellables)

With federated: true: The parameter name is the same — just rename the method:

// v2
try await Auth0.webAuth().clearSession(federated: true)

// v3
try await Auth0.webAuth().logout(federated: true)

6.2 — WebAuthError — removed and new cases in exhaustive switch statements

Applies if: Step 4 found any switch or catch on WebAuthError with explicit case names in the project's source files.

Two WebAuthError cases were removed in v3. If the project has an exhaustive switch over WebAuthError (or explicitly matches these cases), the build will fail.

Three new cases were added to surface previously hidden failures.

Removed cases (will no longer compile if matched):

| v2 case | v3 behaviour | |---|---| | .invalidInvitationURL | Removed — now surfaces as .unknown | | .pkceNotAllowed | Removed — now surfaces as .unknown |

New cases (can now appear in catch/switch blocks):

| v3 case | When it fires | |---|---| | .authenticationFailed | Server-side failure: wrong password, MFA required, account locked, etc. | | .codeExchangeFailed | Token exchange failed: network issue, invalid grant, backend error | | .credentialsManagerError | Credentials manager failed to store or clear credentials after login/logout; access the underlying error via .cause |

Migration — remove the deleted cases from switch statements:

// v2 — exhaustive switch including cases that no longer exist
Auth0.webAuth().start { result in
    switch result {
    case .success(let credentials):
        handle(credentials)
    case .failure(let error):
        switch error {
        case .userCancelled:
            break  // user dismissed — no action needed
        case .pkceNotAllowed:
            // ❌ compile error in v3 — remove this case
            showConfigError("PKCE not allowed")
        default:
            showError(error)
        }
    }
}

// v3 — remove the deleted cases; handle the new ones where appropriate
Auth0.webAuth().start { result in
    switch result {
    case .success(let credentials):
        handle(credentials)
    case .failure(let error):
        switch error {
        case .userCancelled:
            break  // user dismissed — no action needed
        case .authenticationFailed:
            // server rejected the login — show an appropriate message
            showError("Login failed. Please check your credentials.")
        case .codeExchangeFailed:
            // token exchange failed — network or server issue
            showError("Something went wrong. Please try again.")
        case .credentialsManagerError:
            // login succeeded but credentials could not be stored
            // the user is authenticated in memory but will need to log in again next launch
            // access the underlying error via error.cause (WebAuthError.cause: Error?)
            reportToMonitoring(error.cause)
            showError("Could not save your session.")
        default:
            showError(error)
        }
    }
}

If the project uses async/await and catches specific cases:

// v2
do {
    let credentials = try await Auth0.webAuth().start()
    handle(credentials)
} catch WebAuthError.userCancelled {
    break
} catch WebAuthError.pkceNotAllowed {
    // ❌ compile error in v3 — remove this catch
    showConfigError()
} catch {
    showError(error)
}

// v3 — remove deleted cases; add new ones if the project should handle them
do {
    let credentials = try await Auth0.webAuth().start()
    hand

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [auth0](https://github.com/auth0)
- **Source:** [auth0/agent-skills](https://github.com/auth0/agent-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.