diff --git a/docs/getting-started/ory-network-oauth2.mdx b/docs/getting-started/ory-network-oauth2.mdx
index acda791f2..56d42a6ac 100644
--- a/docs/getting-started/ory-network-oauth2.mdx
+++ b/docs/getting-started/ory-network-oauth2.mdx
@@ -1,10 +1,10 @@
---
id: ory-network-oauth2
title: Perform OAuth2 Authorization Code Grant and Client Credentials Grant
-sidebar_label: Try it
+sidebar_label: OAuth2
---
-# Try common OAuth2 Grants
+# OAuth2 with Ory
[Ory OAuth2 & OpenID Connect](https://www.ory.sh/federated-identity-management/) (based on
[Ory Hydra](https://github.com/ory/hydra)) is available in the Ory Network out of the box. This means that you can use OIDC,
diff --git a/docs/oauth2-oidc/_static/oauth2-create-client.png b/docs/oauth2-oidc/_static/oauth2-create-client.png
new file mode 100644
index 000000000..45e4414b3
Binary files /dev/null and b/docs/oauth2-oidc/_static/oauth2-create-client.png differ
diff --git a/docs/oauth2-oidc/_static/oauth2overview.png b/docs/oauth2-oidc/_static/oauth2overview.png
new file mode 100644
index 000000000..2a2a38efb
Binary files /dev/null and b/docs/oauth2-oidc/_static/oauth2overview.png differ
diff --git a/docs/oauth2-oidc/_static/ory-oauth2-outcome.png b/docs/oauth2-oidc/_static/ory-oauth2-outcome.png
new file mode 100644
index 000000000..da9da9e6a
Binary files /dev/null and b/docs/oauth2-oidc/_static/ory-oauth2-outcome.png differ
diff --git a/docs/oauth2-oidc/_static/ory-oauth2-sso-provider.png b/docs/oauth2-oidc/_static/ory-oauth2-sso-provider.png
new file mode 100644
index 000000000..a64160ca5
Binary files /dev/null and b/docs/oauth2-oidc/_static/ory-oauth2-sso-provider.png differ
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/callback.go b/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/callback.go
new file mode 100644
index 000000000..18ee89ee3
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/callback.go
@@ -0,0 +1,71 @@
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "golang.org/x/oauth2"
+)
+
+func handleCallback(w http.ResponseWriter, r *http.Request) {
+ // Get session cookie
+ cookie, err := r.Cookie("session_id")
+ if err != nil {
+ http.Error(w, "No session found", http.StatusBadRequest)
+ return
+ }
+
+ // Get session from store
+ session, ok := sessions[cookie.Value]
+ if !ok {
+ http.Error(w, "Invalid session", http.StatusBadRequest)
+ return
+ }
+
+ // Get authorization code and state from query parameters
+ code := r.URL.Query().Get("code")
+ state := r.URL.Query().Get("state")
+ if code == "" || state == "" || state != session.State {
+ http.Error(w, "Invalid request", http.StatusBadRequest)
+ return
+ }
+
+ // Exchange authorization code for token
+ token, err := oauthConfig.Exchange(
+ context.Background(),
+ code,
+ oauth2.VerifierOption(session.CodeVerifier),
+ )
+ if err != nil {
+ http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // Update session with token
+ session.Token = token
+ sessions[cookie.Value] = session
+
+ // Fetch user info
+ client := oauthConfig.Client(context.Background(), token)
+ userInfoURL := fmt.Sprintf("https://%s.projects.oryapis.com/userinfo", projectSlug)
+ resp, err := client.Get(userInfoURL)
+ if err != nil {
+ http.Error(w, "Failed to fetch user info: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
+
+ // Parse user info response
+ var userInfo map[string]interface{}
+ if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil {
+ http.Error(w, "Failed to parse user info: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ // Update session with user info
+ session.UserInfo = userInfo
+ sessions[cookie.Value] = session
+
+ // Redirect to home page
+ http.Redirect(w, r, "/", http.StatusSeeOther)
+}
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/login.go b/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/login.go
new file mode 100644
index 000000000..0dab7090c
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/go/handlers/login.go
@@ -0,0 +1,61 @@
+
+import (
+ "crypto/rand"
+ "encoding/base64"
+ "net/http"
+ "time"
+
+ "golang.org/x/oauth2"
+)
+
+func handleLogin(w http.ResponseWriter, r *http.Request) {
+ // Generate random state parameter
+ state, err := generateRandomString(32)
+ if err != nil {
+ http.Error(w, "Failed to generate state parameter", http.StatusInternalServerError)
+ return
+ }
+
+ // Generate code verifier for PKCE
+ codeVerifier := oauth2.GenerateVerifier()
+
+ // Create a new session
+ sessionID, err := generateRandomString(32)
+ if err != nil {
+ http.Error(w, "Failed to generate session ID", http.StatusInternalServerError)
+ return
+ }
+
+ // Store session
+ sessions[sessionID] = Session{
+ State: state,
+ CodeVerifier: codeVerifier,
+ }
+
+ // Set session cookie
+ http.SetCookie(w, &http.Cookie{
+ Name: "session_id",
+ Value: sessionID,
+ Path: "/",
+ HttpOnly: true,
+ Secure: r.TLS != nil,
+ MaxAge: int(24 * time.Hour.Seconds()),
+ })
+
+ // Generate authorization URL with PKCE challenge
+ authURL := oauthConfig.AuthCodeURL(
+ state,
+ oauth2.S256ChallengeOption(codeVerifier),
+ )
+
+ // Redirect to authorization server
+ http.Redirect(w, r, authURL, http.StatusSeeOther)
+}
+
+func generateRandomString(length int) (string, error) {
+ b := make([]byte, length)
+ if _, err := rand.Read(b); err != nil {
+ return "", err
+ }
+ return base64.RawURLEncoding.EncodeToString(b), nil
+}
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/go/setup.go b/docs/oauth2-oidc/get-started/_common/code-examples/go/setup.go
new file mode 100644
index 000000000..9369cd510
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/go/setup.go
@@ -0,0 +1,44 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "golang.org/x/oauth2"
+)
+
+// Configuration
+var (
+ // Replace these with your own values
+ clientID = os.Getenv("OAUTH_CLIENT_ID")
+ clientSecret = os.Getenv("OAUTH_CLIENT_SECRET")
+ projectSlug = os.Getenv("ORY_PROJECT_SLUG")
+ redirectURL = os.Getenv("OAUTH_REDIRECT_URI")
+ port = "3000"
+
+ // Ory OAuth2 endpoints
+ oryEndpoint = oauth2.Endpoint{
+ AuthURL: fmt.Sprintf("https://%s.projects.oryapis.com/oauth2/auth", projectSlug),
+ TokenURL: fmt.Sprintf("https://%s.projects.oryapis.com/oauth2/token", projectSlug),
+ }
+
+ // OAuth2 config
+ oauthConfig = &oauth2.Config{
+ ClientID: clientID,
+ ClientSecret: clientSecret,
+ RedirectURL: redirectURL,
+ Scopes: []string{"openid", "offline_access", "email"},
+ Endpoint: oryEndpoint,
+ }
+
+ // In-memory session store (replace with a proper session store in production)
+ sessions = make(map[string]Session)
+)
+
+// Session represents user session data
+type Session struct {
+ State string
+ CodeVerifier string
+ Token *oauth2.Token
+ UserInfo map[string]interface{}
+}
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/callback.js b/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/callback.js
new file mode 100644
index 000000000..e89bde9b4
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/callback.js
@@ -0,0 +1,37 @@
+import session from "express-session"
+app.use(
+ session({
+ secret: process.env.SESSION_SECRET,
+ resave: false,
+ saveUninitialized: true,
+ }),
+)
+app.get("/callback", async (req, res) => {
+ if (!config) {
+ throw new Error("Config not found")
+ }
+
+ try {
+ // Get the current URL
+ const currentUrl = new URL(req.url, `http://${req.headers.host}`)
+
+ // Exchange code for tokens with PKCE verification
+ const tokens = await client.authorizationCodeGrant(config, currentUrl, {
+ pkceCodeVerifier: req.session.codeVerifier,
+ expectedState: req.session.state,
+ })
+
+ // Store tokens in session
+ req.session.tokens = tokens
+
+ // Redirect to home page
+ res.redirect("/")
+ } catch (error) {
+ console.error("Callback error:", error)
+ res.status(500).send(`Authentication failed: ${error.message}`)
+ }
+})
+
+app.listen(3000, () => {
+ console.log("Server is running on port 3000")
+})
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/home.js b/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/home.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/login.js b/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/login.js
new file mode 100644
index 000000000..223a0c7f1
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/js/routes/login.js
@@ -0,0 +1,40 @@
+app.get("/login", async (req, res) => {
+ if (!config) {
+ throw new Error("Config not found")
+ }
+
+ try {
+ // Generate PKCE code verifier
+ const code_verifier = client.randomPKCECodeVerifier()
+
+ // Calculate code challenge from verifier
+ const code_challenge =
+ await client.calculatePKCECodeChallenge(code_verifier)
+
+ // Generate state for CSRF protection
+ const state = client.randomState()
+
+ // Store in session for later verification
+ req.session.codeVerifier = code_verifier
+ req.session.state = state
+
+ // Build authorization parameters
+ const parameters = {
+ redirect_uri: process.env.OAUTH_REDIRECT_URI,
+ scope: "openid email offline_access",
+ code_challenge,
+ code_challenge_method: "S256",
+ state,
+ }
+
+ // Build authorization URL
+ const redirectTo = client.buildAuthorizationUrl(config, parameters)
+
+ // Redirect user to authorization server
+ console.log("Redirecting to:", redirectTo.href)
+ res.redirect(redirectTo.href)
+ } catch (error) {
+ console.error("Login error:", error)
+ res.status(500).send(`Login error: ${error.message}`)
+ }
+})
diff --git a/docs/oauth2-oidc/get-started/_common/code-examples/js/setup.js b/docs/oauth2-oidc/get-started/_common/code-examples/js/setup.js
new file mode 100644
index 000000000..0753cfbe8
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/_common/code-examples/js/setup.js
@@ -0,0 +1,28 @@
+import * as client from "openid-client"
+import express from "express"
+const app = express()
+
+// Configure environment variables
+const ORY_PROJECT_SLUG = process.env.ORY_PROJECT_SLUG
+const OAUTH_CLIENT_ID = process.env.OAUTH_CLIENT_ID
+const OAUTH_CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET
+
+let config
+;(async () => {
+ try {
+ // Create server URL (Ory's issuer URL)
+ const server = new URL(`https://${ORY_PROJECT_SLUG}.projects.oryapis.com`)
+
+ // Use discovery to fetch the server metadata and create a configuration
+ config = await client.discovery(
+ server,
+ OAUTH_CLIENT_ID,
+ OAUTH_CLIENT_SECRET,
+ client.ClientSecretBasic(OAUTH_CLIENT_SECRET),
+ )
+
+ console.log("Discovery successful")
+ } catch (error) {
+ console.error("Discovery error:", error)
+ }
+})()
diff --git a/docs/oauth2-oidc/get-started/client-setup.mdx b/docs/oauth2-oidc/get-started/client-setup.mdx
new file mode 100644
index 000000000..32b15314d
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/client-setup.mdx
@@ -0,0 +1,116 @@
+---
+id: client-setup
+title: Create an OAuth2 client in Ory
+sidebar_label: Create OAuth2 client
+---
+
+This guide shows you how to register an OAuth2 client in your Ory project.
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+
+1. Log in to your [Ory Console](https://console.ory.sh/)
+2. Select your workspace and project from the dropdown menus at the top
+3. Click on **OAuth2** in the main navigation menu
+4. In the OAuth2 page, select on the **OAuth2 Clients** tab
+5. Click the **Create OAuth2 Client** button
+6. In the client type selection screen, select **Custom**
+ - This option gives you full control over all OAuth2 client settings
+```
+
+```mdx-code-block
+import BrowserWindow from "@site/src/theme/BrowserWindow"
+
+
+
+
+```
+
+7. Fill in the client details:
+
+ - **Client Name**: A name for your client
+ - **Redirect URIs**: The URLs to which Ory will redirect users after authentication (e.g., http://localhost:3000/callback)
+ - **Scopes**: The permissions your client will request (recommended: openid, email, and profile)
+ - **Grant Types**: Select `authorization_code` and `refresh_token`
+ - **Response Types**: Select Authorization code (`code`)
+ - You can leave the rest of the settings as default for now.
+
+8. Copy the **Client ID** and **Client Secret** generated for your client. You will need these values to configure your
+ application.
+
+:::note
+
+Ensure you save before leaving the page. You can always come back to this page to view or edit your client settings.
+
+:::
+
+```mdx-code-block
+
+
+```
+
+1. Create an Ory Network project if you don't have one yet:
+
+```shell
+ory create project --name "Ory Docs OAuth2 Integration Example"
+```
+
+:::note
+
+Copy the **Project ID** and **Project Slug** from the output. You will need these values to configure your application.
+
+:::
+
+2. Create these environmental variables in your shell:
+
+```shell
+export ORY_PROJECT_ID=
+export ORY_PROJECT_SLUG=
+```
+
+3. Create the OAuth2 client:
+
+```shell
+ory create oauth2-client --project "$ORY_PROJECT_ID" \
+ --name "Ory Docs OAuth2 Integration Example Client" \
+ --grant-type authorization_code,refresh_token,client_credentials \
+ --response-type code \
+ --scope openid --scope offline_access --scope email \
+ --redirect-uri http://localhost:3000/callback
+```
+
+:::note
+
+The command will output your Client ID and Client Secret. Make sure to save these values securely as they'll be needed in your
+application configuration.
+
+:::
+
+```mdx-code-block
+
+
+```
+
+Finally, add your Ory credentials to your environment variables:
+
+```shell
+export ORY_PROJECT_SLUG=
+export OAUTH_CLIENT_ID=
+export OAUTH_CLIENT_SECRET=
+export OAUTH_REDIRECT_URI= # e.g. http://localhost:3000/callback
+export SESSION_SECRET=
+```
diff --git a/docs/oauth2-oidc/get-started/client/authentication.mdx b/docs/oauth2-oidc/get-started/client/authentication.mdx
new file mode 100644
index 000000000..381ebd2b0
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/client/authentication.mdx
@@ -0,0 +1,45 @@
+---
+id: authentication
+title: Request authorization code
+sidebar_label: Request authorization code
+---
+
+Before requesting an access token, you need to request an authorization code. This route generates PKCE code verifiers and state
+tokens for secure authentication, then redirects the user to Ory's authorization server.
+
+```mdx-code-block
+import jsLogin from "!!raw-loader!./../_common/code-examples/js/routes/login.js"
+import goLogin from "!!raw-loader!./../_common/code-examples/go/handlers/login.go"
+
+import Tabs from "@theme/Tabs"
+import TabItem from "@theme/TabItem"
+import CodeBlock from "@theme/CodeBlock"
+```
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+ {jsLogin}
+```
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+ {goLogin}
+```
+
+```mdx-code-block
+
+
+```
diff --git a/docs/oauth2-oidc/get-started/client/callback.mdx b/docs/oauth2-oidc/get-started/client/callback.mdx
new file mode 100644
index 000000000..759fc3a1f
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/client/callback.mdx
@@ -0,0 +1,44 @@
+---
+id: callback
+title: Implementing the callback routes
+sidebar_label: Handle Callback
+---
+
+After the OAuth2 server has verified the authorization code, it will redirect the user to the callback URL. This callback URL is
+configured in the OAuth2 client settings. The callback endpoint exchanges the temporary authorization code for permanent access
+tokens while verifying security measures (PKCE challenge and state parameter) to prevent attacks.
+
+```mdx-code-block
+import jsCallback from "!!raw-loader!./../_common/code-examples/js/routes/callback.js"
+import goCallback from "!!raw-loader!./../_common/code-examples/go/handlers/callback.go"
+
+import CodeBlock from "@theme/CodeBlock"
+```
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+ {jsCallback}
+```
+
+```mdx-code-block
+
+
+```
+
+```mdx-code-block
+ {goCallback}
+```
+
+```mdx-code-block
+
+
+```
diff --git a/docs/oauth2-oidc/get-started/client/setup.mdx b/docs/oauth2-oidc/get-started/client/setup.mdx
new file mode 100644
index 000000000..b48465f14
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/client/setup.mdx
@@ -0,0 +1,66 @@
+---
+id: setup
+title: Setting up OAuth2 client configuration
+sidebar_label: Configure Client
+---
+
+```mdx-code-block
+import jsSetup from '!!raw-loader!./../_common/code-examples/js/setup.js'
+import goSetup from '!!raw-loader!./../_common/code-examples/go/setup.go'
+import CodeBlock from "@theme/CodeBlock"
+```
+
+This guide shows how to initialize your application to work with Ory's OAuth2 server. You'll configure the basic setup required
+before implementing authentication flows.
+
+```mdx-code-block
+
+
+```
+
+**1. Install dependencies**
+
+```shell
+npm install express-session openid-client
+```
+
+**2. Initialize the OpenID Connect client**
+
+This code sets up the OpenID client by discovering the Ory OAuth2 server endpoints and configuring your client credentials.
+
+```mdx-code-block
+
+{jsSetup}
+
+```
+
+```mdx-code-block
+
+
+```
+
+**1. Install the Go OAuth2 package**
+
+```shell
+go get golang.org/x/oauth2
+```
+
+**2. Initialize the OpenID Connect client**
+
+This code sets up the client by discovering the Ory OAuth2 server endpoints and configuring your client credentials.
+
+```mdx-code-block
+
+{goSetup}
+
+```
+
+```mdx-code-block
+
+
+```
diff --git a/docs/oauth2-oidc/get-started/index.mdx b/docs/oauth2-oidc/get-started/index.mdx
new file mode 100644
index 000000000..aadc011e8
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/index.mdx
@@ -0,0 +1,19 @@
+---
+id: index
+title: OAuth2 & OpenID Connect
+sidebar_label: Get started
+---
+
+This guide covers the essential setup and implementation details for adding OAuth2 authorization flows to your application.
+
+## This guide is for you if:
+
+1. You want to implement OAuth2 authorization in your applications
+2. You want to quickly setup Ory's OAuth2 server
+
+## Prerequisites
+
+Before starting, ensure you have:
+
+1. An [Ory network account](https://console.ory.sh)
+2. [Ory CLI](/docs/guides/cli/installation) installed
diff --git a/docs/oauth2-oidc/get-started/server-setup.mdx b/docs/oauth2-oidc/get-started/server-setup.mdx
new file mode 100644
index 000000000..52c4106a4
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/server-setup.mdx
@@ -0,0 +1,24 @@
+---
+id: server-setup
+title: Access the OAuth2 server
+sidebar_label: Ory OAuth2
+---
+
+```mdx-code-block
+import BrowserWindow from "@site/src/theme/BrowserWindow"
+```
+
+Ory OAuth2 server is enabled by default for all Ory Network projects. You don't need to install or configure anything to start
+using it.
+
+To access the OAuth2 server features:
+
+1. Log in to your [Ory Console](https://console.ory.sh/)
+2. Select your workspace and project
+3. Navigate to the **OAuth2** tab in the navbar
+
+```mdx-code-block
+
+
+
+```
diff --git a/docs/oauth2-oidc/get-started/social-sign-in.mdx b/docs/oauth2-oidc/get-started/social-sign-in.mdx
new file mode 100644
index 000000000..6f82a201c
--- /dev/null
+++ b/docs/oauth2-oidc/get-started/social-sign-in.mdx
@@ -0,0 +1,206 @@
+---
+id: social-sign-in
+title: Configure social sign-in with Ory Identities
+sidebar_label: Social sign-in with Ory Identities
+---
+
+```mdx-code-block
+import BrowserWindow from "@site/src/theme/BrowserWindow"
+import Tabs from "@theme/Tabs"
+import TabItem from "@theme/TabItem"
+```
+
+This guide shows you how to configure Ory Identities as a social sign-in provider, allowing users to authenticate using another
+Ory project.
+
+## Understanding ory-to-ory authentication
+
+When setting up Ory OAuth2 as a social provider, you'll work with two separate Ory projects: a **provider project** that serves as
+your identity source (similar to how Google works in "Login with Google"), and a **consumer project** where you add the "Sign in
+with Ory OAuth2" option for your users.
+
+```mdx-code-block
+
+
+```
+
+**1. Set up Ory OAuth2 as a social provider**
+
+1. Go to your Ory project in the Ory Console
+2. Click on **Authentication** in the main navigation menu
+3. Select **Social Sign-In (OIDC)** from the sidebar
+4. Enable OpenID Connect by toggling the switch
+5. Click on **Add new OpenID Connect provider**
+6. Select **Ory OAuth2** from the provider list
+
+**2. Configure the Ory OAuth2 provider**
+
+Fill in the provider details using the information from your provider project (OAuth2 client setup):
+
+1. **Redirect URI**: This is pre-filled and automatically includes a unique callback ID
+2. **Label**: You can keep "Ory OAuth2" or customize it
+3. **Client ID**: Enter the OAuth2 client ID from your provider project
+4. **Client Secret**: Enter the OAuth2 client secret from your provider project
+5. **Issuer URL**: Enter the base URL of your provider project
+ ```
+ https://your-provider-project-slug.projects.oryapis.com
+ ```
+
+```mdx-code-block
+
+
+
+```
+
+**3. Configure redirect uri in provider project**
+
+To avoid redirect errors, you must add the consumer project's callback URL to your provider project:
+
+1. Go to your **provider project** in the Ory Console
+2. Navigate to OAuth2 → OAuth2 Clients
+3. Find and edit your OAuth2 client
+4. In the Redirect URIs section, add the exact callback URL shown in your consumer project's configuration:
+ ```
+ https://your-consumer-project-slug.projects.oryapis.com/self-service/methods/oidc/callback/ory-XXXX
+ ```
+5. Save the changes
+
+```mdx-code-block
+
+
+```
+
+**1. Create a provider project and oauth2 client (if needed)**
+
+If you haven't already created a provider project and OAuth2 client:
+
+```shell
+# Create a provider project
+ory create project --name "OAuth2 Provider - Example Corp"
+
+# Save the project ID for future use
+export PROVIDER_PROJECT_ID=your-provider-project-id # replace with your project ID
+
+# Create an OAuth2 client in the provider project
+ory create oauth2-client --project "$PROVIDER_PROJECT_ID" \
+ --name "OAuth2 Client for Social Sign-in" \
+ --grant-type authorization_code,refresh_token \
+ --response-type code \
+ --scope openid,offline_access,email \
+ --redirect-uri https://your-consumer-project-slug.projects.oryapis.com/self-service/methods/oidc/callback/your-provider-id
+```
+
+Save the Client ID and Client Secret from the output. You'll need these for configuring the consumer project.
+
+**2. Download the identity configuration from your consumer project**
+
+```shell
+# List all available workspaces
+ory list workspaces
+
+# List all projects in the workspace
+ory list projects --workspace
+
+# Get and save the identity configuration
+ory get identity-config --project --format yaml > identity-config.yaml
+```
+
+**3. Create a jsonnet mapping for identity claims**
+
+Create a file named `claims-mapper.jsonnet` with the following content:
+
+```jsonnet
+local claims = {
+ email_verified: false,
+} + std.extVar('claims');
+
+{
+ identity: {
+ traits: {
+ // Only map verified email addresses to prevent enumeration attacks
+ [if 'email' in claims && claims.email_verified then 'email' else null]: claims.email,
+ },
+ },
+}
+```
+
+**4. Convert the jsonnet mapping to base64**
+
+```shell
+# On Linux/macOS
+BASE64_MAPPER=$(cat claims-mapper.jsonnet | base64)
+
+# On Windows PowerShell
+$BASE64_MAPPER = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes((Get-Content -Raw claims-mapper.jsonnet)))
+```
+
+**5. Add the social sign-in provider to your configuration**
+
+Edit your `identity-config.yaml` file to include the OIDC provider configuration:
+
+```yaml
+selfservice:
+ methods:
+ oidc:
+ config:
+ providers:
+ - id: ory-oauth2 # A unique ID for this provider (don't change once set)
+ provider: generic
+ client_id: "your-client-id" # From step 1
+ client_secret: "your-client-secret" # From step 1
+ issuer_url: "https://your-provider-project-slug.projects.oryapis.com" # Provider project URL
+ mapper_url: "base64://YOUR_BASE64_ENCODED_JSONNET" # Replace with your base64 content
+ scope:
+ - email
+ - offline_access
+ - openid
+ enabled: true
+```
+
+Replace `YOUR_BASE64_ENCODED_JSONNET` with the base64 string from step 4.
+
+**6. Update your project configuration**
+
+```shell
+ory update identity-config --project --file identity-config.yaml
+```
+
+**7. Configure redirect uri in provider project**
+
+Make sure the OAuth2 client in your provider project includes the correct redirect URI for your consumer project:
+
+```shell
+# Get the OAuth2 client ID
+export CLIENT_ID=your-oauth2-client-id # Replace with your client ID
+
+# Get the current OAuth2 client configuration
+ory get oauth2-client $CLIENT_ID --project $PROVIDER_PROJECT_ID > oauth2-client.json
+
+# Update the client configuration to add the redirect URI
+# Edit oauth2-client.json to add the correct redirect URI to the "redirect_uris" array
+# Then update the client:
+ory update oauth2-client $CLIENT_ID --project $PROVIDER_PROJECT_ID --file oauth2-client.json
+```
+
+```mdx-code-block
+
+
+```
+
+## What users will see
+
+Once configured, users will see an "Ory OAuth2" option on your login screen:
+
+```mdx-code-block
+
+
+
+```
+
+When users click this button, they'll be redirected to authenticate with your provider Ory project. After successful
+authentication, they'll be redirected back to your application with a valid session.
diff --git a/src/sidebar.ts b/src/sidebar.ts
index d6babc6e2..d7aa4f3f5 100644
--- a/src/sidebar.ts
+++ b/src/sidebar.ts
@@ -110,7 +110,11 @@ const sdk: SidebarItemsConfig = [
type: "doc",
id: "hydra/sdk/overview",
},
- items: ["hydra/self-hosted/go", "hydra/self-hosted/js"],
+ items: [
+ "hydra/self-hosted/go",
+ "hydra/self-hosted/js",
+ "hydra/guides/using-oauth2",
+ ],
},
{
type: "category",
@@ -459,18 +463,22 @@ const identities: SidebarItemsConfig = [
const oauth2: SidebarItemsConfig = [
homeLink,
+ "getting-started/ory-network-oauth2",
{
type: "category",
- label: "Start",
+ label: "Get Started",
collapsed: false,
- collapsible: false,
link: {
type: "doc",
- id: "getting-started/ory-network-oauth2",
+ id: "oauth2-oidc/get-started/index",
},
items: [
- "getting-started/oauth2-openid/expressjs",
- "hydra/guides/using-oauth2",
+ "oauth2-oidc/get-started/server-setup",
+ "oauth2-oidc/get-started/client-setup",
+ "oauth2-oidc/get-started/client/setup",
+ "oauth2-oidc/get-started/client/authentication",
+ "oauth2-oidc/get-started/client/callback",
+ "oauth2-oidc/get-started/social-sign-in",
],
},
{