400 response when trying to set user permissions for a client from Management API

,

I’m getting this error:

{
  statusCode: 400,
  error: 'Bad Request',
  message: "Path validation error: 'Object didn't pass validation for format user-id: iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients' on property id (ID of the user to assign permissions to).",
  errorCode: 'invalid_uri'
}

The client ID is verbatim from the decoded token. I also tried removing the @clients at the end and still had the same error.

1 Like

Can you post the payload you are sending to the endpoint and which endpoint this error is being thrown from? Your user_id should be of the following form <CONNECTION_NAME|<EMAIL_OR_RANDOM_UUID>.

I’m using auth0 library’s ManagementClient, this is the entire response object:

    {
      "reason": "Bad Request",
      "message": "Path validation error: 'Object didn't pass validation for format user-id: iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients' on property id (ID of the user to assign permissions to).",
      "statusCode": 400,
      "requestInfo": {
        "method": "post",
        "url": "https://any4.auth0.com/api/v2/users/iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients/permissions"
      },
      "originalError": {
        "status": 400,
        "response": {
          "req": {
            "method": "POST",
            "url": "https://any4.auth0.com/api/v2/users/iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients/permissions",
            "data": {
              "permissions": [
                {
                  "permission_name": "delete:project",
                  "resource_server_identifier": "project:understanding-anemia"
                }
              ]
            },
            "headers": {
              "user-agent": "node.js/12.14.1",
              "content-type": "application/json",
              "auth0-client": "eyJuYW1lIjoibm9kZS1hdXRoMCIsInZlcnNpb24iOiIyLjIwLjAiLCJlbnYiOnsibm9kZSI6IjEyLjE0LjEifX0",
              "authorization": "Bearer SNIP",
              "accept": "application/json"
            }
          },
          "header": {
            "date": "Thu, 09 Jan 2020 10:39:58 GMT",
            "content-type": "application/json; charset=utf-8",
            "transfer-encoding": "chunked",
            "connection": "close",
            "server": "nginx",
            "ot-tracer-spanid": "7648312a4561a5e5",
            "ot-tracer-traceid": "5e6f33e3211a12f1",
            "ot-tracer-sampled": "true",
            "vary": "origin,accept-encoding",
            "cache-control": "no-cache",
            "content-encoding": "gzip"
          },
          "status": 400,
          "text": "{\"statusCode\":400,\"error\":\"Bad Request\",\"message\":\"Path validation error: 'Object didn't pass validation for format user-id: iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients' on property id (ID of the user to assign permissions to).\",\"errorCode\":\"invalid_uri\"}"
        }
      }
    }

This is an application token created on the auth0 console to authenticate machine to machine.

Hi, at this point I just want to know if Auth Core supports client credentials (Client Credentials Flow), if it doesn’t - is this something that will be addressed and if not then what is the recommended procedure to support authorizing robots in my app?

Thank you!

Yes, we definitely do. Please refer to Machine to Machine (M2M) | Okta and Using Machine to Machine (M2M) Authorization

You are getting 400 error because you are using wrong id for /users/:id this id needs to be user_id but it looks like you are using the sub id from accessToken which is pointing to the actual client.

If you can explain your explain your use case in more details I will try to provide you the exact flow and endpoints you need to call. Or else you can also refer to the docs I provided above. Let me know how can I help.

Hi ashish;

I assumed the sub is the user ID, how can I get the user ID given a token? Client side I get an access token like this:

const {access_token} = await new AuthenticationClient({
    clientId: process.env.AUTH0_CLIENT,
    clientSecret: process.env.AUTH0_SECRET,
    domain: 'any4.auth0.com'
  }).clientCredentialsGrant({audience: 'https://any4.io/'})

On the server side I verify the token with this middleware:

import * as jwt from 'koa-jwt'
import {koaJwtSecret as secret} from 'jwks-rsa'

const authenticator = jwt({
  secret: secret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 1,
    jwksUri: `https://any4.auth0.com/.well-known/jwks.json`
  }),
  audience: 'https://any4.io/',
  algorithms: ['RS256'],
  issuer: `https://any4.auth0.com/`,
  key: 'jwtData'
})

And get a decoded token looking like this:

    {
      "iss": "https://any4.auth0.com/",
      "sub": "iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb@clients",
      "aud": "https://any4.io/",
      "iat": 1578953267,
      "exp": 1579039667,
      "azp": "iBOtBwpT2vobt3FiDuxpBpU2Gs2F2wqb",
      "gty": "client-credentials",
      "permissions": []
    }

I tried getting the user profile like this:

new AuthenticationClient({domain: 'any4.auth0.com'}).getProfile(authorization.split(' ')[1])
      .then(console.log, console.log)

And I get Unauthorized I’m guessing because the client is missing openid scope and I don’t know how to fix that. I didn’t see my problem addressed in your links, forgive me if I’m blind.

1 Like

Did this get resolved? I’m butting up against the same issue. I’ve got users authenticating, taking their auth0 ID from Sub claim and passing it into the management User.Read(). That works fine. However I now have M2M applications trying to authenticate and when I use their Sub claim as the user ID I’m getting the same response as OP.

How do I get a user ID for a M2M application that I can call User.Read() from the management SDK? I don’t see anything in their claim I can use. I’ve tried stripping the @clients suffix and appending auth0| prefix, but to no avail.

To circumvent this issue I added a detection for when a client (M2M application) is authenticating vs user and call the Client.Read() on the management API instead.

The detection is crude: if strings.HasSuffix(claims.Subject, "@clients") { - not sure if there is a more robust way?