minio / minio

The Object Store for AI Data Infrastructure

Home Page:https://min.io/download

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support array when validating JWT token audience

VinceAdamo opened this issue · comments

Is your feature request related to a problem? Please describe.
With the most recent update, you started validating the JWT token audience (by checking if it matches the OpenID Client ID provided). However, this isn't working for my setup because my JWT audience is an array (with more than one audience).

Describe the solution you'd like
I was just wondering if it would be possible to add a way to support the audience parameter being an array, where only 1 of the audience values provided in the array needs to match the OpenID Client ID).

@VinceAdamo why do you have multiple audience if token is meant for a single service such as MinIO?

My auth provider (Auth0) adds the extra audience in case I need extra information about the user the token was issued to. I don't use it, but there is no way to remove it from the token.

My auth provider (Auth0) adds the extra audience in case I need extra information about the user the token was issued to. I don't use it, but there is no way to remove it from the token.

How is that possible I use auth0

#!/bin/bash

export MINIO_IDENTITY_OPENID_CONFIG_URL=https://alevsk-minio.auth0.com/.well-known/openid-configuration
export MINIO_IDENTITY_OPENID_CLIENT_ID="UOhR2Gw2EuPbSjFla96ppLHWEypzZUh2"
export MINIO_IDENTITY_OPENID_CLIENT_SECRET="cB9_oc1Mx__cNFDdmKmhjNC18O5Udtvp8T0p94Ug8FCM8-PUB4OgFqPXScj01mLm"
export MINIO_IDENTITY_OPENID_SCOPES="openid,profile,email"
export MINIO_IDENTITY_OPENID_CLAIM_NAME="https://min.io/policy"

minio server /tmp/xl{1...4} --console-address ":9001"

There is no secondary audience, are you sure you don't have two different client_ids associated with the same setup?

We can definitely add array support but it feels weird that there are multiple audiences for MinIO's callback URL as it shouldn't be.

Basically I have a client application that requires user login to get an access token for my api. The api connects to minio via python for file storage. The audience parameter in the /authorize endpoint that Auth0 provides is suppose to contain the auth api url, and that is what is embedded in the jwt token. When the users make requests, I use this same access token for minio. It would usually only contain one audience value, but auth0 adds another audience when the openid scope is requested, which I have to add. Client ID and audience aren't the same thing. I only have one Client ID in my access token, but it is under the azp claim.

The aud claim in my token looks like this:

"aud": [
    "https://myauthapi.com/",
    "https://myauthprovider.auth0.com/userinfo"
  ],

The first value in the array is the actual auth api that I am using as my audience. The second is the one that auth0 adds. If you inspect a jwt you get from auth0 you should see a similar audience value being used (with /userinfo).

@VinceAdamo I am quite surprised for me

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "OEY2NDc2MTY0NjQ1NDJDNjA3MkYxMzQ1QzBCRkQ3RDY2NkZENDIxOQ"
}.{
  "https://min.io/policy": "consoleAdmin",
  "nickname": "lenin+idp",
  "name": "Lenin Alevski",
  "picture": "https://s.gravatar.com/avatar/6bd85cf6bb069d9e31d58efc496522e3?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fle.png",
  "updated_at": "2021-07-27T18:36:05.015Z",
  "email": "lenin+idp@min.io",
  "email_verified": true,
  "iss": "https://alevsk-minio.auth0.com/",
  "sub": "auth0|5e3ca40eb0db1d0cc53f7bd4",
  "aud": "UOhR2Gw2EuPbSjFla96ppLHWEypzZUh2",
  "iat": 1627429953,
  "exp": 1627465953
}.[Signature]

Looks like you are using incorrect tokens with MinIO how are you getting the tokens?

I think your application is wrong you are sending us (MinIO) access tokens instead you should be sending us id_token

Oh yeah I’m sending access tokens. ID tokens typically aren’t used to gain access to a resource though, just to provide information about the user. I prefer using access tokens for this purpose, although I guess I can start requesting ID tokens and use those. Just wondering, is there a reason you’re using ID tokens vs access tokens?

Also, just to let you know, your docs say to provide an access token, which is what caused confusion I think.

Oh yeah I’m sending access tokens. ID tokens typically aren’t used to gain access to a resource though, just to provide information about the user. I prefer using access tokens for this purpose, although I guess I can start requesting ID tokens and use those. Just wondering, is there a reason you’re using ID tokens vs access tokens?

id_tokens are the ones you need to use - access_tokens are opaque values it is just that OpenID spec is not very specific about access_token being JWT. That's why you are confused.

MinIO is the service provider that needs to use id_token to validate the token we can't use access_token since we do not talk to userinfo endpoint we need a token that is fully self-describing.

Its not what you prefer that is meaningless - you should use id_token @VinceAdamo here.

We clearly mention this here

https://github.com/minio/minio/blob/master/docs/sts/web-identity.md#authorization-flow

Once obtained the JWT id_token is further sent to STS endpoint i.e MinIO to retrieve temporary credentials.

access_tokens are meant for API access on IDP providers such as access_token can be used to access auth0 admin APIs.

MinIO is not an entity that knows how to deal with access_tokens - we know how to handle id_token

But FWIW I sent a PR to handle more scenarios that confused users don't have to split hairs figuring this out since clearly, Auth0 took a broken approach of sticking JWT onto access_token.

OpenID spec as-is - is terribly written, wonky on details, and allowing myriad's of implementations that confuse the heck out of developers.

You also mention this though:

https://github.com/minio/minio/blob/master/docs/sts/web-identity.md#api-request-parameters

The OAuth 2.0 access token that is provided by the web identity provider. Application must get this token by authenticating the user who is using your application with a web identity provider before the application makes an AssumeRoleWithWebIdentity call.

I've been using access_tokens to access my apis based on what Auth0 says here: https://auth0.com/docs/tokens

But yeah, OpenID definitely could be more clear. It makes more sense to use id_token here anyways. Wish that there was a more clear set of specs for OpenID as it seems everyone is doing things differently. Thanks for sending out this PR.