@ory/argus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -0
- package/assets/commands/local-down.md +19 -0
- package/assets/commands/local-up.md +27 -0
- package/assets/skills/auth-setup/SKILL.md +279 -0
- package/assets/skills/local-dev/SKILL.md +206 -0
- package/assets/skills/login-flow/SKILL.md +383 -0
- package/assets/skills/social-login/SKILL.md +312 -0
- package/dist/agent-auth.d.ts +204 -0
- package/dist/agent-auth.js +553 -0
- package/dist/auth-gate.d.ts +71 -0
- package/dist/auth-gate.js +308 -0
- package/dist/auth-store.d.ts +75 -0
- package/dist/auth-store.js +261 -0
- package/dist/auth.d.ts +93 -0
- package/dist/auth.js +323 -0
- package/dist/cli.d.ts +73 -0
- package/dist/cli.js +484 -0
- package/dist/client.d.ts +158 -0
- package/dist/client.js +679 -0
- package/dist/config.d.ts +135 -0
- package/dist/config.js +344 -0
- package/dist/denial.d.ts +79 -0
- package/dist/denial.js +103 -0
- package/dist/dev.d.ts +95 -0
- package/dist/dev.js +514 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +137 -0
- package/dist/local/cli.d.ts +12 -0
- package/dist/local/cli.js +95 -0
- package/dist/local/configs.d.ts +89 -0
- package/dist/local/configs.js +634 -0
- package/dist/local/health.d.ts +32 -0
- package/dist/local/health.js +65 -0
- package/dist/local/index.d.ts +6 -0
- package/dist/local/index.js +38 -0
- package/dist/local/jaeger-main.d.ts +13 -0
- package/dist/local/jaeger-main.js +85 -0
- package/dist/local/jaeger.d.ts +50 -0
- package/dist/local/jaeger.js +162 -0
- package/dist/local/main.d.ts +7 -0
- package/dist/local/main.js +14 -0
- package/dist/local/manager.d.ts +45 -0
- package/dist/local/manager.js +676 -0
- package/dist/local/seed.d.ts +71 -0
- package/dist/local/seed.js +237 -0
- package/dist/logger.d.ts +29 -0
- package/dist/logger.js +139 -0
- package/dist/mcp.d.ts +76 -0
- package/dist/mcp.js +122 -0
- package/dist/otel/exporter.d.ts +17 -0
- package/dist/otel/exporter.js +12 -0
- package/dist/otel/index.d.ts +2 -0
- package/dist/otel/index.js +8 -0
- package/dist/otel/otlp-http.d.ts +116 -0
- package/dist/otel/otlp-http.js +322 -0
- package/dist/registry/cli.d.ts +12 -0
- package/dist/registry/cli.js +76 -0
- package/dist/registry/config.d.ts +23 -0
- package/dist/registry/config.js +80 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.js +21 -0
- package/dist/registry/main.d.ts +7 -0
- package/dist/registry/main.js +14 -0
- package/dist/registry/manager.d.ts +38 -0
- package/dist/registry/manager.js +674 -0
- package/dist/setup.d.ts +118 -0
- package/dist/setup.js +398 -0
- package/dist/skills.d.ts +78 -0
- package/dist/skills.js +264 -0
- package/dist/subject.d.ts +43 -0
- package/dist/subject.js +55 -0
- package/dist/tool-metadata.d.ts +41 -0
- package/dist/tool-metadata.js +127 -0
- package/dist/tracer.d.ts +172 -0
- package/dist/tracer.js +452 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.js +3 -0
- package/dist/watch-sandbox.d.ts +9 -0
- package/dist/watch-sandbox.js +81 -0
- package/package.json +79 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ory-login-flow
|
|
3
|
+
description: Build login, registration, account recovery, email verification, and account settings pages using Ory Elements. Use whenever the user asks for a login page, sign-in UI, sign-up form, "forgot password" flow, account settings page, or wants to wire Ory's self-service flows into a frontend. Ory Elements is the default rendering layer; only fall back to custom UI nodes if Elements cannot run in the target environment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Build Auth Pages with Ory Elements
|
|
7
|
+
|
|
8
|
+
You are building login, registration, recovery, verification, and
|
|
9
|
+
settings pages using **[Ory Elements](https://github.com/ory/elements)**
|
|
10
|
+
— a prebuilt UI component library that renders Ory's self-service flows.
|
|
11
|
+
|
|
12
|
+
**Default rule: every page in this guide is rendered with Ory Elements.**
|
|
13
|
+
Do not hand-roll forms from `flow.ui.nodes` unless the user has
|
|
14
|
+
explicitly opted out after seeing the Ory Elements path. Custom node
|
|
15
|
+
rendering belongs in the fallback section at the end of this skill.
|
|
16
|
+
|
|
17
|
+
## Why Ory Elements
|
|
18
|
+
|
|
19
|
+
- One component per flow (`<Login>`, `<Registration>`, `<Recovery>`,
|
|
20
|
+
`<Verification>`, `<Settings>`) covers the entire self-service surface.
|
|
21
|
+
- Handles CSRF tokens, error messages, multi-step states, social
|
|
22
|
+
buttons, passkeys, and MFA prompts automatically.
|
|
23
|
+
- New node types and flow capabilities ship with Elements upgrades —
|
|
24
|
+
no per-app rewrite needed.
|
|
25
|
+
- Works in Next.js (App Router and Pages Router) and any React SPA.
|
|
26
|
+
|
|
27
|
+
## Before you start
|
|
28
|
+
|
|
29
|
+
Check the project setup:
|
|
30
|
+
|
|
31
|
+
1. Identify the framework: Next.js (App Router preferred), React SPA
|
|
32
|
+
(Vite, CRA, Remix client routes), Vue, or server-rendered. Vue and
|
|
33
|
+
server-rendered apps drop into the fallback path below.
|
|
34
|
+
2. Verify Ory Elements and the SDK are installed. If not:
|
|
35
|
+
|
|
36
|
+
For Next.js:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @ory/elements-react @ory/nextjs @ory/client-fetch
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For React SPAs:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @ory/elements-react @ory/client-fetch
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. Verify `ORY_SDK_URL` or `NEXT_PUBLIC_ORY_SDK_URL` is configured in
|
|
49
|
+
the environment.
|
|
50
|
+
|
|
51
|
+
If Ory is not set up at all, suggest the user run
|
|
52
|
+
{{REF_AUTH_SETUP}} first.
|
|
53
|
+
|
|
54
|
+
## Understand Ory self-service flows
|
|
55
|
+
|
|
56
|
+
Ory uses a **self-service flow** model. Each auth action
|
|
57
|
+
(login, registration, recovery, verification, settings) is a "flow"
|
|
58
|
+
with these stages:
|
|
59
|
+
|
|
60
|
+
1. **Initialize** — call the Ory API to create a flow (returns a flow
|
|
61
|
+
object with UI nodes).
|
|
62
|
+
2. **Render** — display the form. **Ory Elements does this for you.**
|
|
63
|
+
3. **Submit** — post the user's input back to Ory. Ory Elements wires
|
|
64
|
+
the form action; in the SPA flow you call
|
|
65
|
+
`updateLoginFlow` / `updateRegistrationFlow` / etc.
|
|
66
|
+
4. **Handle result** — redirect on success, show errors on failure.
|
|
67
|
+
Ory Elements surfaces errors in-form automatically.
|
|
68
|
+
|
|
69
|
+
## Build the login page
|
|
70
|
+
|
|
71
|
+
### Login — Next.js App Router (preferred)
|
|
72
|
+
|
|
73
|
+
Create `app/auth/login/page.tsx`:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { Login } from "@ory/elements-react/theme"
|
|
77
|
+
import { getLoginFlow, OryPageLayout } from "@ory/nextjs/app"
|
|
78
|
+
|
|
79
|
+
export default async function LoginPage(props: {
|
|
80
|
+
searchParams: Promise<{ flow?: string; return_to?: string }>
|
|
81
|
+
}) {
|
|
82
|
+
const searchParams = await props.searchParams
|
|
83
|
+
const flow = await getLoginFlow(searchParams)
|
|
84
|
+
|
|
85
|
+
if (!flow) {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<OryPageLayout>
|
|
91
|
+
<Login flow={flow} />
|
|
92
|
+
</OryPageLayout>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Login — React SPA
|
|
98
|
+
|
|
99
|
+
Use the same `<Login>` component from `@ory/elements-react/theme`.
|
|
100
|
+
Initialize the flow via the SDK and pass it in:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { useEffect, useState } from "react";
|
|
104
|
+
import { FrontendApi, Configuration, LoginFlow } from "@ory/client-fetch";
|
|
105
|
+
import { Login } from "@ory/elements-react/theme";
|
|
106
|
+
import "@ory/elements-react/theme/styles.css";
|
|
107
|
+
|
|
108
|
+
const ory = new FrontendApi(
|
|
109
|
+
new Configuration({
|
|
110
|
+
basePath: import.meta.env.VITE_ORY_SDK_URL,
|
|
111
|
+
credentials: "include",
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export function LoginPage() {
|
|
116
|
+
const [flow, setFlow] = useState<LoginFlow | null>(null);
|
|
117
|
+
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
const params = new URLSearchParams(window.location.search);
|
|
120
|
+
const flowId = params.get("flow");
|
|
121
|
+
|
|
122
|
+
const load = flowId
|
|
123
|
+
? ory.getLoginFlow({ id: flowId })
|
|
124
|
+
: ory.createBrowserLoginFlow();
|
|
125
|
+
|
|
126
|
+
load.then(setFlow).catch(console.error);
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
if (!flow) return <div>Loading…</div>;
|
|
130
|
+
|
|
131
|
+
return <Login flow={flow} />;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`<Login>` handles CSRF, error rendering, social buttons, passkeys,
|
|
136
|
+
and submission for you. Do not unwrap `flow.ui.nodes` here.
|
|
137
|
+
|
|
138
|
+
## Build the registration page
|
|
139
|
+
|
|
140
|
+
### Registration — Next.js App Router
|
|
141
|
+
|
|
142
|
+
Create `app/auth/registration/page.tsx`:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { Registration } from "@ory/elements-react/theme"
|
|
146
|
+
import { getRegistrationFlow, OryPageLayout } from "@ory/nextjs/app"
|
|
147
|
+
|
|
148
|
+
export default async function RegistrationPage(props: {
|
|
149
|
+
searchParams: Promise<{ flow?: string; return_to?: string }>
|
|
150
|
+
}) {
|
|
151
|
+
const searchParams = await props.searchParams
|
|
152
|
+
const flow = await getRegistrationFlow(searchParams)
|
|
153
|
+
|
|
154
|
+
if (!flow) {
|
|
155
|
+
return null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<OryPageLayout>
|
|
160
|
+
<Registration flow={flow} />
|
|
161
|
+
</OryPageLayout>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Registration — React SPA
|
|
167
|
+
|
|
168
|
+
Mirror the login pattern: initialize with `createBrowserRegistrationFlow`
|
|
169
|
+
(or `getRegistrationFlow` when a `flow` query param is present) and
|
|
170
|
+
render `<Registration flow={flow} />` from `@ory/elements-react/theme`.
|
|
171
|
+
|
|
172
|
+
## Build the account recovery page
|
|
173
|
+
|
|
174
|
+
### Recovery — Next.js App Router
|
|
175
|
+
|
|
176
|
+
Create `app/auth/recovery/page.tsx`:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { Recovery } from "@ory/elements-react/theme"
|
|
180
|
+
import { getRecoveryFlow, OryPageLayout } from "@ory/nextjs/app"
|
|
181
|
+
|
|
182
|
+
export default async function RecoveryPage(props: {
|
|
183
|
+
searchParams: Promise<{ flow?: string }>
|
|
184
|
+
}) {
|
|
185
|
+
const searchParams = await props.searchParams
|
|
186
|
+
const flow = await getRecoveryFlow(searchParams)
|
|
187
|
+
|
|
188
|
+
if (!flow) {
|
|
189
|
+
return null
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<OryPageLayout>
|
|
194
|
+
<Recovery flow={flow} />
|
|
195
|
+
</OryPageLayout>
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Recovery — React SPA
|
|
201
|
+
|
|
202
|
+
Initialize with `createBrowserRecoveryFlow` and render
|
|
203
|
+
`<Recovery flow={flow} />` from `@ory/elements-react/theme`.
|
|
204
|
+
|
|
205
|
+
## Build the verification page
|
|
206
|
+
|
|
207
|
+
### Verification — Next.js App Router
|
|
208
|
+
|
|
209
|
+
Create `app/auth/verification/page.tsx`:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { Verification } from "@ory/elements-react/theme"
|
|
213
|
+
import { getVerificationFlow, OryPageLayout } from "@ory/nextjs/app"
|
|
214
|
+
|
|
215
|
+
export default async function VerificationPage(props: {
|
|
216
|
+
searchParams: Promise<{ flow?: string }>
|
|
217
|
+
}) {
|
|
218
|
+
const searchParams = await props.searchParams
|
|
219
|
+
const flow = await getVerificationFlow(searchParams)
|
|
220
|
+
|
|
221
|
+
if (!flow) {
|
|
222
|
+
return null
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<OryPageLayout>
|
|
227
|
+
<Verification flow={flow} />
|
|
228
|
+
</OryPageLayout>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Verification — React SPA
|
|
234
|
+
|
|
235
|
+
Initialize with `createBrowserVerificationFlow` and render
|
|
236
|
+
`<Verification flow={flow} />` from `@ory/elements-react/theme`.
|
|
237
|
+
|
|
238
|
+
## Build the account settings page
|
|
239
|
+
|
|
240
|
+
### Settings — Next.js App Router
|
|
241
|
+
|
|
242
|
+
Create `app/auth/settings/page.tsx`:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { Settings } from "@ory/elements-react/theme"
|
|
246
|
+
import { getSettingsFlow, OryPageLayout } from "@ory/nextjs/app"
|
|
247
|
+
|
|
248
|
+
export default async function SettingsPage(props: {
|
|
249
|
+
searchParams: Promise<{ flow?: string }>
|
|
250
|
+
}) {
|
|
251
|
+
const searchParams = await props.searchParams
|
|
252
|
+
const flow = await getSettingsFlow(searchParams)
|
|
253
|
+
|
|
254
|
+
if (!flow) {
|
|
255
|
+
return null
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<OryPageLayout>
|
|
260
|
+
<Settings flow={flow} />
|
|
261
|
+
</OryPageLayout>
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Settings — React SPA
|
|
267
|
+
|
|
268
|
+
Initialize with `createBrowserSettingsFlow` and render
|
|
269
|
+
`<Settings flow={flow} />` from `@ory/elements-react/theme`. The
|
|
270
|
+
component handles password changes, profile traits, MFA enrollment,
|
|
271
|
+
and connected social providers.
|
|
272
|
+
|
|
273
|
+
## Add session management
|
|
274
|
+
|
|
275
|
+
Create a utility to check the current session:
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { FrontendApi, Configuration, Session } from "@ory/client-fetch";
|
|
279
|
+
|
|
280
|
+
const ory = new FrontendApi(
|
|
281
|
+
new Configuration({
|
|
282
|
+
basePath: process.env.NEXT_PUBLIC_ORY_SDK_URL,
|
|
283
|
+
credentials: "include",
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
export async function getSession(): Promise<Session | null> {
|
|
288
|
+
try {
|
|
289
|
+
return await ory.toSession();
|
|
290
|
+
} catch {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export async function logout(): Promise<void> {
|
|
296
|
+
const { logout_url } = await ory.createBrowserLogoutFlow();
|
|
297
|
+
window.location.href = logout_url;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Add route protection
|
|
302
|
+
|
|
303
|
+
### Next.js Middleware
|
|
304
|
+
|
|
305
|
+
Create `middleware.ts` at the project root:
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { createOryMiddleware } from "@ory/nextjs/middleware";
|
|
309
|
+
|
|
310
|
+
export const middleware = createOryMiddleware({
|
|
311
|
+
protectedPaths: ["/dashboard", "/settings", "/profile"],
|
|
312
|
+
publicPaths: ["/", "/auth/login", "/auth/registration", "/auth/recovery"],
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
export const config = {
|
|
316
|
+
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
|
|
317
|
+
};
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### React SPA
|
|
321
|
+
|
|
322
|
+
Wrap protected routes in a `ProtectedRoute` component that calls
|
|
323
|
+
`ory.toSession()` and redirects to `/auth/login` on failure.
|
|
324
|
+
|
|
325
|
+
## Style and customize
|
|
326
|
+
|
|
327
|
+
Ory Elements supports theming. Wrap auth pages in `<ThemeProvider>`
|
|
328
|
+
from `@ory/elements-react/theme` and pass a custom theme object.
|
|
329
|
+
Customizing the theme keeps the Elements rendering — you do not need
|
|
330
|
+
to drop down to raw nodes to restyle the forms.
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import { ThemeProvider } from "@ory/elements-react/theme";
|
|
334
|
+
|
|
335
|
+
<ThemeProvider theme={{
|
|
336
|
+
// Custom colors, fonts, spacing, radii, dark mode tokens, …
|
|
337
|
+
}}>
|
|
338
|
+
<Login flow={flow} />
|
|
339
|
+
</ThemeProvider>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
For larger design changes, the Ory Elements primitives package exposes
|
|
343
|
+
the underlying card, button, and input components — use those before
|
|
344
|
+
falling back to custom node rendering.
|
|
345
|
+
|
|
346
|
+
## Test the flow
|
|
347
|
+
|
|
348
|
+
1. Start the dev server and Ory tunnel (if developing locally)
|
|
349
|
+
2. Visit `/auth/registration` to create an account — confirm Elements
|
|
350
|
+
renders all configured methods (password, social, passkey, etc.)
|
|
351
|
+
3. Visit `/auth/login` to sign in
|
|
352
|
+
4. Verify session is established (check protected routes)
|
|
353
|
+
5. Test `/auth/recovery` with a registered email
|
|
354
|
+
6. Test `/auth/settings` for profile changes
|
|
355
|
+
7. Test logout
|
|
356
|
+
|
|
357
|
+
## Fallback: rendering UI nodes by hand
|
|
358
|
+
|
|
359
|
+
Use this path **only** when Ory Elements cannot run in the target
|
|
360
|
+
environment (e.g., a Vue app where the React Elements components are
|
|
361
|
+
not viable, a server-rendered template engine with no client bundle,
|
|
362
|
+
or a constrained native shell). Before choosing this path, confirm
|
|
363
|
+
with the user that mounting an Elements island is not an option.
|
|
364
|
+
|
|
365
|
+
In that case, iterate `flow.ui.nodes` and render each node based on
|
|
366
|
+
`node.type` (`input`, `text`, `img`, `a`, `script`) and
|
|
367
|
+
`node.attributes`. Group nodes by `node.group` (`default`, `password`,
|
|
368
|
+
`oidc`, `webauthn`, `code`, `lookup_secret`, `totp`) so each method
|
|
369
|
+
renders together. Render `flow.ui.messages` and per-node messages for
|
|
370
|
+
errors. Submit using `flow.ui.action` and `flow.ui.method`. This is
|
|
371
|
+
significantly more code than `<Login flow={flow} />` and must track
|
|
372
|
+
Ory flow API changes manually.
|
|
373
|
+
|
|
374
|
+
## Next steps
|
|
375
|
+
|
|
376
|
+
- Add social login providers: use {{REF_SOCIAL_LOGIN}}.
|
|
377
|
+
Elements renders the buttons automatically once providers are
|
|
378
|
+
configured server-side.
|
|
379
|
+
- Add multi-factor authentication via Ory project settings — the
|
|
380
|
+
`<Login>` and `<Settings>` components handle the second-factor UI.
|
|
381
|
+
- Customize the identity schema for additional profile fields. Elements
|
|
382
|
+
reads the schema from the flow and renders new fields automatically.
|
|
383
|
+
- Set up webhooks for registration events.
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ory-social-login
|
|
3
|
+
description: Configure social login (OAuth2/OIDC) providers — Google, GitHub, Apple, Microsoft, Discord, Slack, GitLab, Facebook — for an Ory-powered app. Use whenever the user wants "Sign in with Google", social sign-in buttons, OIDC providers, or any third-party identity provider on an Ory project. The skill assumes Ory Elements is rendering the auth UI; with Elements, no frontend changes are needed when adding providers.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Set up Social Login with Ory + Ory Elements
|
|
7
|
+
|
|
8
|
+
You are configuring social login (OAuth2/OIDC) providers for an
|
|
9
|
+
Ory-powered application. This adds "Sign in with Google",
|
|
10
|
+
"Sign in with GitHub", and similar buttons to the login and
|
|
11
|
+
registration flows.
|
|
12
|
+
|
|
13
|
+
**Strong recommendation: render the auth UI with [Ory Elements](https://github.com/ory/elements).**
|
|
14
|
+
With Ory Elements, social buttons appear automatically the moment a
|
|
15
|
+
provider is configured on the project — there is no frontend change
|
|
16
|
+
required for any of the providers below. If the app is using custom
|
|
17
|
+
flow rendering, point the user to {{REF_LOGIN_FLOW}} and
|
|
18
|
+
recommend switching to Ory Elements before adding more providers.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
1. **Ory CLI** — run `ory version`. If not installed:
|
|
23
|
+
- macOS: `brew install ory/tap/cli`
|
|
24
|
+
- npm: `npm install -g @ory/cli`
|
|
25
|
+
|
|
26
|
+
2. **Ory project** — run `ory list projects` to find the project ID.
|
|
27
|
+
If no project exists, suggest {{REF_AUTH_SETUP}} first.
|
|
28
|
+
|
|
29
|
+
3. **Auth pages built with Ory Elements** — confirm the project uses
|
|
30
|
+
`@ory/elements-react` (look for `<Login>` / `<Registration>` from
|
|
31
|
+
`@ory/elements-react/theme`). If pages are not built yet, suggest
|
|
32
|
+
{{REF_LOGIN_FLOW}} first. If a custom UI was hand-rolled,
|
|
33
|
+
recommend migrating to Ory Elements so social buttons render for
|
|
34
|
+
free.
|
|
35
|
+
|
|
36
|
+
## Step 1: Choose providers
|
|
37
|
+
|
|
38
|
+
Ask the user which social login providers they want. Common options:
|
|
39
|
+
|
|
40
|
+
| Provider | OIDC Type | What you need |
|
|
41
|
+
| ---------- | ----------- | --------------- |
|
|
42
|
+
| Google | OIDC | Google Cloud Console OAuth2 credentials |
|
|
43
|
+
| GitHub | OAuth2 | GitHub OAuth App or GitHub App |
|
|
44
|
+
| Apple | OIDC | Apple Developer account, Service ID |
|
|
45
|
+
| Microsoft | OIDC | Azure AD app registration |
|
|
46
|
+
| Discord | OAuth2 | Discord Developer Portal application |
|
|
47
|
+
| Slack | OIDC | Slack API app |
|
|
48
|
+
| GitLab | OIDC | GitLab application |
|
|
49
|
+
| Facebook | OAuth2 | Meta Developer app |
|
|
50
|
+
|
|
51
|
+
## Step 2: Create OAuth2 credentials with each provider
|
|
52
|
+
|
|
53
|
+
Guide the user through creating credentials for each selected provider.
|
|
54
|
+
They will need to set these up in the provider's developer console.
|
|
55
|
+
|
|
56
|
+
### Google
|
|
57
|
+
|
|
58
|
+
1. Go to Google Cloud Console > APIs & Services > Credentials
|
|
59
|
+
2. Create an OAuth 2.0 Client ID (Web application type)
|
|
60
|
+
3. Add authorized redirect URI: `https://<project-slug>.projects.oryapis.com/self-service/methods/oidc/callback/google`
|
|
61
|
+
4. Copy the **Client ID** and **Client Secret**
|
|
62
|
+
|
|
63
|
+
### GitHub
|
|
64
|
+
|
|
65
|
+
1. Go to GitHub > Settings > Developer Settings > OAuth Apps > New OAuth App
|
|
66
|
+
2. Set the Authorization callback URL: `https://<project-slug>.projects.oryapis.com/self-service/methods/oidc/callback/github`
|
|
67
|
+
3. Copy the **Client ID** and **Client Secret**
|
|
68
|
+
|
|
69
|
+
### Apple
|
|
70
|
+
|
|
71
|
+
1. Go to Apple Developer > Certificates, Identifiers & Profiles
|
|
72
|
+
2. Create a Service ID, enable "Sign in with Apple"
|
|
73
|
+
3. Configure the return URL: `https://<project-slug>.projects.oryapis.com/self-service/methods/oidc/callback/apple`
|
|
74
|
+
4. Create a Key for Sign in with Apple, download the `.p8` file
|
|
75
|
+
5. You'll need: **Service ID** (client_id), **Team ID**, **Key ID**,
|
|
76
|
+
and the **private key**
|
|
77
|
+
|
|
78
|
+
### Microsoft
|
|
79
|
+
|
|
80
|
+
1. Go to Azure Portal > Azure Active Directory > App Registrations > New Registration
|
|
81
|
+
2. Set redirect URI: `https://<project-slug>.projects.oryapis.com/self-service/methods/oidc/callback/microsoft`
|
|
82
|
+
3. Create a client secret under Certificates & Secrets
|
|
83
|
+
4. Copy the **Application (client) ID** and **Client Secret**
|
|
84
|
+
|
|
85
|
+
### Discord
|
|
86
|
+
|
|
87
|
+
1. Go to Discord Developer Portal > Applications > New Application
|
|
88
|
+
2. Under OAuth2, add redirect: `https://<project-slug>.projects.oryapis.com/self-service/methods/oidc/callback/discord`
|
|
89
|
+
3. Copy the **Client ID** and **Client Secret**
|
|
90
|
+
|
|
91
|
+
## Step 3: Configure providers in Ory
|
|
92
|
+
|
|
93
|
+
Use the Ory CLI to add each provider. The configuration uses JSON patches.
|
|
94
|
+
|
|
95
|
+
### Google OIDC
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
ory patch identity-config <project-id> \
|
|
99
|
+
--add '/selfservice/methods/oidc/config/providers/-={
|
|
100
|
+
"id": "google",
|
|
101
|
+
"provider": "google",
|
|
102
|
+
"client_id": "<GOOGLE_CLIENT_ID>",
|
|
103
|
+
"client_secret": "<GOOGLE_CLIENT_SECRET>",
|
|
104
|
+
"mapper_url": "base64://MAPPER_CONTENT",
|
|
105
|
+
"scope": ["openid", "email", "profile"]
|
|
106
|
+
}' \
|
|
107
|
+
--replace '/selfservice/methods/oidc/enabled=true'
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### GitHub OIDC
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
ory patch identity-config <project-id> \
|
|
114
|
+
--add '/selfservice/methods/oidc/config/providers/-={
|
|
115
|
+
"id": "github",
|
|
116
|
+
"provider": "github",
|
|
117
|
+
"client_id": "<GITHUB_CLIENT_ID>",
|
|
118
|
+
"client_secret": "<GITHUB_CLIENT_SECRET>",
|
|
119
|
+
"mapper_url": "base64://MAPPER_CONTENT",
|
|
120
|
+
"scope": ["user:email"]
|
|
121
|
+
}' \
|
|
122
|
+
--replace '/selfservice/methods/oidc/enabled=true'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Apple OIDC
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
ory patch identity-config <project-id> \
|
|
129
|
+
--add '/selfservice/methods/oidc/config/providers/-={
|
|
130
|
+
"id": "apple",
|
|
131
|
+
"provider": "apple",
|
|
132
|
+
"client_id": "<APPLE_SERVICE_ID>",
|
|
133
|
+
"apple_team_id": "<TEAM_ID>",
|
|
134
|
+
"apple_private_key_id": "<KEY_ID>",
|
|
135
|
+
"apple_private_key": "<PRIVATE_KEY_CONTENTS>",
|
|
136
|
+
"mapper_url": "base64://MAPPER_CONTENT",
|
|
137
|
+
"scope": ["openid", "email", "name"]
|
|
138
|
+
}' \
|
|
139
|
+
--replace '/selfservice/methods/oidc/enabled=true'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Microsoft OIDC
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
ory patch identity-config <project-id> \
|
|
146
|
+
--add '/selfservice/methods/oidc/config/providers/-={
|
|
147
|
+
"id": "microsoft",
|
|
148
|
+
"provider": "microsoft",
|
|
149
|
+
"client_id": "<MICROSOFT_CLIENT_ID>",
|
|
150
|
+
"client_secret": "<MICROSOFT_CLIENT_SECRET>",
|
|
151
|
+
"microsoft_tenant": "common",
|
|
152
|
+
"mapper_url": "base64://MAPPER_CONTENT",
|
|
153
|
+
"scope": ["openid", "email", "profile"]
|
|
154
|
+
}' \
|
|
155
|
+
--replace '/selfservice/methods/oidc/enabled=true'
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Discord OIDC
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
ory patch identity-config <project-id> \
|
|
162
|
+
--add '/selfservice/methods/oidc/config/providers/-={
|
|
163
|
+
"id": "discord",
|
|
164
|
+
"provider": "discord",
|
|
165
|
+
"client_id": "<DISCORD_CLIENT_ID>",
|
|
166
|
+
"client_secret": "<DISCORD_CLIENT_SECRET>",
|
|
167
|
+
"mapper_url": "base64://MAPPER_CONTENT",
|
|
168
|
+
"scope": ["identify", "email"]
|
|
169
|
+
}' \
|
|
170
|
+
--replace '/selfservice/methods/oidc/enabled=true'
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Step 4: Create Jsonnet data mappers
|
|
174
|
+
|
|
175
|
+
Each provider needs a Jsonnet mapper that maps the provider's claims
|
|
176
|
+
to Ory identity traits. Create a mapper file for each provider.
|
|
177
|
+
|
|
178
|
+
### Standard email-based mapper
|
|
179
|
+
|
|
180
|
+
This works for Google, GitHub, Microsoft, Discord, and most providers:
|
|
181
|
+
|
|
182
|
+
```jsonnet
|
|
183
|
+
local claims = {
|
|
184
|
+
email_verified: false,
|
|
185
|
+
} + std.extVar('claims');
|
|
186
|
+
|
|
187
|
+
{
|
|
188
|
+
identity: {
|
|
189
|
+
traits: {
|
|
190
|
+
[if 'email' in claims && claims.email_verified then 'email' else null]: claims.email,
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Apple mapper
|
|
197
|
+
|
|
198
|
+
Apple sends name data only on first login:
|
|
199
|
+
|
|
200
|
+
```jsonnet
|
|
201
|
+
local claims = {
|
|
202
|
+
email_verified: false,
|
|
203
|
+
} + std.extVar('claims');
|
|
204
|
+
|
|
205
|
+
{
|
|
206
|
+
identity: {
|
|
207
|
+
traits: {
|
|
208
|
+
[if 'email' in claims && claims.email_verified then 'email' else null]: claims.email,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
To use these mappers, either:
|
|
215
|
+
|
|
216
|
+
1. Base64-encode the Jsonnet and use `mapper_url: "base64://..."`
|
|
217
|
+
in the provider config
|
|
218
|
+
2. Host the mapper at a URL and use `mapper_url: "https://..."`
|
|
219
|
+
in the provider config
|
|
220
|
+
|
|
221
|
+
To base64-encode a mapper file:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
base64 -i mapper.jsonnet
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Then set `mapper_url` to `"base64://<encoded-content>"` in the provider configuration.
|
|
228
|
+
|
|
229
|
+
## Step 5: Verify social login in the UI (Ory Elements)
|
|
230
|
+
|
|
231
|
+
If the app uses Ory Elements (the recommended setup), **no frontend
|
|
232
|
+
changes are needed**. The `<Login>` and `<Registration>` components
|
|
233
|
+
read the available methods from the flow object and render the
|
|
234
|
+
appropriate social buttons automatically — including provider icons
|
|
235
|
+
and labels.
|
|
236
|
+
|
|
237
|
+
Reload the login page and confirm the new buttons appear. If they do
|
|
238
|
+
not:
|
|
239
|
+
|
|
240
|
+
- Confirm OIDC is enabled and the provider was added (Step 7
|
|
241
|
+
troubleshooting commands).
|
|
242
|
+
- Confirm the page is rendering `<Login flow={flow} />` from
|
|
243
|
+
`@ory/elements-react/theme`, not a custom UI.
|
|
244
|
+
- Confirm the flow was re-initialized after the provider was added
|
|
245
|
+
(a stale flow id from before the change will not include the new
|
|
246
|
+
buttons).
|
|
247
|
+
|
|
248
|
+
### Fallback: custom UI rendering of OIDC nodes
|
|
249
|
+
|
|
250
|
+
Use this only if the user has explicitly chosen not to use Ory
|
|
251
|
+
Elements. In that case, render the OIDC nodes from the flow:
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
flow.ui.nodes
|
|
255
|
+
.filter(node => node.group === "oidc")
|
|
256
|
+
.map(node => {
|
|
257
|
+
// Each node represents a social login button.
|
|
258
|
+
// node.attributes contains the provider id and label.
|
|
259
|
+
// Render a button that submits the form with the provider value.
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Before going down this path, recommend switching to Ory Elements via
|
|
264
|
+
{{REF_LOGIN_FLOW}} so future provider additions don't require
|
|
265
|
+
frontend work.
|
|
266
|
+
|
|
267
|
+
## Step 6: Test each provider
|
|
268
|
+
|
|
269
|
+
For each configured provider:
|
|
270
|
+
|
|
271
|
+
1. Go to the login page
|
|
272
|
+
2. Click the social login button for the provider — Ory Elements
|
|
273
|
+
should already be rendering it
|
|
274
|
+
3. Complete the OAuth flow with the provider
|
|
275
|
+
4. Verify you're redirected back and a session is created
|
|
276
|
+
5. Check the identity was created: `ory list identities --project <project-id>`
|
|
277
|
+
6. Test the registration flow — a new user signing in via social should auto-register
|
|
278
|
+
7. Test account linking — an existing user should be able to link a social provider
|
|
279
|
+
|
|
280
|
+
## Step 7: Handle account linking
|
|
281
|
+
|
|
282
|
+
When a user logs in with a social provider whose email matches an
|
|
283
|
+
existing account, Ory can either:
|
|
284
|
+
|
|
285
|
+
- **Link automatically** — merge the social identity with the existing account
|
|
286
|
+
- **Require manual linking** — prompt the user to log in with their
|
|
287
|
+
existing method first
|
|
288
|
+
|
|
289
|
+
Configure the linking strategy:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
ory patch identity-config <project-id> \
|
|
293
|
+
--replace '/selfservice/methods/oidc/config/enabled=true'
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
When manual linking is required, Ory Elements renders the linking
|
|
297
|
+
prompt automatically — no UI work needed.
|
|
298
|
+
|
|
299
|
+
## Troubleshooting
|
|
300
|
+
|
|
301
|
+
- **Redirect URI mismatch**: Ensure the redirect URI in the provider's
|
|
302
|
+
console exactly matches what Ory expects: `https://<slug>.projects.oryapis.com/self-service/methods/oidc/callback/<provider-id>`
|
|
303
|
+
- **No social buttons showing with Ory Elements**: Verify OIDC is
|
|
304
|
+
enabled and at least one provider is configured:
|
|
305
|
+
`ory get identity-config <project-id> --format json | jq '.selfservice.methods.oidc'`
|
|
306
|
+
Then reload the page so a fresh flow is initialized.
|
|
307
|
+
- **No social buttons showing with a custom UI**: The custom UI must
|
|
308
|
+
iterate `flow.ui.nodes` filtered by `group === "oidc"`. The simplest
|
|
309
|
+
fix is to migrate to Ory Elements.
|
|
310
|
+
- **Mapper errors**: Test the Jsonnet mapper locally with sample claims data
|
|
311
|
+
- **Local development**: Use `ory tunnel` to proxy requests — social
|
|
312
|
+
login requires proper cookie handling that localhost alone can't provide
|