You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: finish Tier 1's docs (Apple plus the two fixes)
README now lists apple among the providers, documents its four env
values and the two real differences (self-signed ES256 secret, identity
from a verified id_token); the env example gains the APPLE_* block.
NEXT.md drops the "except Apple" caveat and records the two Apple
decisions (response_mode=query, no nonce) plus what is still owed:
a DB-backed smoke-test run, a live Apple round trip, and the WebAuthn
ceremonies. CURRENT-STATE.md gains the Apple/what-is-tested section and
the two bug fixes, and its verification-gap paragraph now names exactly
which paths this sandbox could not exercise. PROGRESS.md gains the
continuation entry.
Copy file name to clipboardExpand all lines: README.md
+18-3Lines changed: 18 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,15 +32,30 @@ GITHUB_CLIENT_SECRET=...
32
32
33
33
A provider missing its client ID or secret is simply unavailable — its endpoints return `404 oauth_provider_not_configured` rather than the server refusing to start.
34
34
35
-
Supported providers are `google`, `github`, `microsoft`, `discord` and `gitlab` — all the same authorization-code shape, so each is one case in `httpapi/oauth_handlers.go` plus its env vars:
35
+
Supported providers are `google`, `github`, `microsoft`, `discord`, `gitlab` and `apple`.
36
+
37
+
`google`/`github`/`microsoft`/`discord`/`gitlab` all have the same authorization-code shape, so each is one case in `httpapi/oauth_handlers.go` plus its env vars:
Apple is **not** wired up yet — its client "secret" is a short-lived JWT you sign with a key from Apple's developer console rather than a static string, and the email arrives inside a signed `id_token` instead of from a userinfo call. It needs its own piece of work, not another case in that switch.
45
+
Apple is the one that does not fit that shape, and it is the only provider needing more than an ID and a secret:
46
+
47
+
```
48
+
APPLE_CLIENT_ID=com.example.web # your Services ID, not the app bundle ID
- Its client "secret" is a short-lived ES256 JWT this API signs itself (`httpapi/apple.go`), which is why it needs the `.p8` key rather than a string. In `.env`, write the key's newlines as `\n`; a real multiline value passed through a secret manager is used as-is.
55
+
- There is no userinfo endpoint. The email and account ID come from the `id_token` in the token response, verified against Apple's published signing keys (issuer, audience, expiry and RS256 all enforced) rather than merely decoded.
56
+
- The authorization request pins `response_mode=query`, so the existing GET callback route works unchanged. Consequently the one-time `user` payload (the name Apple sends only on a first authorization) is not captured — this API stores the id_token's email, not names.
57
+
58
+
All four `APPLE_*` values are required; a partially configured Apple is simply unavailable, like any other unconfigured provider.
44
59
45
60
## Second factors
46
61
@@ -129,7 +144,7 @@ POST /v1/login/passkey/finish (completes a paused login)
129
144
POST /v1/login/recovery-code (completes a paused login)
130
145
```
131
146
132
-
`{provider}` is `google`, `github`, `microsoft`, `discord`or `gitlab`.
147
+
`{provider}` is `google`, `github`, `microsoft`, `discord`, `gitlab`or `apple`.
133
148
The two OAuth flows are separate
134
149
on purpose:
135
150
-`/oauth/{provider}` → `/oauth/{provider}/callback` is login/signup —
0 commit comments