big-night-72627
04/07/2025, 5:28 PMbrief-egg-61061
04/07/2025, 5:28 PMbrief-egg-61061
04/07/2025, 5:29 PMjavascript import {     Configuration,     FrontendApi,     LoginFlow,     UiNode,     UiNodeInputAttributes,   } from "@ory/client"   import {     filterNodesByGroups,     isUiNodeInputAttributes,   } from "@ory/integrations/ui"   import { useEffect, useState } from "react"   import { useSearchParams } from "react-router-dom"      const frontend = new FrontendApi(     new Configuration({       basePath: "<http://localhost:4000>", // Use your local Ory Tunnel URL       baseOptions: {         withCredentials: true, // we need to include cookies       },     }),   )      export const Login = () => {     const [flow, setFlow] = useState<LoginFlow>()     const [searchParams] = useSearchParams()        useEffect(() => {       // check if the login flow is for two factor authentication       const aal2 = searchParams.get("aal2")       // we can redirect the user back to the page they were on before login       const returnTo = searchParams.get("return_to")          frontend         .createBrowserLoginFlow({           returnTo: returnTo || "/", // redirect to the root path after login           // if the user has a session, refresh it           refresh: true,           // if the aal2 query parameter is set, we get the two factor login flow UI nodes           aal: aal2 ? "aal2" : "aal1",         })         .then(({ data: flow }) => {           // set the flow data           setFlow(flow)         })         .catch((err) => {           // Couldn't create login flow           // handle the error         })     }, [])        const mapUINode = (node: UiNode, key: number) => {       // other node types are also supported       if (isUiNodeInputAttributes(node.attributes)) {         const attrs = node.attributes as UiNodeInputAttributes         const nodeType = attrs.type            switch (nodeType) {           case "button":           case "submit":             return (               <button                 type={attrs.type as "submit" | "reset" | "button" | undefined}                 name={attrs.name}                 value={attrs.value}               />             )           default:             return (               <input                 name={attrs.name}                 type={attrs.type}                 autoComplete={                   attrs.autocomplete || attrs.name === "identifier"                     ? "username"                     : ""                 }                 defaultValue={attrs.value}                 required={attrs.required}                 disabled={attrs.disabled}               />             )         }       }     }        return flow ? (       <form action={flow.ui.action} method={flow.ui.method}>         {filterNodesByGroups({           nodes: flow.ui.nodes,           // we will also map default fields here such as csrf_token           // modify this to include "code" for passwordless login           groups: ["default", "code"],         }).map((node, idx) => mapUINode(node, idx))}       </form>     ) : (       <div>Loading...</div>     )   }html <head>     <script src="/.well-known/ory/webauthn.js"></script>   </head>javascript // In your return statement return flow ? (     <form action={flow.ui.action} method={flow.ui.method}>       {filterNodesByGroups({         nodes: flow.ui.nodes,         // Include webauthn for passwordless authentication         groups: ["default", "webauthn"],       }).map((node, idx) => mapUINode(node, idx))}     </form>   ) : (     <div>Loading...</div>   )javascript import { Configuration, FrontendApi } from "@ory/client"      const frontend = new FrontendApi(     new Configuration({       basePath: `https://${process.env.ORY_PROJECT_SLUG}.<http://projects.oryapis.com|projects.oryapis.com>`,     }),   )      export async function createRegistration() {     return await frontend.createBrowserRegistrationFlow()   }javascript return flow ? (     <form action={flow.ui.action} method={flow.ui.method}>       {filterNodesByGroups({         nodes: flow.ui.nodes,         // Include code or webauthn for passwordless registration         groups: ["default", "code", "webauthn"],       }).map((node, idx) => mapUINode(node, idx))}     </form>   ) : (     <div>Loading...</div>   )yaml selfservice:   methods:     code:       enabled: true       passwordless_enabled: true     webauthn:       enabled: true       config:         passwordless: true         rp:           display_name: Your App Name           id: <http://your-domain.com|your-domain.com>           origins:             - <https://your-domain.com>   registration:     after:       code:         hooks:           - hook: session  # This automatically logs users in after registrationbig-night-72627
04/07/2025, 5:56 PMbrief-egg-61061
04/07/2025, 5:56 PMbrief-egg-61061
04/07/2025, 5:57 PMjavascript import {   Configuration,   FrontendApi,   RegistrationFlow,   UiNodeInputAttributes, } from "@ory/client" import {   filterNodesByGroups,   isUiNodeInputAttributes, } from "@ory/integrations/ui" import { useEffect, useState } from "react"  // Initialize the Ory Frontend API client const frontend = new FrontendApi(   new Configuration({     basePath: "<http://localhost:4000>", // Use your Ory Tunnel URL or Ory Network project URL     baseOptions: {       withCredentials: true, // Important for cookies     },   }), )  function PasswordlessRegistration() {   const [flow, setFlow] = useState(null)   const [error, setError] = useState(null)    // Initialize the registration flow   useEffect(() => {     // Create a new registration flow     frontend.createBrowserRegistrationFlow()       .then(({ data }) => {         setFlow(data)       })       .catch((err) => {         setError(err.response?.data || err)         console.error(err)       })   }, [])    // Handle form submission   const handleSubmit = (e) => {     e.preventDefault()     const form = e.currentTarget     const formData = new FormData(form)          // Submit the form data to Ory     frontend.updateRegistrationFlow({       flow: flow.id,       updateRegistrationFlowBody: Object.fromEntries(formData)     })       .then(({ data }) => {         // If successful, the user will be redirected         // If additional steps are needed (like entering the code), update the flow         setFlow(data)       })       .catch((err) => {         setError(err.response?.data || err)         console.error(err)       })   }    if (error) {     return <div>An error occurred: {JSON.stringify(error)}</div>   }    if (!flow) {     return <div>Loading...</div>   }    return (     <div>       <h2>Register with Passwordless Authentication</h2>       <form action={flow.ui.action} method={flow.ui.method} onSubmit={handleSubmit}>         {/* Render all nodes from the "code" group and default group */}         {filterNodesByGroups({           nodes: flow.ui.nodes,           groups: ["default", "code"],         }).map((node, idx) => {           if (isUiNodeInputAttributes(node.attributes)) {             const attrs = node.attributes                          // Display messages for this node if any             const messages = node.messages.length > 0 && (               <div className="messages">                 {node.messages.map((message, i) => (                   <div key={i} className={`message ${message.type}`}>                     {message.text}                   </div>                 ))}               </div>             )                          // Display label if available             const label = node.meta?.label?.text && (               <label htmlFor={attrs.name}>{node.meta.label.text}</label>             )              // Render different input types             switch (attrs.type) {               case "submit":                 return (                   <div key={idx}>                     <button                        type="submit"                        name={attrs.name}                        value={attrs.value || ""}                       disabled={attrs.disabled}                     >                       {node.meta?.label?.text || "Submit"}                     </button>                     {messages}                   </div>                 )               case "hidden":                 return (                   <input                     key={idx}                     type={attrs.type}                     name={attrs.name}                     value={attrs.value || ""}                   />                 )               default:                 return (                   <div key={idx}>                     {label}                     <input                       id={attrs.name}                       name={attrs.name}                       type={attrs.type}                       value={attrs.value || ""}                       required={attrs.required}                       disabled={attrs.disabled}                       placeholder={node.meta?.label?.text}                     />                     {messages}                   </div>                 )             }           }           return null         })}       </form>     </div>   ) }  export default PasswordlessRegistrationyaml selfservice:   methods:     code:       enabled: true       passwordless_enabled: true  # Enable passwordless login with code       config:         lifespan: 15m0s  # How long the code is valid   flows:     registration:       enabled: true       after:         code:           hooks:             - hook: session  # Automatically log users in after registrationafter.code.hookssessionbig-night-72627
04/09/2025, 6:01 PMbrief-egg-61061
04/09/2025, 6:01 PMbrief-egg-61061
04/09/2025, 6:02 PMjavascript import {   Configuration,   FrontendApi,   RegistrationFlow,   UiNodeInputAttributes,   UiNodeScriptAttributes, } from "@ory/client" import {   filterNodesByGroups,   isUiNodeInputAttributes, } from "@ory/integrations/ui" import { HTMLAttributeReferrerPolicy, useEffect, useState } from "react"  // Initialize the Ory Frontend API client const frontend = new FrontendApi(   new Configuration({     basePath: "<http://localhost:4000>", // Use your Ory Tunnel URL or Ory Network project URL     baseOptions: {       withCredentials: true,     },   }), )  function PasskeyRegistration() {   const [flow, setFlow] = useState(null)   const [error, setError] = useState(null)    // Initialize the registration flow   useEffect(() => {     frontend.createBrowserRegistrationFlow()       .then(({ data }) => {         setFlow(data)       })       .catch((err) => {         setError(err.response?.data || err)         console.error(err)       })   }, [])    // Add the WebAuthn script to the DOM   useEffect(() => {     if (!flow) return      // Add the WebAuthn script     const scriptNodes = filterNodesByGroups({       nodes: flow.ui.nodes,       groups: "passkey",       attributes: "text/javascript",       withoutDefaultGroup: true,       withoutDefaultAttributes: true,     }).map((node) => {       const attr = node.attributes       const script = document.createElement("script")       script.src = attr.src       script.type = attr.type       script.async = attr.async       script.referrerPolicy = attr.referrerpolicy       script.crossOrigin = attr.crossorigin       script.integrity = attr.integrity       document.body.appendChild(script)       return script     })      // Check for onloadTrigger     const onloadNode = flow.ui.nodes.find(       (node) =>          isUiNodeInputAttributes(node.attributes) &&          node.attributes.onloadTrigger === "oryPasskeyRegistration"     )          if (onloadNode) {       // Execute the passkey registration trigger when available       window.setTimeout(() => {         if (window.__oryPasskeyRegistration) {           window.__oryPasskeyRegistration()         }       }, 500)     }      // Cleanup     return () => {       scriptNodes.forEach((script) => {         document.body.removeChild(script)       })     }   }, [flow])    if (error) {     return <div>An error occurred: {JSON.stringify(error)}</div>   }    if (!flow) {     return <div>Loading...</div>   }    return (     <div>       <h2>Register with Passkey</h2>       <form action={flow.ui.action} method={flow.ui.method}>         {/* Render all nodes from the "passkey" group and default group */}         {filterNodesByGroups({           nodes: flow.ui.nodes,           groups: ["default", "passkey"],           attributes: ["hidden", "submit", "button"],         }).map((node, idx) => {           if (isUiNodeInputAttributes(node.attributes)) {             const attrs = node.attributes                          // Display messages for this node if any             const messages = node.messages.length > 0 && (               <div className="messages">                 {node.messages.map((message, i) => (                   <div key={i} className={`message ${message.type}`}>                     {message.text}                   </div>                 ))}               </div>             )                          // Display label if available             const label = node.meta?.label?.text && (               <label htmlFor={attrs.name}>{node.meta.label.text}</label>             )              // Render different input types             switch (attrs.type) {               case "button":               case "submit":                 return (                   <div key={idx}>                     <button                        type={attrs.type}                       name={attrs.name}                        value={attrs.value || ""}                       disabled={attrs.disabled}                       onClick={attrs.onclick ? () => eval(attrs.onclick) : undefined}                     >                       {node.meta?.label?.text || "Submit"}                     </button>                     {messages}                   </div>                 )               default:                 return (                   <div key={idx}>                     {label}                     <input                       id={attrs.name}                       name={attrs.name}                       type={attrs.type}                       value={attrs.value || ""}                       required={attrs.required}                       disabled={attrs.disabled}                     />                     {messages}                   </div>                 )             }           }           return null         })}       </form>     </div>   ) }  export default PasskeyRegistrationjavascript import {   Configuration,   FrontendApi,   LoginFlow,   UiNodeInputAttributes, } from "@ory/client" import {   filterNodesByGroups,   isUiNodeInputAttributes, } from "@ory/integrations/ui" import { useEffect, useState } from "react"  // Initialize the Ory Frontend API client const frontend = new FrontendApi(   new Configuration({     basePath: "<http://localhost:4000>", // Use your Ory Tunnel URL or Ory Network project URL     baseOptions: {       withCredentials: true,     },   }), )  function PasskeyLogin() {   const [flow, setFlow] = useState(null)   const [error, setError] = useState(null)    // Initialize the login flow   useEffect(() => {     frontend.createBrowserLoginFlow({       refresh: true, // Refresh the session if it exists     })       .then(({ data }) => {         setFlow(data)       })       .catch((err) => {         setError(err.response?.data || err)         console.error(err)       })   }, [])    // Add the WebAuthn script to the DOM   useEffect(() => {     if (!flow) return      // Add the WebAuthn script     const scriptNodes = filterNodesByGroups({       nodes: flow.ui.nodes,       groups: "passkey",       attributes: "text/javascript",       withoutDefaultGroup: true,       withoutDefaultAttributes: true,     }).map((node) => {       const attr = node.attributes       const script = document.createElement("script")       script.src = attr.src       script.type = attr.type       script.async = attr.async       script.referrerPolicy = attr.referrerpolicy       script.crossOrigin = attr.crossorigin       script.integrity = attr.integrity       document.body.appendChild(script)       return script     })      // Check for onloadTrigger for auto-initialization     const onloadNode = flow.ui.nodes.find(       (node) =>          isUiNodeInputAttributes(node.attributes) &&          node.attributes.onloadTrigger === "oryPasskeyLoginAutocompleteInit"     )          if (onloadNode) {       // Execute the passkey login autocomplete trigger when available       window.setTimeout(() => {         if (window.__oryPasskeyLoginAutocompleteInit) {           window.__oryPasskeyLoginAutocompleteInit()         }       }, 500)     }      // Cleanup     return () => {       scriptNodes.forEach((script) => {         document.body.removeChild(script)       })     }   }, [flow])    if (error) {     return <div>An error occurred: {JSON.stringify(error)}</div>   }    if (!flow) {     return <div>Loading...</div>   }    return (     <div>       <h2>Login with Passkey</h2>       <form action={flow.ui.action} method={flow.ui.method}>         {/* Render all nodes from the "passkey" group and default group */}         {filterNodesByGroups({           nodes: flow.ui.nodes,           groups: ["default", "passkey"],         }).map((node, idx) => {           if (isUiNodeInputAttributes(node.attributes)) {             const attrs = node.attributes                          // Display messages for this node if any             const messages = node.messages.length > 0 && (               <div className="messages">                 {node.messages.map((message, i) => (                   <div key={i} className={`message ${message.type}`}>                     {message.text}                   </div>                 ))}               </div>             )                          // Display label if available             const label = node.meta?.label?.text && (               <label htmlFor={attrs.name}>{node.meta.label.text}</label>             )              // Render different input types             switch (attrs.type) {               case "button":               case "submit":                 return (                   <div key={idx}>                     <button                        type={attrs.type}                       name={attrs.name}                        value={attrs.value || ""}                       disabled={attrs.disabled}                       onClick={attrs.onclick ? () => eval(attrs.onclick) : undefined}                     >                       {node.meta?.label?.text || "Sign in with passkey"}                     </button>                     {messages}                   </div>                 )               default:                 return (                   <div key={idx}>                     {label}                     <input                       id={attrs.name}                       name={attrs.name}                       type={attrs.type}                       value={attrs.value || ""}                       required={attrs.required}                       disabled={attrs.disabled}                     />                     {messages}                   </div>                 )             }           }           return null         })}       </form>     </div>   ) }  export default PasskeyLoginhtml <head>   <script src="/.well-known/ory/webauthn.js"></script> </head>yaml selfservice:   methods:     passkey:       enabled: true       config:         rp:           display_name: "Your Application Name"           id: "<http://your-domain.com|your-domain.com>"           origins:             - "<https://your-domain.com>"   flows:     registration:       after:         passkey:           hooks:             - hook: session  # Automatically log users in after registrationbig-night-72627
04/10/2025, 8:15 PMbrief-egg-61061
04/10/2025, 8:15 PMbrief-egg-61061
04/10/2025, 8:15 PMhtml    <head>        <script src="/.well-known/ory/webauthn.js"></script>      </head>__oryPasskeyRegistrationoryPasskeyRegistrationjavascript    // Add this to your component    useEffect(() => {      const checkWebAuthnLoaded = setInterval(() => {        if (window.__oryPasskeyRegistration) {          clearInterval(checkWebAuthnLoaded);          console.log("WebAuthn script loaded successfully");        }      }, 100);            // Clear interval after 10 seconds to prevent infinite checking      setTimeout(() => clearInterval(checkWebAuthnLoaded), 10000);            return () => clearInterval(checkWebAuthnLoaded);    }, []);onclickTriggeronloadTriggeronclickTriggerjavascript // Instead of directly calling window.oryPasskeyRegistration() // Use the UI node with the correct trigger const passkeyButton = flow.ui.nodes.find(   node =>      isUiNodeInputAttributes(node.attributes) &&      node.attributes.onclickTrigger === "oryPasskeyRegistration" );  // Then render this button in your UIbig-night-72627
04/10/2025, 8:20 PMThis browser does not support WebAuthn!brief-egg-61061
04/10/2025, 8:20 PMbrief-egg-61061
04/10/2025, 8:21 PM# For Passkeys    ory patch identity-config --project <project-id> --workspace <workspace-id> \      --replace "/selfservice/methods/passkey/config/rp/id=\"localhost\"" \      --replace "/selfservice/methods/passkey/config/rp/origins=[\"<http://localhost:3000\>"]" \      --format yamllocalhostlocalhostbig-night-72627
04/14/2025, 9:30 PMbrief-egg-61061
04/14/2025, 9:30 PMbrief-egg-61061
04/14/2025, 9:30 PMsessions.cookie.persistentcold-winter-87802
04/20/2025, 10:37 PMbrief-egg-61061
04/20/2025, 10:37 PMbrief-egg-61061
04/20/2025, 10:37 PMreturn_toreturn_tojavascript // When initializing the login flow frontend.createBrowserLoginFlow({   return_to: "<https://your-app.com/dashboard>" })yaml selfservice:   flows:     login:       after:         default_browser_return_url: <https://your-app.com/default-page>         passkey:           default_browser_return_url: <https://your-app.com/passkey-specific-page>javascript // After successful login .then((res) => {   router.push('/your-redirect-path') })yaml selfservice:   allowed_return_urls:     - <https://your-app.com/>return_tocold-winter-87802
04/20/2025, 10:38 PMbrief-egg-61061
04/20/2025, 10:38 PMbrief-egg-61061
04/20/2025, 10:39 PMjavascript import { Configuration, FrontendApi } from "@ory/client"  const frontend = new FrontendApi(   new Configuration({     basePath: "<http://localhost:4000>", // Use your Ory Tunnel URL or project URL     baseOptions: {       withCredentials: true,     },   }), )  // Create a logout flow and get the logout URL async function logout() {   try {     // Create a "logout flow" in Ory     const { data: flow } = await frontend.createBrowserLogoutFlow()          // Option 1: Redirect to the logout URL     window.location.href = flow.logout_url          // Option 2: Use the token to perform the logout via AJAX     // await frontend.updateLogoutFlow({     //   token: flow.logout_token,     // })     // Then redirect or update UI as needed   } catch (error) {     console.error("Logout failed:", error)   } }javascript import { Configuration, FrontendApi } from "@ory/client" import { useState } from "react"  const frontend = new FrontendApi(   new Configuration({     basePath: "<http://localhost:4000>",     baseOptions: {       withCredentials: true,     },   }), )  export function LogoutButton() {   const [logoutUrl, setLogoutUrl] = useState(null)      // Get the logout URL when component mounts   useEffect(() => {     frontend.createBrowserLogoutFlow()       .then(({ data }) => {         setLogoutUrl(data.logout_url)       })       .catch(err => console.error(err))   }, [])      return (     <a href={logoutUrl}>Logout</a>   ) }javascript import { Configuration, FrontendApi } from "@ory/client"  const frontend = new FrontendApi(   new Configuration({     basePath: `https://${process.env.ORY_PROJECT_SLUG}.<http://projects.oryapis.com|projects.oryapis.com>`,   }), )  export async function logout(token) {   return await frontend.performNativeLogout({     performNativeLogoutBody: {       session_token: token,     },   }) }javascript // Redirect to the OIDC logout endpoint window.location.href = `https://${projectSlug}.<http://projects.oryapis.com/oauth2/sessions/logout|projects.oryapis.com/oauth2/sessions/logout>`withCredentials: truereturn_tocold-winter-87802
04/20/2025, 11:50 PMbrief-egg-61061
04/20/2025, 11:50 PMbrief-egg-61061
04/20/2025, 11:51 PMyaml selfservice:   flows:     login:       before:         hooks:           - hook: web_hook             config:               url: <https://your-api.com/validate-domain>               method: POST               auth:                 type: api_key                 config:                   name: Authorization                   value: Bearer your-secret-token                   in: headerjavascript // Example webhook implementation <http://app.post|app.post>('/validate-domain', (req, res) => {   const { email } = req.body.traits || {};      if (!email) {     return res.status(400).json({       error: {         message: "Email is required"       }     });   }      // Extract domain from email   const domain = email.split('@')[1];      // List of allowed domains   const allowedDomains = ['<http://company.com|company.com>', '<http://approved-partner.com|approved-partner.com>'];      if (!allowedDomains.includes(domain)) {     return res.status(403).json({       error: {         message: "Your email domain is not authorized to access this application"       }     });   }      // Allow the login to proceed   return res.status(200).json({}); });yaml selfservice:   flows:     login:       before:         hooks:           - hook: web_hook             config:               url: <https://your-api.com/validate-domain>               method: POST               can_interrupt: true               auth:                 type: api_key                 config:                   name: Authorization                   value: Bearer your-secret-token                   in: headercan_interrupt: truebash ory patch identity-config {project_id} \   --add '/selfservice/flows/login/before/hooks=[{"hook": "web_hook", "config": {"url": "<https://your-api.com/validate-domain>", "method": "POST", "can_interrupt": true}}]'cold-winter-87802
04/20/2025, 11:54 PMbrief-egg-61061
04/20/2025, 11:54 PMbrief-egg-61061
04/20/2025, 11:54 PMyaml selfservice:   flows:     login:       after:         passkey:           hooks:             - hook: web_hook               config:                 url: <https://your-api.com/update-traits>                 method: POST                 response:                   parse: trueresponse.parse: truejavascript // Example webhook implementation <http://app.post|app.post>('/update-traits', (req, res) => {   // Get the current identity from the request   const { identity } = req.body;      // Get the current traits   const currentTraits = identity.traits || {};      // Append new data to traits   const updatedTraits = {     ...currentTraits,     last_login_timestamp: new Date().toISOString(),     login_count: (currentTraits.login_count || 0) + 1,     // Add any other data you want to append   };      // Return the updated identity   res.status(200).json({     identity: {       traits: updatedTraits     }   }); });javascript    res.status(200).json({      identity: {        traits: currentTraits, // Keep existing traits        metadata_public: {          // Public metadata visible to the user          last_login: new Date().toISOString()        },        metadata_admin: {          // Admin-only metadata          login_statistics: {            count: (identity.metadata_admin?.login_statistics?.count || 0) + 1          }        }      }    });big-night-72627
05/03/2025, 3:40 PMbrief-egg-61061
05/03/2025, 3:40 PMbrief-egg-61061
05/03/2025, 3:41 PMhydra create client \   --endpoint <http://your-hydra-admin-api/> \   --id my-api-client \   --secret my-api-secret \   --grant-types client_credentials \   --response-types token \   --scope read,writehydra create jwks --endpoint=<http://your-hydra-admin-api/> my-key-set --alg RS256PUT /admin/keys/{set}ory_at_cold-winter-87802
05/03/2025, 9:33 PMbrief-egg-61061
05/03/2025, 9:33 PMbrief-egg-61061
05/03/2025, 9:33 PM--response-typecodeory create oauth2-client --response-type codetokenory create oauth2-client --response-type tokenid_tokenory create oauth2-client --response-type id_tokenory create oauth2-client --response-type "code id_token"ory create oauth2-client \     --grant-type authorization_code --grant-type refresh_token \     --response-type code \     --scope openid --scope offline_access \     --token-endpoint-auth-method client_secret_post \     --redirect-uri <https://my-app.com/callback>codecold-winter-87802
05/03/2025, 9:36 PMbrief-egg-61061
05/03/2025, 9:36 PMbrief-egg-61061
05/03/2025, 9:36 PMory_at_JGhESDjKfHMQ8Wcy0cC3.hIQxGmX37ydn8WmKAnlD3Ucold-winter-87802
05/03/2025, 9:38 PMbrief-egg-61061
05/03/2025, 9:38 PMbrief-egg-61061
05/03/2025, 9:38 PMGET /sessions/token-exchangeinit_codereturn_to_code/sessions/whoamijavascript import { Configuration, FrontendApi } from "@ory/client"  const frontend = new FrontendApi(   new Configuration({     basePath: "<https://your-project.projects.oryapis.com>",     baseOptions: {       withCredentials: true, // Important for sending cookies     },   }), )  // Get session information and token const { data } = await frontend.toSession() const sessionToken = data.session_token/sessions/whoamiMP2YWEMeM8MxjkGKpH4dqOQ4Q4DlSPajAuthorizationcold-winter-87802
05/03/2025, 9:45 PMbrief-egg-61061
05/03/2025, 9:45 PMbrief-egg-61061
05/03/2025, 9:46 PMory_st_javascript // Example of using a session token in a native app const session = await frontend.toSession({   xSessionToken: "your-session-token" })https://$<http://PROJECT_SLUG.projects.oryapis.com/self-service/{flow-type}/api|PROJECT_SLUG.projects.oryapis.com/self-service/{flow-type}/api>ory_at_cold-winter-87802
05/03/2025, 10:32 PMbrief-egg-61061
05/03/2025, 10:32 PMbrief-egg-61061
05/03/2025, 10:33 PMjavascript // Example permission check const isAllowed = await ory   .permission   .checkPermission({     namespace: "files",      object: "document-123",      relation: "view",     subjectId: "user:john@example.com"   })   .then(({data}) => data.allowed)javascript // In your API middleware function checkScope(requiredScope) {   return (req, res, next) => {     // Validate the token and check if it has the required scope     const token = req.headers.authorization?.split(' ')[1]          // Introspect the token to verify it and get its scopes     ory.introspectOAuth2Token({       token: token     }).then(({data}) => {       if (data.active && data.scope.includes(requiredScope)) {         next()       } else {         res.status(403).json({ error: "Insufficient permissions" })       }     })   } }  // Usage app.get('/api/resource', checkScope('read:resource'), (req, res) => {   // Handle the request })javascript    // Before any sensitive operation    const allowed = await ory.permission.checkPermission({...})    if (!allowed) {      return res.status(403).send("Permission denied")    }cold-winter-87802
05/03/2025, 11:04 PMbrief-egg-61061
05/03/2025, 11:04 PMbrief-egg-61061
05/03/2025, 11:04 PMyaml mutators:   id_token:     enabled: true     config:       issuer_url: <http://127.0.0.1:4455/>       jwks_url: file:///etc/config/oathkeeper/id_token.jwks.json       claims: |         {           "session": {{ .Extra | toJson }}         }Cookie: ory_kratos_session=... → Authorization: bearer eyJhbGci...Cookie: ory_kratos_session=... → X-User-ID: user-123big-night-72627
06/04/2025, 5:39 AMbrief-egg-61061
06/04/2025, 5:39 AMbrief-egg-61061
06/04/2025, 5:39 AMjson [   {     "id": "public",     "version": "v0.36.0-beta.4",     "upstream": {       "url": "$RESOURCE_SERVER",       "preserve_host": true     },     "match": {       "url": "<https?://[^/]+/creditors/(\\.docs(/.*)?|.*[./-]public)$>",       "methods": [         "GET", "HEAD"       ]     },     "authenticators": [       {         "handler": "noop"       }     ],     "authorizer": {       "handler": "allow"     },     "mutators": [       {         "handler": "noop"       }     ]   } ]Back-off restarting failed container web-server in pod XXXXXbig-night-72627
06/04/2025, 5:40 AMbrief-egg-61061
06/04/2025, 5:40 AMbrief-egg-61061
06/04/2025, 5:40 AMbig-night-72627
06/04/2025, 5:43 AM❯ k describe ingress internal -n auth-c0
Name:             internal
Labels:           <http://app.kubernetes.io/component=api|app.kubernetes.io/component=api>
                  <http://app.kubernetes.io/instance=auth-c0-vwg-stg-1-ew1|app.kubernetes.io/instance=auth-c0-vwg-stg-1-ew1>
                  <http://app.kubernetes.io/managed-by=Helm|app.kubernetes.io/managed-by=Helm>
                  <http://app.kubernetes.io/name=auth|app.kubernetes.io/name=auth>
                  <http://app.kubernetes.io/version=main-bcd7ffac|app.kubernetes.io/version=main-bcd7ffac>
                  cell=cell0
                  <http://helm.sh/chart=auth-1.1.0-bcd7ffac|helm.sh/chart=auth-1.1.0-bcd7ffac>
Namespace:        auth-c0
Address:          <http://ingress-internal-b9753b17e64918a9.elb.eu-west-1.amazonaws.com|ingress-internal-b9753b17e64918a9.elb.eu-west-1.amazonaws.com>
Ingress Class:    nginx-internal
Default backend:  <default>
Rules:
  Host                                       Path  Backends
  ----                                       ----  --------
  <http://stg-1.apps.vwg.rivianvw.io|stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://web.stg-1.apps.vwg.rivianvw.io|web.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://docs.stg-1.apps.vwg.rivianvw.io|docs.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://lineside.stg-1.apps.vwg.rivianvw.io|lineside.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://lineside-admin.stg-1.apps.vwg.rivianvw.io|lineside-admin.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://ride.stg-1.apps.vwg.rivianvw.io|ride.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://elemental.stg-1.apps.vwg.rivianvw.io|elemental.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://login.stg-1.apps.vwg.rivianvw.io|login.stg-1.apps.vwg.rivianvw.io>
                                             /   login-svc:80 (100.64.113.116:80)
  <http://kratos.stg-1.apps.vwg.rivianvw.io|kratos.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://frame.stg-1.apps.vwg.rivianvw.io|frame.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://middleware.stg-1.apps.vwg.rivianvw.io|middleware.stg-1.apps.vwg.rivianvw.io>
                                             /   oathkeeper-svc:4455 (100.64.113.122:4455)
  <http://keto.stg-1.apps.vwg.rivianvw.io|keto.stg-1.apps.vwg.rivianvw.io>
                                             /   keto-svc:4466 (100.64.115.0:4466)
  <http://hydra.stg-1.apps.vwg.rivianvw.io|hydra.stg-1.apps.vwg.rivianvw.io>
                                             /   hydra-svc:4444 (100.64.115.2:4444)
Annotations:                                 <http://argocd.argoproj.io/tracking-id|argocd.argoproj.io/tracking-id>: auth-c0-vwg-stg-1-ew1:<http://networking.k8s.io/Ingress:auth-c0/internal|networking.k8s.io/Ingress:auth-c0/internal>
Events:                                      <none>brief-egg-61061
06/04/2025, 5:43 AMbrief-egg-61061
06/04/2025, 5:43 AMkubectl describe ingressoathkeeper-svc:4455login-svcketo-svchydra-svcbig-night-72627
06/04/2025, 7:26 PMmethods:
    oidc:
      config:
        providers:
          #- id: "RVW Tech"
          - id: microsoftmicrosoftbrief-egg-61061
06/04/2025, 7:26 PMbrief-egg-61061
06/04/2025, 7:26 PMlabelidlabelyaml methods:   oidc:     config:       providers:         - id: microsoft           label: "Sign in with RVW Tech"           client_id: "..."           client_secret: "..."           provider: microsoftlabelidbig-night-72627
06/20/2025, 4:28 PMbrief-egg-61061
06/20/2025, 4:28 PMbrief-egg-61061
06/20/2025, 4:28 PMbig-night-72627
06/20/2025, 4:35 PMbrief-egg-61061
06/20/2025, 4:35 PMbrief-egg-61061
06/20/2025, 4:35 PM<http://localhost:4433>ory_kratos_sessionCookiego    // Go example using the Kratos Go SDK    session, _, err := apiClient.FrontendApi.ToSession(context.Background()).        Cookie("ory_kratos_session=<your-session-cookie-here>").Execute()sh    curl '<http://localhost:4433/sessions/whoami>' \      -H 'Cookie: ory_kratos_session=<your-session-cookie-here>'localhost127.0.0.1big-night-72627
06/24/2025, 10:22 PMbrief-egg-61061
06/24/2025, 10:22 PMbrief-egg-61061
06/24/2025, 10:22 PMremoteremoteremotejson {   "id": "some-id",   "upstream": {     "url": "<http://my-backend-service>"   },   "match": {     "url": "<http://my-app/api/<.*>>",     "methods": ["GET"]   },   "authenticators": [     {       "handler": "bearer_token"     }   ],   "authorizer": {     "handler": "remote",     "config": {       "remote": "<http://my-email-authorizer/authorize>",       "headers": {         "X-Subject": "{{ print .Subject }}",         "X-Email": "{{ print .Extra.email }}"       }     }   },   "mutators": [     {       "handler": "noop"     }   ] }remoteX-Email.Extra.emailbig-night-72627
06/24/2025, 10:23 PM"authorizers": [
    {
      "handler": "allow",
      "config": {
        "subject_matches": [
          "<mailto:user1@example.com|user1@example.com>",
          "<mailto:admin@example.com|admin@example.com>",
          "<mailto:another.user@goriv.co|another.user@goriv.co>"
        ]
      }
    }
  ],brief-egg-61061
06/24/2025, 10:23 PMbrief-egg-61061
06/24/2025, 10:24 PMallowsubject_matchesallowallowremote_jsonremoteremote_jsonketo_engine_acp_oryremotebig-night-72627
06/27/2025, 4:29 AMbrief-egg-61061
06/27/2025, 4:29 AMbrief-egg-61061
06/27/2025, 4:29 AMid_tokencookie_sessionid_tokenAuthorization: Bearer <jwt>json {   "id": "example-rule",   "upstream": {     "url": "<http://my-backend-service>"   },   "match": {     "url": "<http://my-app/api/.*>",     "methods": ["GET", "POST"]   },   "authenticators": [     {       "handler": "cookie_session",       "config": {         "check_session_url": "<http://kratos:4433/sessions/whoami>",         "only": ["ory_kratos_session"]       }     }   ],   "authorizer": {     "handler": "allow"   },   "mutators": [     {       "handler": "id_token",       "config": {         "issuer_url": "<http://oathkeeper:4455/>",         "jwks_url": "file:///etc/config/oathkeeper/id_token.jwks.json",         "claims": "{\"session\": {{ .Extra | toJson }}}"       }     }   ] }cookie_sessionid_tokenjwks_urlAuthorizationbig-night-72627
06/27/2025, 4:34 AMbrief-egg-61061
06/27/2025, 4:34 AMbrief-egg-61061
06/27/2025, 4:34 AMbrief-egg-61061
06/27/2025, 4:35 AMbrief-egg-61061
06/27/2025, 4:35 AMbig-night-72627
06/27/2025, 2:28 PMbrief-egg-61061
06/27/2025, 2:28 PMbrief-egg-61061
06/27/2025, 2:29 PMerror executing headers template "Bearer {{ print .IDToken }}" in rule "rvtech:frame:protected": template: rvtech:frame:protected:Authorization:1:16: executing "rvtech:frame:protected:Authorization" at <.IDToken>: can't evaluate field IDToken in type *authn.AuthenticationSession{{ print .IDToken }}.IDTokenAuthenticationSessionAuthenticationSession.Subject.Extra.Header.MatchContext.IDTokenid_tokenAuthorizationid_tokenAuthorization{{ print .Subject }}{{ print .Extra.some_field }}.IDTokenAuthenticationSessionid_tokenbig-night-72627
06/27/2025, 2:34 PMbrief-egg-61061
06/27/2025, 2:34 PMbrief-egg-61061
06/27/2025, 2:34 PMAuthorization{{ print .IDToken }}.IDTokenAuthenticationSessioncan't evaluate field IDToken in type *authn.AuthenticationSessionid_tokenid_tokenAuthorization: Bearer <jwt>Authorizationid_tokenAuthorizationX-User-Subjectjson {   "id": "rvtech:frame:protected",   "upstream": {     "url": "<http://frame-svc>"   },   "match": {     "url": "<http|https>://frame.stg-1.apps.vwg.rivianvw.io/<(.*)?$>",     "methods": ["GET", "POST", "OPTIONS"]   },   "authenticators": [     {       "handler": "cookie_session",       "config": {         "check_session_url": "<http://kratos-public:4433/sessions/whoami>",         "only": ["ory_kratos_session"]       }     }   ],   "authorizer": { "handler": "allow" },   "mutators": [     {       "handler": "id_token",       "config": {         "issuer_url": "<https://oathkeeper-proxy.stg-1.apps.vwg.rivianvw.io>",         "jwks_url": "file:///etc/secrets/mutator.id_token.jwks.json",         "claims": "{\"session\": {{ .Extra | toJson }}}"       }     },     {       "handler": "header",       "config": {         "headers": {           "X-User-Subject": "{{ print .Subject }}"         }       }     }   ] }id_tokenAuthorization: Bearer <jwt>.IDTokenX-User-Subjectbig-night-72627
06/27/2025, 5:23 PMaccess_rules:
  repositories:
  - file:///etc/rules/access-rules.json
authenticators:
  anonymous:
    config:
      subject: guest
    enabled: true
  cookie_session:
    config:
      check_session_url: <http://kratos-public:4433/sessions/whoami>
      extra_from: '@this'
      preserve_path: true
      preserve_query: true
      subject_from: identity.id
    enabled: true
  noop:
    enabled: true
authorizers:
  allow:
    enabled: true
  deny:
    enabled: true
  keto_engine_acp_ory:
    config:
      base_url: <https://keto-instance.com>
      required_action: ""
      required_resource: ""
    enabled: false
errors:
  fallback:
  - json
  handlers:
    json:
      config:
        verbose: false
      enabled: true
    redirect:
      config:
        to: <https://kratos.stg-1.apps.vwg.rivianvw.io/self-service/login/browser?return_to=%s>
        when:
        - error:
          - unauthorized
          - forbidden
          request:
            header:
              accept:
              - text/html
      enabled: true
log:
  format: json
  leak_sensitive_values: true
  level: debug
  redaction_text: ""
mutators:
  header:
    config:
      headers:
        X-User-Subject: '{{ print .Subject }}'
    enabled: true
  id_token:
    config:
      claims: |
        {
          "sub": "{{ .Subject }}",
          "email": "{{ .Extra.identity.traits.email }}",
          "name": {
            "first": "{{ .Extra.identity.traits.name.first }}",
            "last": "{{ .Extra.identity.traits.name.last }}"
          }
        }
      issuer_url: <https://oathkeeper-proxy.stg-1.apps.vwg.rivianvw.io>
      jwks_url: file:///etc/secrets/mutator.id_token.jwks.json
      ttl: 15m
    enabled: true
  noop:
    enabled: true
serve:
  api:
    port: 4456
  prometheus:
    port: 9000
  proxy:
    port: 4455
~ ${
    "id": "rvtech:frame:protected",
    "upstream": {
      "url": "<http://frame-svc>"
    },
    "match": {
      "url": "<http|https>://frame.stg-1.apps.vwg.rivianvw.io/<(.*)?$>",
      "methods": ["GET", "POST", "OPTIONS"]
    },
    "authenticators": [
        {
          "handler": "cookie_session",
          "config": {
            "check_session_url": "<http://kratos-public:4433/sessions/whoami>",
            "only": ["ory_kratos_session"]
          }
        }
    ],
    "authorizer": { "handler": "allow" },
    "mutators": [
        {
          "handler": "id_token",
          "config": {
            "issuer_url": "<https://oathkeeper-proxy.stg-1.apps.vwg.rivianvw.io>",
            "jwks_url": "file:///etc/secrets/mutator.id_token.jwks.json",
            "claims": "{\"session\": {{ .Extra | toJson }}}"
          }
        },
        {
          "handler": "header",
          "config": {
            "headers": {
              "X-User-Subject": "{{ print .Subject }}",
            }
          }
        }
      ]
  }brief-egg-61061
06/27/2025, 5:23 PMbrief-egg-61061
06/27/2025, 5:24 PMid_tokenAuthorization: Bearer <jwt>Authorizationid_tokenX-User-Subjectid_tokenAuthorizationAuthorization: Bearer <jwt>id_tokenAuthorizationid_tokenid_tokenAuthorizationid_tokenAuthorization: Bearer <jwt>big-night-72627
07/01/2025, 9:21 PMbrief-egg-61061
07/01/2025, 9:21 PMbrief-egg-61061
07/01/2025, 9:21 PMOPTIONSOPTIONS/api/oauth-clients<http://middleware.stg-1.apps.vwg.rivianvw.io|middleware.stg-1.apps.vwg.rivianvw.io>OPTIONSPOSTOPTIONSOPTIONS"methods": ["OPTIONS", "POST", ...]/api/oauth-clients<http://middleware.stg-1.apps.vwg.rivianvw.io|middleware.stg-1.apps.vwg.rivianvw.io>OPTIONSOPTIONSbig-night-72627
07/01/2025, 10:45 PMbrief-egg-61061
07/01/2025, 10:45 PMbrief-egg-61061
07/01/2025, 10:45 PMOPTIONSOPTIONSmethodsOPTIONSjson {   "id": "example-rule",   "upstream": {     "url": "<http://your-backend-service>"   },   "match": {     "url": "<http://your-host/api/your-endpoint>",     "methods": ["GET", "POST", "OPTIONS"]   },   "authenticators": [     { "handler": "noop" }   ],   "authorizer": { "handler": "allow" },   "mutators": [     { "handler": "noop" }   ] }"OPTIONS"methodsOPTIONScold-winter-87802
07/02/2025, 12:20 AMbrief-egg-61061
07/02/2025, 12:21 AMbrief-egg-61061
07/02/2025, 12:21 AMcookie_sessionOPTIONScookie_sessionanonymousnoopOPTIONSanonymousnoopcookie_sessionauthenticatorsOPTIONSjson "authenticators": [   {     "handler": "cookie_session",     "config": {       "check_session_url": "<http://kratos-public:4433/sessions/whoami>",       "only": ["ory_kratos_session"]     }   },   { "handler": "anonymous" } ]OPTIONSOPTIONSbig-night-72627
07/02/2025, 1:51 AMbrief-egg-61061
07/02/2025, 1:51 AMbrief-egg-61061
07/02/2025, 1:51 AMerror executing claims template in rule "rvtech:middleware:protected": template: ... at <.Extra.identity.traits.email>: nil pointer evaluating interface {}.traitsOPTIONSid_token.Extra.identity.traits.emailOPTIONS.Extra.identitynil.traitsnilid_tokenanonymousanonymousOPTIONSdefaultjson "claims": "{   \"sub\": \"{{ .Subject }}\",   \"email\": \"{{ .Extra.identity.traits.email | default \"\" }}\" }".Extra.identity.traits.emailid_tokenbig-night-72627
07/12/2025, 6:35 PMbrief-egg-61061
07/12/2025, 6:35 PMbrief-egg-61061
07/12/2025, 6:35 PM.Extra.identitykindIswithindexid_tokenprintid_tokennil.Extra.identitykindIsindexprintprintIndexprint.Extra.identitybig-night-72627
07/12/2025, 6:36 PMbrief-egg-61061
07/12/2025, 6:37 PMbrief-egg-61061
07/12/2025, 6:37 PMrvtech:gql-router:cors-preflightOPTIONS<https://gql-router.stg-1.apps.vwg.rivianvw.io>.*rvtech:gql-router:protectedGETPOSTcookie_sessionOPTIONSOPTIONSOPTIONS/graphqlAccess-Control-Allow-OriginOrigin<https://ota.stg-1.apps.vwg.rivianvw.io><https://local.rivianvw.io:4299>OriginAccess-Control-Allow-Credentials: trueAccess-Control-Allow-Origin*OriginanonymousOPTIONS/graphqlrvtech:gql-router:cors-preflightmatch.url/graphqlOrigin<https://ota.stg-1.apps.vwg.rivianvw.io>OPTIONSOriginbig-night-72627
07/14/2025, 6:09 PMbrief-egg-61061
07/14/2025, 6:09 PMbrief-egg-61061
07/14/2025, 6:09 PMprintprintIndexbig-night-72627
07/14/2025, 8:37 PMbrief-egg-61061
07/14/2025, 8:37 PMbrief-egg-61061
07/14/2025, 8:37 PM'Failed to revoke session: the request was rejected to protect you from Cross-Site-Request-Forgery'csrf_tokenCookieX-CSRF-TokenCookiebig-night-72627
07/15/2025, 1:39 AMbrief-egg-61061
07/15/2025, 1:39 AMbrief-egg-61061
07/15/2025, 1:40 AMclient_idclient_secretsh ory perform client-credentials \   --client-id=<your-client-id> \   --client-secret=<your-client-secret> \   --project <your-project-id>javascript const clientID = "the-client-id" const clientSecret = "the-secret-id" const basicAuth = btoa(encodeURIComponent(clientID) + ":" + encodeURIComponent(clientSecret))  fetch("<https://your-project.projects.oryapis.com/oauth2/token>", {   method: "POST",   headers: {     Authorization: "Basic " + basicAuth,     "Content-Type": "application/x-www-form-urlencoded",   },   body: "grant_type=client_credentials&scope=read", })   .then((response) => response.json())   .then((data) => console.log(data))javascript const qs = new URLSearchParams() qs.set("grant_type", "client_credentials") qs.set("client_id", clientID) qs.set("client_secret", clientSecret) qs.set("scope", "read")  fetch("<https://your-project.projects.oryapis.com/oauth2/token>", {   method: "POST",   headers: { "Content-Type": "application/x-www-form-urlencoded" },   body: qs.toString(), })   .then((response) => response.json())   .then((data) => console.log(data))client_idclient_secretbig-night-72627
07/15/2025, 1:52 AMbrief-egg-61061
07/15/2025, 1:52 AMbrief-egg-61061
07/15/2025, 1:53 AM{
  "error": "invalid_scope",
  "error_description": "The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope 'read'."
}readreadsh    ory update oauth2-client --project <project-id> <client-id> \      --scope readsh    ory create oauth2-client --project <project-id> \      --name "My Client" \      --grant-type client_credentials \      --scope readscopeinvalid_scopebig-night-72627
07/21/2025, 10:07 PMbrief-egg-61061
07/21/2025, 10:07 PMbrief-egg-61061
07/21/2025, 10:07 PMmetadata_publicdebug_claimsclaimsjsonnet local claims = std.extVar('claims'); {   identity: {     traits: {       // Minimal traits mapping - adjust as needed       [if 'email' in claims && claims.email_verified then 'email' else null]: claims.email,       // You might even use traits: {} temporarily if no traits are strictly required     },     metadata_public: {       // Store all received claims       debug_claims: claims     }   }, }big-night-72627
07/21/2025, 11:18 PMdebug_claimsbrief-egg-61061
07/21/2025, 11:18 PMbrief-egg-61061
07/21/2025, 11:18 PMdebug_claimsdebug_claimsmetadata_publicGET /identities/{id}metadata_public.debug_claimsdebug_claimsclaimsbig-night-72627
08/06/2025, 1:12 AMbrief-egg-61061
08/06/2025, 1:12 AMbrief-egg-61061
08/06/2025, 1:12 AMbodyctxjsonnet function(ctx) {   identity: ctx.identity }jsonnet function(ctx) {     identity: ctx.identity }json {   "identity": { ... } }ctxctx.identityctx.flowctxjsonnet function(ctx) {   identity: ctx.identity }big-night-72627
08/06/2025, 1:13 AMbrief-egg-61061
08/06/2025, 1:13 AMbrief-egg-61061
08/06/2025, 1:14 AMctxctxctxjson {   "ctx": {     "flow": { ... },     "identity": { ... },     "request_cookies": { ... },     "request_headers": { ... },     "request_method": "POST",     "request_url": "<https://playground.projects.oryapis.com/self-service/registration?flow=...>",     // ... other fields   } }jsonnet function(ctx) {   userId: ctx.identity.id,   email: ctx.identity.traits.email,   flowId: ctx.flow.id,   method: ctx.request_method }big-night-72627
08/06/2025, 1:26 AMidentitybrief-egg-61061
08/06/2025, 1:26 AMbrief-egg-61061
08/06/2025, 1:27 AMidentitybig-night-72627
08/06/2025, 1:28 AMbrief-egg-61061
08/06/2025, 1:28 AMbrief-egg-61061
08/06/2025, 1:28 AMidentitybig-night-72627
08/06/2025, 1:30 AMbrief-egg-61061
08/06/2025, 1:30 AMbrief-egg-61061
08/06/2025, 1:30 AMafter.login.oidc.hooksjson {   "session": {     "id_token": {       "roles": ["admin", "user"]     },     "access_token": {       "roles": ["admin", "user"]     }   } }rolesbig-night-72627
08/06/2025, 3:39 AMid_token:
          enabled: true
          config:
            issuer_url: <https://xxxx.io>
            jwks_url: file:///etc/secrets/mutator.id_token.jwks.json
            ttl: 15m
            claims: |
              {{ if .Extra.identity }}
                {
                  "sub": "{{ .Subject }}",
                  "company_code": "{{ .Extra.identity.traits.company_code }}",
                  "corporation": "{{ .Extra.identity.traits.corporation }}",
                  "cost_center": "{{ .Extra.identity.traits.cost_center }}",
                  "email": "{{ .Extra.identity.traits.email }}",
                  "employee_id": "{{ .Extra.identity.traits.employee_id }}",
                  "first_name": "{{ .Extra.identity.traits.first_name }}",
                  "last_name": "{{ .Extra.identity.traits.last_name }}",
                  "name": "{{ .Extra.identity.traits.name }}",
                  "roles": "{{ .Extra.identity.traits.roles }}",
                  "tenant_id": "{{ .Extra.identity.traits.tenant_id }}"
                }
              {{ else }}
                {} 
              {{ end }}brief-egg-61061
08/06/2025, 3:39 AMbrief-egg-61061
08/06/2025, 3:39 AMrolesid_token.Extra.identity.traits.rolesyaml "roles": "{{ .Extra.identity.traits.roles }}"rolesrolesyaml "roles": {{ .Extra.identity.traits.roles }}rolesyaml claims: |   {{ if .Extra.identity }}     {       "sub": "{{ .Subject }}",       "roles": {{ .Extra.identity.traits.roles }}       // ... other claims ...     }   {{ else }}     {}   {{ end }}id_tokenrolesnilbrief-egg-61061
08/06/2025, 3:40 AMbrief-egg-61061
08/06/2025, 3:40 AMrolesid_token{{ .Extra.identity.traits.roles }}id_tokenaccess_tokenid_token.Extrasession.id_token.roles{{ .Extra.id_token.roles }}rolesyaml "roles": {{ .Extra.identity.traits.roles }}yaml "roles": "{{ .Extra.identity.traits.roles }}".Extra.identity.traits.roles.Extra.identity.traits.rolesbig-night-72627
08/06/2025, 5:02 PM{"audience":"application","error":{"message":"error executing claims template in rule \"rvtech:frame:protected\": template: fce1eec24db43f22059c48d80de3a299:12:23: executing \"fce1eec24db43f22059c48d80de3a299\" at <.Extra.session.id_token.roles>: nil pointer evaluating interface {}.id_token","stack_trace":"\<http://ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate|ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate>\n\t/project/pipeline/mutate/mutator_id_token.go:152\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:310\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.(*Negroni).UseHandler.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/cmd/server.runProxy.func1.ContextualizedMiddleware.6\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/corsx/middleware.go:28\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/reqlog/middleware.go:143\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:105\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2220\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:3210\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:2092\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1700"},"granted":false,"http_host":"<http://frame.stg-1.apps.vwg.rivianvw.io|frame.stg-1.apps.vwg.rivianvw.io>","http_method":"GET","http_url":"<http://frame.stg-1.apps.vwg.rivianvw.io/>","http_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","level":"warning","msg":"The mutation handler encountered an error","mutation_handler":"id_token","reason_id":"mutation_handler_error","rule_id":"rvtech:frame:protected","service_name":"ORY Oathkeeper","service_version":"v0.40.9","subject":"c7255360-9817-44f2-9904-218ebb713e91","time":"2025-08-06T16:38:58.554952391Z"}
{"audience":"application","error":{"message":"error executing claims template in rule \"rvtech:frame:protected\": template: fce1eec24db43f22059c48d80de3a299:12:23: executing \"fce1eec24db43f22059c48d80de3a299\" at <.Extra.session.id_token.roles>: nil pointer evaluating interface {}.id_token","stack_trace":"\<http://ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate|ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate>\n\t/project/pipeline/mutate/mutator_id_token.go:152\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:310\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.(*Negroni).UseHandler.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/cmd/server.runProxy.func1.ContextualizedMiddleware.6\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/corsx/middleware.go:28\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/reqlog/middleware.go:143\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:105\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2220\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:3210\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:2092\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1700"},"granted":false,"http_host":"<http://frame.stg-1.apps.vwg.rivianvw.io|frame.stg-1.apps.vwg.rivianvw.io>","http_method":"GET","http_url":"<http://frame.stg-1.apps.vwg.rivianvw.io/>","http_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","level":"warning","msg":"Access request denied","service_name":"ORY Oathkeeper","service_version":"v0.40.9","time":"2025-08-06T16:38:58.555253937Z"}
{"audience":"application","error":{"debug":"","message":"An internal server error occurred, please contact the system administrator","reason":"","stack_trace":"\<http://ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate|ngithub.com/ory/oathkeeper/pipeline/mutate.(*MutatorIDToken).Mutate>\n\t/project/pipeline/mutate/mutator_id_token.go:152\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:310\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.(*Negroni).UseHandler.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/cmd/server.runProxy.func1.ContextualizedMiddleware.6\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/corsx/middleware.go:28\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/reqlog/middleware.go:143\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:105\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.677/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*middleware).serveHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:176\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.NewMiddleware.func1.1\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.57.0/handler.go:65\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2220\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:3210\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:2092\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1700","status":"Internal Server Error","status_code":500},"http_request":{"headers":{"accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en-US,en;q=0.9","cache-control":"no-cache","cookie":["__reveal_ut=6014eb61-1bfb-4449-4123-4f2d5665e511; ory_kratos_session=MTc1NDQ1ODM5MXw5QWhoak10VnVxUS02eEswRXRUTVpOWG9fZmhGQ2N5TUxmb2szSVFiYkNXMVdPVVFERWFJUXR6OFJfOGoxWW9mRnFTSV9XWVVIWE05NTV6b3Z3SmhlbC1FSTE4YVdGTlFUSUllT0RDQ2R6VWcya0c1UDNDc0VTRmt2MWFQX2E0Y1BlbGZIRmxZVFdtR1dHdlFfN1ZZN3Nid0xvb2JnUkxsaDVFUEM0MUF6RkJ0WFdjaldTeW83ZWlvUlZYV3d5eFpnM2laeERkU1p2VmY5SDNhU1lWbFE2SEw0V2xHcnZqVEl5a3Y5NkJyZ2hKZDM0ZzZickpWM2RwcmZVa2FrT29ZaTlMQnhBb2tGdGtRSU04Wm9TTEJ8zgQVBDYNdEMguiPLwdgklS3vVzJwOSV-7G_tab6Ufoo=; __reveal_ut=65a6b2aa-1dcd-4272-5ec1-fb5bdcb5a3f3"],"pragma":"no-cache","referer":"<https://login.stg-1.apps.vwg.rivianvw.io/>","sec-ch-ua":"\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"macOS\"","sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"same-site","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","x-forwarded-port":"80","x-forwarded-scheme":"http","x-real-ip":"10.223.103.86","x-request-id":"a7ba32649471c84adcecb08809f4da81","x-scheme":"http"},"host":"<http://frame.stg-1.apps.vwg.rivianvw.io|frame.stg-1.apps.vwg.rivianvw.io>","method":"GET","path":"/","query":null,"remote":"100.64.88.246:57926","scheme":"http"},"http_response":{"status_code":500},"level":"error","msg":"An error occurred while handling a request","service_name":"ORY Oathkeeper","service_version":"v0.40.9","time":"2025-08-06T16:38:58.555560093Z"}brief-egg-61061
08/06/2025, 5:02 PMbrief-egg-61061
08/06/2025, 5:02 PMerror executing claims template in rule "rvtech:frame:protected": template: ... at <.Extra.session.id_token.roles>: nil pointer evaluating interface {}.id_token.Extra.session.id_token.roles.Extra.session.id_tokennil.Extra.session.id_token.roles.rolesnilyaml claims: |   {{ if .Extra.session }}     {{ if .Extra.session.id_token }}       {         "roles": {{ .Extra.session.id_token.roles }}         // ... other claims ...       }     {{ else }}       {         "roles": []         // ... other claims ...       }     {{ end }}   {{ else }}     {       "roles": []       // ... other claims ...     }   {{ end }}.Extra.session.id_tokenrolesbig-night-72627
08/06/2025, 5:13 PMbrief-egg-61061
08/06/2025, 5:13 PMbrief-egg-61061
08/06/2025, 5:13 PM.Extra.Extra.Extra.Extra.Extrabig-night-72627
08/06/2025, 11:26 PMselfservice:
  # ...
  flows:
    # ...
    login:
      after:
        oidc:
          hooks:
          - config:
              body: <base64://ZnVuY3Rpb24oY3R4KSB7CiAgICBpZDogY3R4LmlkZW50aXR5LmlkLAogICAgc2N>oZW1hX2lkOiBjdHguaWRlbnRpdHkuc2NoZW1hX2lkLAogICAxxxCAgIH0KfQ==
              method: POST
              response:
                parse: true
              url: <https://xxx/api/identities/hydrate>
            hook: web_hook
          - # New `session` hook to use data from the webhook
            hook: session
            config:
              payload:
                id_token:
                  # Use data from the webhook response. `id_token` is from the response, not kratos context
                  roles: "{{ .webhook_response.body.session.id_token.roles }}"
                access_token:
                  # Use data from the webhook response. `access_token` is from the response, not kratos context
                  roles: "{{ .webhook_response.body.session.access_token.roles }}"
      ui_url: <https://login.stg-1.apps.vwg.rivianvw.io/login>brief-egg-61061
08/06/2025, 11:26 PMbrief-egg-61061
08/06/2025, 11:27 PMparse: truesessionsessionwebhook_response.bodysessionyaml    roles: "{{ .webhook_response.body.session.id_token.roles }}"web_hooksessionbodywebhook_response.bodysessionrolesid_tokenaccess_tokenbody.session.id_token.rolesbody.session.access_token.rolesbig-night-72627
08/07/2025, 3:53 PMlogin:
            ui_url: <https://login.stg-1.apps.vwg.rivianvw.io/login>
            after:
              oidc:
                hooks:
                  - hook: web_hook
                    config:
                      url: <https://user-management-middleware-production-tooling.stg-1.apps.vwg.rivianvw.io/api/identities/hydrate>
                      method: POST
                      body: "<base64://ZnVuY3Rpb24oY3R4KSB7CiAgICBpZDogY3R4LmlkZW50aXR5LmlkLAogICAgc2N>oZW1hX2lkOiBjdHguaWRlbnRpdHkuc2NoZW1hX2lkLAogICAgdHJhaXRzOiB7CiAgICAgIGVtYWlsOiBjdHguaWRlbnRpdHkudHJhaXRzLmVtYWlsLAogICAgICBlbXBsb3llZV9pZDogY3R4LmlkZW50aXR5LnRyYWl0cy5lbXBsb3llZV9pZCwKICAgICAgY29tcGFueV9jb2RlOiBjdHguaWRlbnRpdHkudHJhaXRzLmNvbXBhbnlfY29kZSwKICAgICAgY29ycG9yYXRpb246IGN0eC5pZGVudGl0eS50cmFpdHMuY29ycG9yYXRpb24sCiAgICAgIHRlbmFudF9pZDogY3R4LmlkZW50aXR5LnRyYWl0cy50ZW5hbnRfaWQKICAgIH0KfQ=="
                      response:
                        parse: true
                  - hook: session
                    config:
                      payload:
                        id_token:
                          roles: "{{ .webhook_response.body.session.id_token.roles }}"
                        access_token:
                          roles: "{{ .webhook_response.body.session.access_token.roles }}"{
  id: 'c725asdfgagda-218ebb713e91',
  schema_id: 'default',
  traits: {
    company_code: '0000',
    corporation: 'foo',
    email: 'swestergaard@foo.tech',
    employee_id: '164f3xxxxd-a86a-a765bc9exx2c',
    tenant_id: '9be208xxe-bdx54668e3'
  }
}{
  "session": {
    "id_token": {
      "roles": "ota-admin"
    },
    "access_token": {
      "roles": [
        "admin",
        "user"
      ]
    }
  }
}{
  "identity": {
    "id": "obfuscated-id-a",
    "schema_id": "default",
    "schema_url": "obfuscated-url",
    "state": "active",
    "state_changed_at": "obfuscated-date-time",
    "traits": {
      "email": "obfuscated-user@obfuscated.tech",
      "roles": "",
      "fullname": "Obfuscated User",
      "last_name": "User",
      "tenant_id": "obfuscated-tenant-id",
      "first_name": "Obfuscated",
      "corporation": "Obfuscated Corp",
      "cost_center": "XXXX",
      "employee_id": "obfuscated-employee-id",
      "company_code": "XXXX",
      "debug_claims": {
        "iss": "obfuscated-issuer-url",
        "sub": "obfuscated-subject-id",
        "name": "Obfuscated User",
        "email": "obfuscated-user@obfuscated.tech",
        "raw_claims": {
          "rh": "obfuscated-raw-claim-rh",
          "aud": "obfuscated-audience-id",
          "exp": 0,
          "iat": 0,
          "iss": "obfuscated-raw-claim-issuer-url",
          "nbf": 0,
          "oid": "obfuscated-oid",
          "sid": "obfuscated-session-id",
          "sub": "obfuscated-raw-claim-subject-id",
          "tid": "obfuscated-raw-claim-tenant-id",
          "uti": "obfuscated-unique-token-identifier",
          "ver": "X.X",
          "name": "Obfuscated User",
          "email": "obfuscated-user@obfuscated.tech",
          "preferred_username": "obfuscated-user@obfuscated.tech"
        },
        "preferred_username": "obfuscated-user@obfuscated.tech"
      }
    }
  }
}brief-egg-61061
08/07/2025, 3:53 PMbrief-egg-61061
08/07/2025, 3:53 PMsessionid_tokenaccess_tokenroles.webhook_response.bodyresponse.parse: truerolestraits.rolesjson    {      "session": {        "id_token": { "roles": "ota-admin" },        "access_token": { "roles": ["admin", "user"] }      }    }big-night-72627
08/07/2025, 3:58 PMuthenticators:
        cookie_session:
          enabled: true
          config:
            check_session_url: <http://some-whoami-url>
            preserve_path: true
            preserve_query: true
            subject_from: "identity.id"
            extra_from: "@this"
            only:
              - ory_kratos_session
        anonymous:
          enabled: true
          config:
            subject: guest
        noop:
          enabled: true
      authorizers:
        allow:
          enabled: true
        deny:
          enabled: true
        keto_engine_acp_ory:
          enabled: false
          config:
            base_url: <https://keto-instance.com>
            required_action: ""
            required_resource: ""
      mutators:
        noop:
          enabled: true
        id_token:
          enabled: true
          config:
            issuer_url: <https://some-issuer-url>
            jwks_url: file:///etc/secrets/mutator.id_token.jwks.json
            ttl: 15m
            claims: |
              {{ if .Extra.identity }}
                {
                  "sub": "{{ .Subject }}",
                  "company_code": "{{ .Extra.identity.traits.company_code }}",
                  "corporation": "{{ .Extra.identity.traits.corporation }}",
                  "cost_center": "{{ .Extra.identity.traits.cost_center }}",
                  "email": "{{ .Extra.identity.traits.email }}",
                  "employee_id": "{{ .Extra.identity.traits.employee_id }}",
                  "first_name": "{{ .Extra.identity.traits.first_name }}",
                  "last_name": "{{ .Extra.identity.traits.last_name }}",
                  "name": "{{ .Extra.identity.traits.name }}",
                  {{ if .Extra.session }}
                    {{ if .Extra.session.id_token }}
                      "roles": "roles.session_id,
                    {{ else }}
                      "roles": "roles.empty"
                    {{ end }}
                  {{ end }}
                  "tenant_id": "{{ .Extra.identity.traits.tenant_id }}"
                }
              {{ else }}
                {} 
              {{ end }}
        header:
          enabled: true
          config:
            headers:
              X-User-Subject: "{{ if .Extra.identity }}{{ .Subject }}{{ else }}anonymous{{ end }}"
      log:
        level: trace
        format: json
        leak_sensitive_values: true
        redaction_text: ""identitySchemas:
      "identity.default.schema.json": |
        {
           "$id": "<https://schemas.ory.sh/presets/kratos/identity.email.schema.json>",
           "$schema": "<http://json-schema.org/draft-07/schema#>",
           "title": "Person",
           "type": "object",
           "properties": {
             "traits": {
               "type": "object",
               "properties": {
                 "email": {
                   "type": "string",
                   "format": "email",
                   "title": "E-Mail",
                   "<http://ory.sh/kratos|ory.sh/kratos>": {
                     "credentials": {
                       "password": {
                         "identifier": true
                       },
                       "webauthn": {
                         "identifier": true
                       },
                       "passkey": {
                         "display_name": true
                       }
                     },
                     "recovery": {
                       "via": "email"
                     },
                     "verification": {
                       "via": "email"
                     }
                   }
                 },
                 "company_code": {
                   "type": "string",
                   "title": "Company Code"
                 },
                 "corporation": {
                   "type": "string",
                   "title": "Corporation"
                 },
                 "cost_center": {
                   "type": "string",
                   "title": "Cost Center"
                 },
                 "employee_id": {
                   "type": "string",
                   "title": "Employee ID"
                 },
                 "first_name": {
                   "title": "First Name",
                   "type": "string"
                 },
                 "last_name": {
                   "title": "Last Name",
                   "type": "string"
                 },
                 "roles": {
                   "type": "string",
                   "title": "Roles"
                 },
                 "tenant_id": {
                   "type": "string",
                   "title": "Tenant ID"
                 }
               },
               "required": [
                 "email"
               ],
               "additionalProperties": true
             }
           }
         }{
          "id": "xxx:frame:protected",
          "upstream": {
            "url": "<http://xxx-svc>"
          },
          "match": {
            "url": "<http|https>://xxx.io/<(.*)?$>",
            "methods": ["GET", "POST", "PUT", "DELETE", "PATCH"]
          },
          "authenticators": [{ "handler": "cookie_session" }],
          "authorizer": {
            "handler": "allow"
          },
          "mutators": [{ "handler": "id_token" }, { "handler": "header" }]
        },brief-egg-61061
08/07/2025, 3:58 PMbrief-egg-61061
08/07/2025, 3:59 PMid_tokenAuthorization: Bearer <jwt>headerid_tokenid_tokenAuthorizationAuthorization: Bearer <jwt>rolesid_tokenAuthorization: Bearer <jwt>big-night-72627
08/07/2025, 4:01 PM[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [IdentitiesController] Entire Payload: {"id":"[Obfuscated User ID]","schema_id":"default","traits":{"company_code":"XXXX","corporation":"[Obfuscated Corporation]","email":"[Obfuscated Email]","employee_id":"[Obfuscated Employee ID]","tenant_id":"[Obfuscated Tenant ID]"}}
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [IdentitiesController] User [Obfuscated Email] (ID: [Obfuscated User ID]) has roles: [Obfuscated Role]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [IdentitiesController] Returning session data for user [Obfuscated Email] (ID: [Obfuscated User ID]): {"session":{"id_token":{"roles":"[Obfuscated Role]"},"access_token":{"roles":["[Obfuscated Role 1]","[Obfuscated Role 2]"]}}}
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] Received request for /sessions/whoami
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] Incoming Headers:
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] host: [Obfuscated Host]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-request-id: [Obfuscated Request ID]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-real-ip: [Obfuscated IP]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-forwarded-for: [Obfuscated IP]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-forwarded-host: [Obfuscated Host]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-forwarded-port: XX
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-forwarded-proto: [Obfuscated Protocol]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-forwarded-scheme: [Obfuscated Scheme]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] x-scheme: [Obfuscated Scheme]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-ch-ua-platform: "[Obfuscated Platform]"
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] user-agent: [Obfuscated User Agent]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-ch-ua: [Obfuscated UA 1], "[Obfuscated UA 2]", "[Obfuscated UA 3]"
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-ch-ua-mobile: ?X
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] accept: /
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] origin: [Obfuscated Origin URL]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-fetch-site: [Obfuscated Fetch Site]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-fetch-mode: [Obfuscated Fetch Mode]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] sec-fetch-dest: [Obfuscated Fetch Destination]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] referer: [Obfuscated Referer URL]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] accept-encoding: [Obfuscated Encoding]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] accept-language: [Obfuscated Language]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] cookie: [Obfuscated Cookie 1]; [Obfuscated Cookie 2]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] if-none-match: [Obfuscated ETag]
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] Incoming Cookies (from @Cookies decorator):
[Nest] 62 - [Obfuscated Date], [Obfuscated Time] LOG [SessionsController] Object(2) {
ory_kratos_session: '[Obfuscated Session Cookie]',
__reveal_ut: '[Obfuscated UT Cookie]'brief-egg-61061
08/07/2025, 4:01 PMbrief-egg-61061
08/07/2025, 4:02 PMid_tokenid_tokenAuthorization: Bearer <jwt>id_tokenid_tokenid_tokenAuthorization/sessions/whoamiAuthorizationid_tokenAuthorizationid_tokenid_tokenAuthorization: Bearer <jwt>big-night-72627
08/09/2025, 7:52 PMclaims: |
              {{ if .Extra.identity }}
                {
                  "sub": "{{ .Subject }}",
                  "company_code": "{{ .Extra.identity.traits.company_code }}",
                  "corporation": "{{ .Extra.identity.traits.corporation }}",
                  "cost_center": "{{ .Extra.identity.traits.cost_center }}",
                  "email": "{{ .Extra.identity.traits.email }}",
                  "employee_id": "{{ .Extra.identity.traits.employee_id }}",
                  "first_name": "{{ .Extra.identity.traits.first_name }}",
                  "last_name": "{{ .Extra.identity.traits.last_name }}",
                  "fullname": "{{ .Extra.identity.traits.fullname }}",
                  {{ if .Extra.session }}
                    {{ if .Extra.session.id_token }}
                      "roles": "roles.session_id",
                    {{ else }}
                      "roles": "roles.empty",
                    {{ end }}
                  {{ else }}
                    "roles": "roles.anonymous",
                  {{ end }}
                  "tenant_id": "{{ .Extra.identity.traits.tenant_id }}"
                }
              {{ else }}
                {}
              {{ end }}{
  "session": {
    "id_token": {
      "roles": "admin"
    },
    "access_token": {
      "roles": [
        "admin",
        "user"
      ]
    }
  }
}brief-egg-61061
08/09/2025, 7:52 PMbrief-egg-61061
08/09/2025, 7:52 PMclaimsjinja {{ if .Extra.identity }}   {     ...     {{ if .Extra.session }}       {{ if .Extra.session.id_token }}         "roles": "roles.session_id",       {{ else }}         "roles": "roles.empty",       {{ end }}     {{ else }}       "roles": "roles.anonymous",     {{ end }}     ...   } {{ else }}   {} {{ end }}rolesroles"roles.session_id""roles.empty""roles.anonymous".Extra.session.id_token{"session":{"id_token":{"roles":"admin"}}}jinja "roles": {{ .Extra.session.id_token.roles }}jinja "roles": "{{ .Extra.session.id_token.roles }}".Extra.Extra.session.id_token.roles.Extra.session.id_token.rolesbrief-egg-61061
08/10/2025, 4:23 AMbrief-egg-61061
08/10/2025, 4:23 AMweb_hookbodymethodurlresponse.parse: truesessionweb_hookpayloadid_tokenaccess_token{{ .webhook_response.body.session.id_token.roles }}{{ .webhook_response.body.session.access_token.roles }}big-night-72627
08/10/2025, 4:26 AMbrief-egg-61061
08/10/2025, 4:26 AMbrief-egg-61061
08/10/2025, 4:27 AMjson {   "session": {     "id_token": {       "roles": ["admin", "user"]     },     "access_token": {       "roles": ["admin", "user"]     }   } }sessionrolesid_tokenaccess_token{{ .webhook_response.body.session.id_token.roles }}big-night-72627
08/10/2025, 4:54 AMbrief-egg-61061
08/10/2025, 4:54 AMbrief-egg-61061
08/10/2025, 4:55 AMsessionid_tokenaccess_tokenjson {   "session": {     "id_token": {       "roles": ["admin", "user"]     },     "access_token": {       "roles": ["admin", "user"]     }   } }sessionyaml id_token:   roles: "{{ .webhook_response.body.session.id_token.roles }}" access_token:   roles: "{{ .webhook_response.body.session.access_token.roles }}"big-night-72627
08/10/2025, 4:56 AMid_token:
  roles: "{{ .webhook_response.body.session.id_token.roles }}"
access_token:
  roles: "{{ .webhook_response.body.session.access_token.roles }}"brief-egg-61061
08/10/2025, 4:56 AMbrief-egg-61061
08/10/2025, 4:56 AMyaml id_token:   roles: "{{ .webhook_response.body.session.id_token.roles }}" access_token:   roles: "{{ .webhook_response.body.session.access_token.roles }}"response.parse: truesession.webhook_response.bodysession.id_token.rolesbig-night-72627
08/10/2025, 5:10 AMbrief-egg-61061
08/10/2025, 5:10 AMbrief-egg-61061
08/10/2025, 5:10 AMafter loginweb_hookweb_hookresponse.parse: truesessionsession.webhook_response.bodyyaml login:   after:     oidc:       hooks:         - hook: web_hook           config:             url: <https://your-webhook-endpoint>             method: POST             body: "<base64-encoded-jsonnet>"             response:               parse: true         - hook: session           config:             payload:               id_token:                 roles: "{{ .webhook_response.body.session.id_token.roles }}"               access_token:                 roles: "{{ .webhook_response.body.session.access_token.roles }}"json {   "session": {     "id_token": {       "roles": ["admin", "user"]     },     "access_token": {       "roles": ["admin", "user"]     }   } }sessionrolesbig-night-72627
08/19/2025, 5:32 PMbrief-egg-61061
08/19/2025, 5:33 PMbrief-egg-61061
08/19/2025, 5:33 PMbig-night-72627
08/19/2025, 5:33 PMbrief-egg-61061
08/19/2025, 5:33 PMbrief-egg-61061
08/19/2025, 5:34 PMbig-night-72627
08/30/2025, 10:31 PMchilly-king-10285
08/30/2025, 10:31 PMchilly-king-10285
08/30/2025, 10:31 PMjson {   "identity": {     "traits": {       "email": "<mailto:user@example.com|user@example.com>",       "roles": ["admin", "user"]     },     "metadata_public": {       "debug_claims": {         "foo": "bar"       }     }   } }traitsmetadata_publicjson   {     "session": {       "id_token": {         "roles": ["admin", "user"]       },       "access_token": {         "roles": ["admin", "user"]       }     }   }yaml   session:     payload:       id_token:         roles: "{{ .webhook_response.body.session.id_token.roles }}"       access_token:         roles: "{{ .webhook_response.body.session.access_token.roles }}"metadata_publicbig-night-72627
08/30/2025, 11:38 PMchilly-king-10285
08/30/2025, 11:38 PMchilly-king-10285
08/30/2025, 11:38 PMshow_verification_uiweb_hooksessionafter.oidc.hooksbig-night-72627
08/31/2025, 12:26 AMchilly-king-10285
08/31/2025, 12:26 AMchilly-king-10285
08/31/2025, 12:27 AMjson   {     "session": {       "id_token": {         "roles": ["admin", "user"]       },       "access_token": {         "roles": ["admin", "user"]       }     }   }session.webhook_response.bodysessionbig-night-72627
08/31/2025, 11:28 PMchilly-king-10285
08/31/2025, 11:28 PMchilly-king-10285
08/31/2025, 11:28 PMpublic_metadatametadata_publicid_tokentraits{{ .Extra.identity.traits.some_field }}id_tokenmetadata_publicid_token{{ .Extra.identity.metadata_public.some_field }}public_metadataid_tokenmetadata_publicbig-night-72627
10/09/2025, 11:00 PMchilly-king-10285
10/09/2025, 11:00 PMchilly-king-10285
10/09/2025, 11:01 PMory_kratos_sessionid_tokencookie_sessionjson "authenticators": [   {     "handler": "cookie_session",     "config": {       "check_session_url": "<http://kratos:4433/sessions/whoami>",       "only": ["ory_kratos_session"]     }   } ]id_tokenid_tokenjson "mutators": [   {     "handler": "id_token",     "config": {       "issuer_url": "<https://oathkeeper.yourdomain.com>",       "jwks_url": "file:///etc/config/oathkeeper/id_token.jwks.json",       "claims": "{\"session\": {{ .Extra | toJson }}}"     }   } ]jwks_urldocker run oryd/oathkeeper:<version> credentials generate --alg RS256 > jwks.jsonory_kratos_sessionAuthorizationcookie_sessionid_tokenbig-night-72627
10/09/2025, 11:02 PMchilly-king-10285
10/09/2025, 11:02 PMchilly-king-10285
10/09/2025, 11:02 PMory_kratos_session/sessions/whoamitokenize_astokenize_as/sessions/whoamitokenize_assh    curl -X GET \      -H "Cookie: ory_kratos_session=<your-session-cookie>" \      "https://<your-kratos-url>/sessions/whoami?tokenize_as=<your-jwt-template-name>"tokenizedsh curl -X GET \   -H "Cookie: ory_session...=..." \   "https://$<http://PROJECT_SLUG.projects.oryapis.com/sessions/whoami?tokenize_as=jwt_example_template1|PROJECT_SLUG.projects.oryapis.com/sessions/whoami?tokenize_as=jwt_example_template1>"  # Response: {   // ...   "tokenized": "{the-jwt}" }ory_kratos_session/sessions/whoamitokenize_astokenizedbig-night-72627
10/09/2025, 11:03 PMchilly-king-10285
10/09/2025, 11:03 PMchilly-king-10285
10/09/2025, 11:03 PMory_kratos_sessiontoSessiontokenize_asjavascript import { Configuration, FrontendApi } from "@ory/client"  const frontend = new FrontendApi(   new Configuration({     basePath: `https://${process.env.ORY_PROJECT_SLUG}.<http://projects.oryapis.com|projects.oryapis.com>`,   }), )  export async function toSessionWithJwt(sessionId: string) {   const session = await frontend.toSession({     tokenize_as: "jwt_example_template1", // your JWT template name   })   const jwt = session.tokenized   return jwt }jwt_example_template1tokenizedory_kratos_sessiontoSessiontokenize_asbig-night-72627
10/09/2025, 11:07 PMchilly-king-10285
10/09/2025, 11:07 PMchilly-king-10285
10/09/2025, 11:08 PMtokenize_assession.whoami.tokenizer.templatestokenize_as/sessions/whoamiyaml session:     whoami:       tokenizer:         templates:           jwt_example_template1:             jwks_url: base64://... # A JSON Web Key Set (required)             claims_mapper_url: base64://... # A JsonNet template for modifying the claims             ttl: 1m # 1 minute (defaults to 10 minutes)           another_jwt_template:             jwks_url: base64://... # A JSON Web Key Setjwt_example_template1another_jwt_templatetokenize_astokenize_asbig-night-72627
10/09/2025, 11:19 PMchilly-king-10285
10/09/2025, 11:19 PMchilly-king-10285
10/09/2025, 11:19 PMory_kratos_sessiontokenize_as/sessions/whoamitokenize_asbig-night-72627
10/10/2025, 2:24 AMchilly-king-10285
10/10/2025, 2:24 AMchilly-king-10285
10/10/2025, 2:25 AMclaims_mapper_urljsonnet local claims = std.extVar('claims'); local session = std.extVar('session');  {   claims: {     iss: claims.iss + "/additional-component",     schema_id: session.identity.schema_id,     external_id: session.identity.external_id,     session: session,   } }claims_mapper_urlbase64://<your-base64-encoded-jsonnet>big-night-72627
10/10/2025, 4:08 AMchilly-king-10285
10/10/2025, 4:08 AMchilly-king-10285
10/10/2025, 4:09 AMjwks_url> ory create jwk some-example-set \ >   --alg ES256 --project $PROJECT_ID --format json-pretty >big-night-72627
10/18/2025, 7:24 PMchilly-king-10285
10/18/2025, 7:24 PMchilly-king-10285
10/18/2025, 7:24 PM/admin/sessionsactive=truehttp GET /admin/sessions?page_size=250&page_token=1&active=truego func GetSessions(ctx context.Context, pageToken string, perPage int64) (sessions []client.Session, err error) {       sessions, _, err = ory.IdentityApi.ListSessions(ContextWithToken(ctx)).           PageToken(pageToken). // Optional - token id           PageSize(perPage).    // Optional - number of sessions per page           Active(true).         // Optional - used to filter result for active or inactive sessions; not setting this returns all sessions           Execute()          if err != nil {           return nil, err       }          return sessions, err   }page_tokenpage_size/admin/sessionsactive=truebig-night-72627
10/21/2025, 2:56 AMchilly-king-10285
10/21/2025, 2:56 AMchilly-king-10285
10/21/2025, 2:56 AMsh      ory patch oauth2-config --project <project-id> --workspace <workspace-id> \        --replace "/strategies/access_token=\"jwt\""javascript      import { Configuration, JsonPatch, OAuth2Api } from "@ory/client"       const ory = new OAuth2Api(        new Configuration({          basePath: `https://${process.env.ORY_PROJECT_SLUG}.<http://projects.oryapis.com|projects.oryapis.com>`,          accessToken: process.env.ORY_API_KEY,        }),      )       export async function patchOAuth2Client(id, patches) {        await ory.patchOAuth2Client({          id,          jsonPatch: [            ...patches,            {              op: "replace",              path: "access_token_strategy",              value: "jwt",            },          ],        })      }sh    curl -u '<client_id>:<client_secret>' \      -d 'grant_type=client_credentials' \      https://<hydra-url>/oauth2/tokenaccess_tokenaccess_token