stack/sdks/spec/README.md
Aman Ganapathy c8694c7ff5
[Fix] [Feat] Update OAuth Sign-In and Get Token Functions to Work (#1130)
### Summary of Changes

Previously, on the Swift SDK, the `signInWithOAuth` function wasn't
working. In this PR, we fix it by having the `getOAuthUrl` function to
actually redirect correctly. Note that to do so, we updated the
`validRedirectUrl` check on the backend to accept app native redirects
(from our new trusted url scheme). Another thing to note is that we
added functionality to the `TokenStore` abstraction to conditionally
refresh the access token that the user is trying to fetch if it is
expired/close to expiring if possible. `getOAuthUrl` will attempt to get
a valid access token, and thus will rely on our algorithm documented in
`utilities.md`.

The specs serve as the source of truth.

We go further and implement Apple Native sign in. To do so, we have it
hit a new route on the backend and verify the `jwtToken` retrieved by
the sdk against an Apple-provided set of `jwks`. We use jose to do so,
in line with the rest of the codebase.

We take this opportunity to refactor the oauth provider route owing to
the amount of duplicated logic. Additionally, to enable the apple sign
in, users will have to update the Apple authentication method modal on
the dashboard and add accepted bundle ids. These are identifiers for
projects, and we will check the `JWT` on the backend to make sure the
audience is set to an accepted bundleId.

We also update the Apple modal to be more informative.

### Using the new Features

To use the Apple native sign in, users will have to 1) sign up with an
apple developer account, 2) set up their bundleids for their projects by
connecting them to the apple developer account, 3) update the Stack-Auth
Authentication Methods dashboard apple modal with the relevant fields.
Then, trying to sign in with apple with our Swift SDK will use the apple
native sign in.

### UI Changes

Renamed the fields in the apple modal. Added a new field for bundle ids.
See below.


https://github.com/user-attachments/assets/0e760c0e-3198-4818-ac7f-4900d7a125bb



Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-01-28 02:17:27 +00:00

2.8 KiB

Stack Auth SDK Specification

This folder contains the specification for Stack Auth's SDKs.

When writing this specification, try to write imperative pseudocode as much as possible (be explicit about what things are named, etc.).

Notation

The spec files use the following notation:

Notation Meaning
[authenticated] Include access token, handle 401 refresh
[server-only] Requires secretServerKey
[BROWSER-LIKE] Requires browser or browser-like environment (browser, WebView, in-app browser). On mobile, open an in-app browser (ASWebAuthenticationSession on iOS, Custom Tabs on Android). On desktop, open the system browser with a registered URL scheme.
[BROWSER-ONLY] Strictly requires browser environment (DOM, window object)
[CLI-ONLY] Only in languages/platforms with an interactive terminal
[JS-ONLY] Only available in the JavaScript SDK
{ field, field } Request body (JSON)
"Does not error" Function handles errors internally
"Errors: ..." Lists possible errors with code/message

See _utilities.spec.md for more details.

Language Adaptation

The languages should adapt:

  • Naming conventions: camelCase (JS), snake_case (Python), PascalCase (Go), etc.
  • Async patterns: Promises (JS), async/await (Python), goroutines (Go)
  • Error handling: Exceptions vs Result types (language preference)
  • Parameter conventions: Objects vs. kwargs, etc.
  • Framework hooks: Eg. for React, add use* equivalents to get*/list* methods
  • Everything else, wherever it makes sense: Every language is unique and the patterns will differ. If you have to decide between what's idiomatic in a language vs. what was done in the Stack Auth SDK for other languages, use the idiomatic pattern.

Implementation Notes

Object Construction

When constructing SDK objects (User, Team, etc.) from API responses:

  1. Map naming conventions to your language's naming convention
  2. Objects should hold a reference to the SDK client for making API calls
  3. Objects can be mutable or immutable based on language conventions
  4. update() methods should update local properties after successful API call

Caching

Normal functions should not cache. Some frameworks, like React, have hooks that require caching; for these, require explicit guidance.

Pagination

Most list* methods support pagination:

  • Request with cursor and limit query params
  • Response includes pagination: { next_cursor?: string }
  • next_cursor is null or absent when no more pages
  • Default limit is typically 100
  • Note that not all backend APIs support pagination, and some just return all items at once.

Date/Time Formats

  • API uses milliseconds since epoch for timestamps (e.g., signed_up_at_millis)
  • Convert to your language's native Date/DateTime type