<@U04UQ68083H> How do I specify the encoding algor...
# ory-copilot
b
@chilly-king-10285 How do I specify the encoding algorithm for all exchanges?
c
A message from kapa.ai
Ory provides different ways to specify encoding algorithms depending on the context. For Ory Identities (Kratos), you can specify the cipher algorithm for encryption and decryption of OIDC tokens. The available algorithms are
noop
,
XChaCha20 Poly1305
, and
AES
. You can specify the algorithm in the configuration file as follows: For `noop`:
Copy code
yaml ciphers:    algorithm: noop
For `XChaCha20 Poly1305`:
Copy code
yaml secrets:    cipher:    - 32-CHARACTER-LONG-STRING-SECRET   ciphers:    algorithm: xchacha20-poly1305
For `AES`:
Copy code
yaml secrets:    cipher:    - 32-CHARACTER-LONG-STRING-SECRET   ciphers:    algorithm: aes
Remember to set up secrets key rotation and ensure that secrets are 32-character-long strings ([source](https://www.ory.sh/docs/kratos/guides/select-cipher-algorithm)). For Ory OAuth2 and OpenID Connect, you can specify the subject identifier algorithms. The available algorithms are
public
and
pairwise
. You can specify the algorithm using the Ory CLI as follows: For `public`:
Copy code
bash ory patch oauth2-config {project.id} \    --replace "/oidc/subject_identifiers/supported_types=[\"public\"]"
For `pairwise`:
Copy code
bash ory patch oauth2-config {project.id} \    --replace "/oidc/subject_identifiers/supported_types=[\"pairwise\"]" \    --replace "/oidc/subject_identifiers/pairwise/salt=\"{16-character-long-salt}\""
Remember not to change the salt value once it's set in production ([source](https://www.ory.sh/docs/hydra/guides/openid)). For password hashing in Ory Identities, you can specify the algorithm as
bcrypt
or
argon2
in the configuration file as follows: For `bcrypt`:
Copy code
yaml hashers:    algorithm: bcrypt
For `argon2`:
Copy code
yaml hashers:    argon2:    parallelism: 1    memory: 128MB    iterations: 3    salt_length: 16    key_length: 32
Refer to the setup guide to determine the ideal parameters for
argon2
([source](https://www.ory.sh/docs/self-hosted/kratos/configuration/password)). Please note that these configurations are context-specific and may not apply to all exchanges in Ory.
b
@chilly-king-10285 So our JWT request using Postman/Client Credentails RS256, but our Swagger request is encoding with ES256. I want to use RS256 for all.
c
A message from kapa.ai
To use RS256 for all JWT signing, you need to ensure that the cryptographic keys used for signing are generated with the RS256 algorithm. For Ory Hydra, you can specify the algorithm when generating keys using the Ory CLI:
Copy code
bash ory create jwk some-example-set --alg RS256 --project {project.id} --format json-pretty
(Source: [Ory Docs](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-signing-keys)) For Ory Oathkeeper, you can generate a key for the RS256 algorithm using the following command:
Copy code
bash docker run oryd/oathkeeper:<version-you-want> credentials generate --alg RS256 > jwks.json
(Source: [Ory Docs](https://www.ory.sh/docs/oathkeeper/configure-deploy#cryptographic-keys)) Remember that if the key set contains more than one key, the first key in the list will be used for signing. So, ensure that the first key in your JWKS is an RS256 key. Also, note that for client authentication using JWTs, Ory supports RSA and ECDSA private/public key pairs and supports signing algorithms such as RS256. To use this feature for a specific OAuth 2.0 Client, set the
token_endpoint_auth_method
to
private_key_jwt
and register the public key of the RSA signing key either using the
jwks_uri
or
jwks
fields of the client. (Source: [Ory Docs](https://www.ory.sh/docs/hydra/guides/jwt#jwts-for-client-authentication)) Please ensure that your Postman/Client Credentials and Swagger requests are configured to use the RS256 keys for JWT signing.
b
@chilly-king-10285 Can I set that in my project configuration on Ory Network?
c
A message from kapa.ai
Yes, you can set the JWT signing algorithm in your project configuration on the Ory Network. For example, when creating an OAuth2 client, you can specify the
token_endpoint_auth_signing_alg
to be "RS256". Here is an example of how to do this:
Copy code
javascript import { Configuration, 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 createOAuth2Client() {    await ory.createOAuth2Client({    oAuth2Client: {    token_endpoint_auth_method: "private_key_jwt",    token_endpoint_auth_signing_alg: "RS256", // or ES256, EdDSA; ...    // ...    },    })   }
(Source: [Ory Docs](https://www.ory.sh/docs/hydra/guides/jwt#registering-the-clients-public-key)) Also, when setting the algorithm used to sign the payload by the userinfo endpoint, you can set the
userinfo_signed_response_alg
field to "RS256":
Copy code
javascript import { Configuration, 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 setClientLifespans(clientId: string) {    await ory.patchOAuth2Client({    id: clientId,    jsonPatch: [    {    op: "replace",    path: "/userinfo_signed_response_alg",    value: "RS256",    },    ],    })   }
(Source: [Ory Docs](https://www.ory.sh/docs/oauth2-oidc/userinfo-oidc#returning-a-signed-jwt-from-the-userinfo-endpoint)) Please ensure that you replace the placeholders with your actual project and client details.
b
@chilly-king-10285 But Ory Network is signing the JWT - how do I set it there?
c
A message from kapa.ai
I'm sorry for any confusion, but based on the provided knowledge sources, there isn't a direct way to set the JWT signing algorithm in the Ory Network project configuration. The JWT signing algorithm is typically determined by the keys used for signing, which are generated using specific algorithms like RS256 or ES256. However, you can control the JWT signing algorithm by generating and using the appropriate keys. For instance, if you want to use RS256 for all JWT signing, you should generate and use keys with the RS256 algorithm. If you're using Ory Hydra or Ory Oathkeeper, you can generate keys with the RS256 algorithm using the Ory CLI or Docker respectively: For Ory Hydra:
Copy code
bash ory create jwk some-example-set --alg RS256 --project {project.id} --format json-pretty
(Source: [Ory Docs](https://www.ory.sh/docs/identities/session-to-jwt-cors#json-web-token-signing-keys)) For Ory Oathkeeper:
Copy code
bash docker run oryd/oathkeeper:<version-you-want> credentials generate --alg RS256 > jwks.json
(Source: [Ory Docs](https://www.ory.sh/docs/oathkeeper/configure-deploy#cryptographic-keys)) Please note that these commands are run in your local environment and the generated keys should be used in your Ory setup. If you're looking for a way to set the JWT signing algorithm directly in the Ory Network project configuration, I would recommend checking the Ory Network documentation or reaching out to the Ory support for more specific guidance.
b
@chilly-king-10285 How do I change my JWKS to use ES256?
c
A message from kapa.ai
To change your JSON Web Key Set (JWKS) to use the ES256 algorithm, you can use the Ory CLI to create a new key set with the ES256 algorithm. Here's how you can do it:
Copy code
bash ory create jwk some-example-set --alg ES256 --project {project.id} --format json-pretty > es256.jwks.json
(Source: [Ory Docs](https://www.ory.sh/docs/identities/session-to-jwt-cors#end-to-end-example)) This command will create a new JWKS with the ES256 algorithm and save it to a file named
es256.jwks.json
. Replace
{project.id}
with your actual project ID. After generating the new JWKS, you can update the JWKS in your Ory setup using the Ory Hydra or Ory API: For Ory Hydra:
Copy code
bash PUT /admin/keys/{set}
(Source: [Ory Docs](https://www.ory.sh/docs/hydra/reference/api)) For Ory API:
Copy code
bash PUT /admin/keys/{set}
(Source: [Ory Docs](https://www.ory.sh/docs/reference/api)) In both cases, replace
{set}
with the ID of the JWKS you want to update. The request body should contain the new JWKS you generated. Please note that these commands are run in your local environment and the changes should be reflected in your Ory setup.
b
@chilly-king-10285 I'm using Ory Network, how do I update the JWKS there?
c
A message from kapa.ai
Based on the provided knowledge sources, Ory Network automatically generates two cryptographic keys for each project: one for ID Tokens and one for JWT Access Tokens. These keys are stored securely and encrypted at rest using AES256-GCM and the system secret ([source](https://www.ory.sh/docs/hydra/jwks#default-cryptographic-keys-in-ory)). If you want to use your own keys instead of the ones generated by Ory, you can use the Ory API to update the JSON Web Key Set (JWKS). Here's the endpoint you can use:
Copy code
bash PUT /admin/keys/{set}
(Source: [Ory Docs](https://www.ory.sh/docs/reference/api)) In this endpoint,
{set}
should be replaced with the ID of the JWKS you want to update. The request body should contain the new JWKS you want to use. Please note that to perform this operation, you must be authenticated by means of an
oryAccessToken
([source](https://www.ory.sh/docs/reference/api)). However, the exact steps to update the JWKS in Ory Network might be different and are not clearly outlined in the provided knowledge sources. For more specific guidance, I would recommend checking the Ory Network documentation or reaching out to the Ory support.
b
@chilly-king-10285 Should the API key be kept private? What if we need to instantiate OAuth2Api?
c
A message from kapa.ai
Yes, the API key should be kept private. API keys are used to authorize privileged operations, such as calling the Admin API, which allows you to delete users. They work only in the context of the Project for which they were created and are bound to an Ory Network project, not to a specific user. This means that any user with access to the API Key can perform the operations that the API Key allows, even if they are no longer part of the project. Therefore, it's crucial to keep your API Keys secure and rotate them if necessary ([source](https://www.ory.sh/docs/concepts/personal-access-token)). When you need to instantiate
OAuth2Api
, you can use the API key in the configuration. However, you should ensure that the key is not exposed in your code or logged in any way. Here's an example of how to do this:
Copy code
javascript import { Configuration, 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,  }), )
In this example, the API key is stored in an environment variable
ORY_API_KEY
, which keeps it secure and separate from the codebase ([source](https://www.ory.sh/docs/getting-started/local-development#ory-apis)).
b
@chilly-king-10285 How do I use OAuth2Api in my frontend to process an oauth challenge?
c
A message from kapa.ai
To process an OAuth challenge in your frontend using
OAuth2Api
, you can follow the example provided in the Ory documentation. Here's a simplified version of how you might handle a login challenge:
Copy code
javascript import { Configuration, OAuth2Api } from "@ory/client"   import { Request, Response } from "express"      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 handleLogin(request: Request, response: Response) {    const challenge = request.query.login_challenge.toString()    const { data: loginRequest } = await ory.getOAuth2LoginRequest({      loginChallenge: challenge.toString(),    })       if (loginRequest.skip) {      // User is already authenticated, don't show the login form and simply accept the login request.      await ory        .acceptOAuth2LoginRequest({          loginChallenge: challenge,          acceptOAuth2LoginRequest: {            subject: loginRequest.subject,          },        })        .then(({ data }) => response.redirect(data.redirect_to))      return    }       // Show the login form if the form was not submitted.    if (request.method === "GET") {      response.render("login", {        loginRequest,      })      return    }       // The user did not want to sign in with the given app.    if (request.body.submit === "Deny access") {      await ory        .rejectOAuth2LoginRequest({          loginChallenge: challenge,          rejectOAuth2Request: {            error: "access_denied",            error_description: "The resource owner denied the request",          },        })        .then(({ data }) => response.redirect(data.redirect_to))    }       const user = authenticateUserCredentials(      request.body.email,    // ... continue with your authentication logic  }
(Source: [Ory Docs](https://www.ory.sh/docs/oauth2-oidc/custom-login-consent/flow#login-endpoint-code-example)) In this example, the
handleLogin
function is an Express.js route handler that processes the login challenge. It first retrieves the login request using the
getOAuth2LoginRequest
method. If the user is already authenticated (
loginRequest.skip
is
true
), it accepts the login request using the
acceptOAuth2LoginRequest
method. If the user is not authenticated, it shows the login form. If the user denies access, it rejects the login request using the
rejectOAuth2LoginRequest
method. Please note that this is a simplified example and you should add proper error handling and complete the authentication logic according to your application's requirements.
b
@chilly-king-10285 How do I change the URL/endpoint that my OAuth challenge request is redirected to?
c
A message from kapa.ai
To change the URL or endpoint that your OAuth challenge request is redirected to, you need to update the Redirect URI in the configuration of the social sign-in provider. Here are the steps to do this: 1. Open the Ory Console and navigate to the social sign-in configuration screen. 2. Choose the provider you want to fix and click on the configuration button. 3. Copy the Redirect URI from the form. 4. Replace the Ory Network URL
{project-slug}.<http://projects.oryapis.com|projects.oryapis.com>
with your custom hostname, such as
<http://ory.example.org|ory.example.org>
. 5. Update the Redirect URI - also called Authorization callback URL - in the social sign-in provider configuration. Make sure the Redirect URI matches the hostname you configured in the Ory Network configuration. For example, when your custom hostname is
<https://ory.example.org>
, the Redirect URI needs to be
<https://ory.example.org>
, not
<https://www.ory.example.org>
or
<https://ory.example.org/>
. (Source: [Ory Docs](https://www.ory.sh/docs/identities/sign-in/social-sign-in/redirect-url))
b
@chilly-king-10285 What is the "subject" of the acceptOAuth2LoginRequest property?
c
A message from kapa.ai
The "subject" in the
acceptOAuth2LoginRequest
property refers to the user ID of the end-user that authenticated. In the context of OAuth 2.0 and OpenID Connect, the "subject" is a unique identifier assigned to a user. When accepting a login request, if the "subject" value is set and
skip
is true, you MUST include this "subject" type. This is because the "subject" is used to identify the user that has granted or denied the scope requested by the OAuth 2.0 client. Here's an example of how it's used:
Copy code
javascript await ory    .acceptOAuth2LoginRequest({{      loginChallenge: challenge,      acceptOAuth2LoginRequest: {{        subject: loginRequest.subject,      }},    }})    .then(({{ data }}) => response.redirect(data.redirect_to))
(Source: [Ory Docs](https://www.ory.sh/docs/hydra/reference/api))
b
@chilly-king-10285 The
subject
in the
getOAuth2LoginRequest
is null.
c
A message from kapa.ai
If the
subject
in the
getOAuth2LoginRequest
is
null
, it means that the user is not authenticated yet. The
subject
field is the user ID of the end-user that authenticated. If this value is
null
, it indicates that the user has not yet authenticated. In this case, you should redirect the user to your login page where they can authenticate. After successful authentication, you can then accept the login request with the
acceptOAuth2LoginRequest
method, providing the authenticated user's ID as the
subject
. Here's an example of how you might handle this:
Copy code
javascript const {{ data: loginRequest }} = await ory.getOAuth2LoginRequest({{      loginChallenge: challenge.toString(),   }})    if (!loginRequest.subject) {   // Redirect the user to the login page   response.redirect('/login');   return; }  // If the user is authenticated, accept the login request await ory    .acceptOAuth2LoginRequest({{      loginChallenge: challenge,      acceptOAuth2LoginRequest: {{        subject: loginRequest.subject,      }},    }})    .then(({{ data }}) => response.redirect(data.redirect_to))
(Source: [Ory Docs](https://www.ory.sh/docs/hydra/reference/api))
b
@chilly-king-10285 I'm logged in (I have an Ory session cookie) - why is subject being returned as
''
?
c
A message from kapa.ai
The
subject
being returned as an empty string could be due to a few reasons: 1. The session might have expired: In this case, even though the session cookie exists, the session might not be valid anymore. You can check the session status by sending a request to the
/sessions/whoami
endpoint ([source](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-cookie)). 2. The session cookie might not be sent with the request: This could happen if the
withCredentials
option is not set to
true
in your request configuration ([source](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-cookie)). 3. There might be an issue with the reverse proxy configuration: If you're running Ory behind a reverse proxy that strips the Cookie header, this could cause issues ([source](https://www.ory.sh/docs/self-hosted/hydra/debug/csrf#reverse-proxy-or-load-balancers)). If you're still facing issues, I would recommend checking the Ory documentation or reaching out to the Ory support for more specific guidance.
b
@chilly-king-10285 I have withCredentials to true, but I'm also running through a tunnel. Is that it?
c
A message from kapa.ai
Yes, that could be the issue. When developing locally, your application typically runs on
localhost
or on a local custom domain such as
app.local
. However, your Ory Network project runs on your slug URL
https://{project.slug}.<http://projects.oryapis.com|projects.oryapis.com>
. The Ory APIs can't set cookies on a different domain than the one they are running on. The solution is to tunnel the Ory APIs on a port on your local machine, which allows cookies to be set on the same domain as the application is running. This is done using the Ory Tunnel, which should be used for development only and not in a production environment ([source](https://www.ory.sh/docs/security-model#what-about-local-development)). If you're already running through a tunnel and still facing issues, it might be due to the tunnel configuration. Make sure that the tunnel is correctly set up and that it's not stripping the Cookie header or causing other issues.
b
@chilly-king-10285 The cookie domain is localhost
c
A message from kapa.ai
If your application is running on
localhost
and you're using Ory Network, you need to ensure that the Ory APIs are also exposed on
localhost
. This is because the Ory APIs can't set cookies on a different domain than the one they are running on. To achieve this, you can use the Ory Tunnel, a development tool bundled with the Ory CLI. It allows you to mirror the Ory APIs on your local machine, enabling cookies to be set on the same domain as the application is running. Here's how you can start the Ory Tunnel:
Copy code
bash npx @ory/cli tunnel --dev <http://localhost:3000>
In this command, replace
<http://localhost:3000>
with the URL where your application is running. After running this command, the Ory APIs will be mirrored on
<http://localhost:4000>
. Please note that the
--dev
flag disables security checks for easier integration and should not be used when deploying the Tunnel to a staging environment ([source](https://www.ory.sh/docs/getting-started/integrate-auth/react#run-ory-apis-on-localhost)). Also, when setting cookies, Ory must be able to set the
domain
in the HTTP cookie to the same domain as the application that consumes its APIs. For example, when working with an application that runs on
<http://localhost:3000>
for local development, Ory must be able to set
domain=localhost
in the HTTP cookie ([source](https://www.ory.sh/docs/security-model#access-to-your-domain)).
b
@chilly-king-10285 That is happening as expected.
c
A message from kapa.ai
If your application is running on
localhost
, the Ory APIs are exposed on
localhost
via the Ory Tunnel, and the
withCredentials
option is set to
true
, but the
subject
is still being returned as an empty string, it might be due to a few other reasons: 1. The session might have expired: Even though the session cookie exists, the session might not be valid anymore. You can check the session status by sending a request to the
/sessions/whoami
endpoint ([source](https://www.ory.sh/docs/kratos/session-management/overview#using-ory-session-cookie)). 2. There might be an issue with the reverse proxy configuration: If you're running Ory behind a reverse proxy that strips the Cookie header, this could cause issues ([source](https://www.ory.sh/docs/self-hosted/hydra/debug/csrf#reverse-proxy-or-load-balancers)). 3. The user might not be authenticated: If the user has not authenticated yet, the
subject
will be
null
. In this case, you should redirect the user to your login page where they can authenticate. If you're still facing issues, I would recommend checking the Ory documentation or reaching out to the Ory support for more specific guidance.